KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > persistence > jdbcimpl > JdbcMultivaluedOrderedIndex


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.mdr.persistence.jdbcimpl;
20
21 import org.netbeans.mdr.persistence.*;
22 import org.netbeans.mdr.util.*;
23
24 import java.sql.*;
25 import java.util.*;
26 import java.io.*;
27
28 /**
29  * JdbcMultivaluedOrderedIndex implements the MDR MultivaluedOrderedIndex
30  * using JDBC.
31  *
32  * @author John V. Sichi
33  * @version $Id: JdbcMultivaluedOrderedIndex.java,v 1.5 2006/06/30 20:56:10 jtulach Exp $
34  */

35 class JdbcMultivaluedOrderedIndex
36     extends JdbcMultivaluedIndex implements MultivaluedOrderedIndex
37 {
38     protected LazyPreparedStatement sqlInsertWithOrdinal;
39     protected LazyPreparedStatement sqlUpdateWithOrdinal;
40     protected LazyPreparedStatement sqlDeleteWithOrdinal;
41     protected LazyPreparedStatement sqlShiftOrdinals;
42     protected LazyPreparedStatement sqlFindOrdered;
43     protected LazyPreparedStatement sqlFindValueOrdinal;
44     
45     protected void defineSql()
46     {
47         super.defineSql();
48
49         // TODO: assert needSurrogate
50

51         sqlInsertWithOrdinal = new LazyPreparedStatement(
52             "insert into " + tableName
53             + " values(?,?,?,?)");
54         
55         sqlUpdateWithOrdinal = new LazyPreparedStatement(
56             "update " + tableName + " set " + valColName
57             + " = ? where " + keyColName + " = ? and "
58             + storage.ORDINAL_COL_NAME + " = ?");
59         
60         sqlDeleteWithOrdinal = new LazyPreparedStatement(
61             "delete from " + tableName
62             + " where " + keyColName + " = ?"
63             + " and " + storage.ORDINAL_COL_NAME + " = ?");
64         
65         sqlShiftOrdinals = new LazyPreparedStatement(
66             "update " + tableName + " set "
67             + storage.ORDINAL_COL_NAME + " = " + storage.ORDINAL_COL_NAME
68             + " + ? where " + keyColName + " = ? and "
69             + storage.ORDINAL_COL_NAME + " >= ?");
70
71         // NOTE: keyColName is redundant in ORDER BY, but maybe it improves
72
// the chances that even a stupid optimizer will realize it can use the
73
// primary key index for ordering. And if DBMS doesn't support
74
// ORDER BY non-selected column (which is non-standard), we
75
// extend the select list but ignore the extra columns during fetch.
76
String JavaDoc selectOrdered = "select " + valColName;
77         boolean orderByUnrelated = false;
78         try {
79             orderByUnrelated =
80                 storage.getDatabaseMetaData().supportsOrderByUnrelated();
81         } catch (SQLException ex) {
82             // assume exception means it doesn't
83
}
84         if (!orderByUnrelated) {
85             selectOrdered = selectOrdered
86                 + ", " + keyColName + ", " + storage.ORDINAL_COL_NAME;
87         }
88         sqlFindOrdered = new LazyPreparedStatement(
89             selectOrdered + " from " + tableName
90             + " where " + keyColName + " = ? order by "
91             + keyColName + ", " + storage.ORDINAL_COL_NAME);
92
93         sqlFindValueOrdinal = new LazyPreparedStatement(
94             "select " + storage.ORDINAL_COL_NAME + " from " + tableName
95             + " where " + keyColName + " = ?"
96             + " and " + valColName + " = ?");
97     }
98     
99     // implement MultivaluedOrderedIndex
100
public List getItemsOrdered(Object JavaDoc key) throws StorageException
101     {
102         return new ItemList(key,null);
103     }
104     
105     // implement MultivaluedOrderedIndex
106
public Collection getObjectsOrdered(
107         Object JavaDoc key, SinglevaluedIndex repos) throws StorageException
108     {
109         if (keyType == Storage.EntryType.MOFID) {
110             return new ItemList(key,repos);
111         } else {
112             return getItemsOrdered(key);
113         }
114     }
115     
116     // implement MultivaluedOrderedIndex
117
public void add(Object JavaDoc key, int index, Object JavaDoc value)
118         throws StorageException
119     {
120         addImpl(key,index,value,true);
121     }
122     
123     // override JdbcIndex
124
protected void addImpl(Object JavaDoc key, Object JavaDoc value) throws StorageException
125     {
126         // Have to query to get the current size as the new index. But as an
127
// optimization, there's no need to shift the ordinals of the existing
128
// entries.
129
int index = getItemsOrdered(key).size();
130         addImpl(key,index,value,false);
131     }
132
133     private void addImpl(
134         Object JavaDoc key, int index, Object JavaDoc value,boolean shiftOrdinals)
135         throws StorageException
136     {
137         if (shiftOrdinals) {
138             storage.executeUpdate(
139                 sqlShiftOrdinals,
140                 new Object JavaDoc[]{new Integer JavaDoc(1),key,new Integer JavaDoc(index)});
141         }
142         
143         Object JavaDoc [] args = new Object JavaDoc[]{
144             key,value,new Integer JavaDoc(index),
145             new Long JavaDoc(storage.getSerialNumber())};
146         storage.executeUpdate(sqlInsertWithOrdinal,args);
147     }
148
149     // implement MultivaluedOrderedIndex
150
public boolean remove(Object JavaDoc key, int index)
151         throws StorageException
152     {
153         return removeImpl(key,index,true);
154     }
155     
156     // override JdbcMultivaluedIndex
157
public boolean remove(Object JavaDoc key, Object JavaDoc value) throws StorageException
158     {
159         int index = storage.getSingletonInt(
160             sqlFindValueOrdinal,
161             new Object JavaDoc[]{key,value});
162         if (index == -1) {
163             return false;
164         }
165         remove(key,index);
166         return true;
167     }
168     
169     private boolean removeImpl(Object JavaDoc key, int index,boolean shiftOrdinals)
170         throws StorageException
171     {
172         storage.executeUpdate(
173             sqlDeleteWithOrdinal,
174             new Object JavaDoc[]{key,new Integer JavaDoc(index)});
175
176         if (shiftOrdinals) {
177             storage.executeUpdate(
178                 sqlShiftOrdinals,
179                 new Object JavaDoc[]{new Integer JavaDoc(-1),key,new Integer JavaDoc(index)});
180         }
181         
182         return true;
183     }
184     
185     // implement MultivaluedOrderedIndex
186
public void replace(Object JavaDoc key, int index, Object JavaDoc element)
187         throws StorageException
188     {
189         storage.executeUpdate(
190             sqlUpdateWithOrdinal,
191             new Object JavaDoc[]{element,key,new Integer JavaDoc(index)});
192     }
193
194     private class ItemList extends AbstractSequentialList
195     {
196         private Object JavaDoc key;
197         private SinglevaluedIndex repos;
198
199         ItemList(Object JavaDoc key,SinglevaluedIndex repos)
200         {
201             this.key = key;
202             this.repos = repos;
203         }
204
205         // implement AbstractSequentialList
206
public ListIterator listIterator(int index)
207         {
208             try {
209                 ListIterator iter = new ItemListIter(
210                     storage.getResultSetIterator(
211                         sqlFindOrdered,
212                         new Object JavaDoc[]{key},
213                         getValueType()),
214                     repos,
215                     key);
216                 while (iter.nextIndex() != index) {
217                     iter.next();
218                 }
219                 return iter;
220             } catch (StorageException ex) {
221                 throw new RuntimeStorageException(ex);
222             }
223         }
224
225         // implement AbstractSequentialList
226
public int size()
227         {
228             try {
229                 return storage.getSingletonInt(sqlFindCount,new Object JavaDoc[]{key});
230             } catch (StorageException ex) {
231                 throw new RuntimeStorageException(ex);
232             }
233         }
234     }
235
236     private class ItemListIter implements ListIterator
237     {
238         private ListIterator iter;
239         private SinglevaluedIndex repos;
240         private Object JavaDoc key;
241         private int lastPos;
242
243         ItemListIter(
244             ListIterator iter,SinglevaluedIndex repos,Object JavaDoc key)
245         {
246             this.iter = iter;
247             this.repos = repos;
248             this.key = key;
249
250             lastPos = -1;
251         }
252
253         // implement ListIterator
254
public void add(Object JavaDoc obj)
255         {
256             try {
257                 int index = nextIndex();
258                 // if at end, no need to shift ordinals
259
addImpl(key,index,obj,iter.hasNext());
260             } catch (StorageException ex) {
261                 throw new RuntimeStorageException(ex);
262             }
263             iter.add(obj);
264             lastPos = -1;
265         }
266
267         // implement ListIterator
268
public boolean hasNext()
269         {
270             return iter.hasNext();
271         }
272
273         // implement ListIterator
274
public boolean hasPrevious()
275         {
276             return iter.hasPrevious();
277         }
278
279         private Object JavaDoc getValue(Object JavaDoc obj)
280         {
281             if (repos != null) {
282                 try {
283                     return repos.get(obj);
284                 } catch (StorageException ex) {
285                     throw new RuntimeStorageException(ex);
286                 }
287             } else {
288                 return obj;
289             }
290         }
291
292         // implement ListIterator
293
public Object JavaDoc next()
294         {
295             lastPos = iter.nextIndex();
296             return getValue(iter.next());
297         }
298
299         // implement ListIterator
300
public int nextIndex()
301         {
302             return iter.nextIndex();
303         }
304
305         // implement ListIterator
306
public Object JavaDoc previous()
307         {
308             lastPos = iter.previousIndex();
309             return getValue(iter.previous());
310         }
311
312         // implement ListIterator
313
public int previousIndex()
314         {
315             return iter.previousIndex();
316         }
317
318         // implement ListIterator
319
public void remove()
320         {
321             if (lastPos == -1) {
322                 throw new IllegalStateException JavaDoc();
323             }
324             // remove from iter first, in case we just did a previous() from end
325
iter.remove();
326             try {
327                 // if at end, no need to shift ordinals
328
removeImpl(
329                     key,lastPos,iter.hasNext());
330             } catch (StorageException ex) {
331                 throw new RuntimeStorageException(ex);
332             }
333             lastPos = -1;
334         }
335
336         // implement ListIterator
337
public void set(Object JavaDoc obj)
338         {
339             iter.set(obj);
340             try {
341                 JdbcMultivaluedOrderedIndex.this.replace(
342                     key,lastPos,obj);
343             } catch (StorageException ex) {
344                 throw new RuntimeStorageException(ex);
345             }
346             lastPos = -1;
347         }
348     }
349 }
350
351 // End JdbcMultivaluedOrderedIndex.java
352
Popular Tags