KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > collections > StoredContainer


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2000,2006 Oracle. All rights reserved.
5  *
6  * $Id: StoredContainer.java,v 1.51 2006/10/30 21:14:10 bostic Exp $
7  */

8
9 package com.sleepycat.collections;
10
11 import java.util.Collection JavaDoc;
12 import java.util.Iterator JavaDoc;
13
14 import com.sleepycat.compat.DbCompat;
15 import com.sleepycat.je.CursorConfig;
16 import com.sleepycat.je.DatabaseException;
17 import com.sleepycat.je.OperationStatus;
18 import com.sleepycat.util.RuntimeExceptionWrapper;
19
20 /**
21  * A abstract base class for all stored collections and maps. This class
22  * provides implementations of methods that are common to the {@link
23  * java.util.Collection} and the {@link java.util.Map} interfaces, namely
24  * {@link #clear}, {@link #isEmpty} and {@link #size}.
25  *
26  * <p>In addition, this class provides the following methods for stored
27  * collections only. Note that the use of these methods is not compatible with
28  * the standard Java collections interface.</p>
29  * <ul>
30  * <li>{@link #isWriteAllowed()}</li>
31  * <li>{@link #isSecondary()}</li>
32  * <li>{@link #isOrdered()}</li>
33  * <li>{@link #areDuplicatesAllowed()}</li>
34  * <li>{@link #areDuplicatesOrdered()}</li>
35  * <li>{@link #areKeysRenumbered()}</li>
36  * <li>{@link #getCursorConfig()}</li>
37  * <li>{@link #isTransactional()}</li>
38  * </ul>
39  *
40  * @author Mark Hayes
41  */

42 public abstract class StoredContainer implements Cloneable JavaDoc {
43
44     DataView view;
45
46     StoredContainer(DataView view) {
47
48         this.view = view;
49     }
50
51     /**
52      * Returns true if this is a read-write container or false if this is a
53      * read-only container.
54      * This method does not exist in the standard {@link java.util.Map} or
55      * {@link java.util.Collection} interfaces.
56      *
57      * @return whether write is allowed.
58      */

59     public final boolean isWriteAllowed() {
60
61         return view.writeAllowed;
62     }
63
64     /**
65      * Returns the cursor configuration that is used for all operations
66      * performed via this container.
67      * For example, if <code>CursorConfig.getReadUncommitted</code> returns
68      * true, data will be read that is modified but not committed.
69      * This method does not exist in the standard {@link java.util.Map} or
70      * {@link java.util.Collection} interfaces.
71      *
72      * @return the cursor configuration, or null if no configuration has been
73      * specified.
74      */

75     public final CursorConfig getCursorConfig() {
76
77         return DbCompat.cloneCursorConfig(view.cursorConfig);
78     }
79
80     /**
81      * Returns whether read-uncommitted is allowed for this container.
82      * For the JE product, read-uncommitted is always allowed; for the DB
83      * product, read-uncommitted is allowed if it was configured for the
84      * underlying database for this container.
85      * Even when read-uncommitted is allowed it must specifically be enabled by
86      * calling one of the {@link StoredCollections} methods.
87      * This method does not exist in the standard {@link java.util.Map} or
88      * {@link java.util.Collection} interfaces.
89      *
90      * @return whether read-uncommitted is allowed.
91      *
92      * @deprecated This method is deprecated with no replacement in this class.
93      * In the DB product, <code>DatabaseConfig.getReadUncommitted</code> may be
94      * called.
95      */

96     public final boolean isDirtyReadAllowed() {
97
98         return view.readUncommittedAllowed;
99     }
100
101     /**
102      * @deprecated This method has been replaced by {@link #getCursorConfig}.
103      * <code>CursorConfig.isReadUncommitted</code> may be called to determine
104      * whether dirty-read is enabled.
105      */

106     public final boolean isDirtyRead() {
107
108         return view.cursorConfig.getReadUncommitted();
109     }
110
111     /**
112      * Returns whether the databases underlying this container are
113      * transactional.
114      * Even in a transactional environment, a database will be transactional
115      * only if it was opened within a transaction or if the auto-commit option
116      * was specified when it was opened.
117      * This method does not exist in the standard {@link java.util.Map} or
118      * {@link java.util.Collection} interfaces.
119      *
120      * @return whether the database is transactional.
121      */

122     public final boolean isTransactional() {
123
124         return view.transactional;
125     }
126
127     /**
128      * Clones a container with a specified cursor configuration.
129      */

130     final StoredContainer configuredClone(CursorConfig config) {
131
132         try {
133             StoredContainer cont = (StoredContainer) clone();
134             cont.view = cont.view.configuredView(config);
135             cont.initAfterClone();
136             return cont;
137         } catch (CloneNotSupportedException JavaDoc willNeverOccur) { return null; }
138     }
139
140     /**
141      * Override this method to initialize view-dependent fields.
142      */

143     void initAfterClone() {
144     }
145
146     /**
147      * Returns whether duplicate keys are allowed in this container.
148      * Duplicates are optionally allowed for HASH and BTREE databases.
149      * This method does not exist in the standard {@link java.util.Map} or
150      * {@link java.util.Collection} interfaces.
151      *
152      * <p>Note that the JE product only supports BTREE databases.</p>
153      *
154      * @return whether duplicates are allowed.
155      */

156     public final boolean areDuplicatesAllowed() {
157
158         return view.dupsAllowed;
159     }
160
161     /**
162      * Returns whether duplicate keys are allowed and sorted by element value.
163      * Duplicates are optionally sorted for HASH and BTREE databases.
164      * This method does not exist in the standard {@link java.util.Map} or
165      * {@link java.util.Collection} interfaces.
166      *
167      * <p>Note that the JE product only supports BTREE databases, and
168      * duplicates are always sorted.</p>
169      *
170      * @return whether duplicates are ordered.
171      */

172     public final boolean areDuplicatesOrdered() {
173
174         return view.dupsOrdered;
175     }
176
177     /**
178      * Returns whether keys are renumbered when insertions and deletions occur.
179      * Keys are optionally renumbered for RECNO databases.
180      * This method does not exist in the standard {@link java.util.Map} or
181      * {@link java.util.Collection} interfaces.
182      *
183      * <p>Note that the JE product does not support RECNO databases, and
184      * therefore keys are never renumbered.</p>
185      *
186      * @return whether keys are renumbered.
187      */

188     public final boolean areKeysRenumbered() {
189
190         return view.keysRenumbered;
191     }
192
193     /**
194      * Returns whether keys are ordered in this container.
195      * Keys are ordered for BTREE, RECNO and QUEUE database.
196      * This method does not exist in the standard {@link java.util.Map} or
197      * {@link java.util.Collection} interfaces.
198      *
199      * <p>Note that the JE product only support BTREE databases, and
200      * therefore keys are always ordered.</p>
201      *
202      * @return whether keys are ordered.
203      */

204     public final boolean isOrdered() {
205
206         return view.ordered;
207     }
208
209     /**
210      * Returns whether this container is a view on a secondary database rather
211      * than directly on a primary database.
212      * This method does not exist in the standard {@link java.util.Map} or
213      * {@link java.util.Collection} interfaces.
214      *
215      * @return whether the view is for a secondary database.
216      */

217     public final boolean isSecondary() {
218
219         return view.isSecondary();
220     }
221
222     /**
223      * Returns a non-transactional count of the records in the collection or
224      * map. This method conforms to the {@link java.util.Collection#size} and
225      * {@link java.util.Map#size} interfaces.
226      *
227      * <p>This operation is faster than obtaining a count by scanning the
228      * collection manually, and will not perturb the current contents of the
229      * cache. However, the count is not guaranteed to be accurate if there are
230      * concurrent updates.</p>
231      *
232      * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is thrown.
233      */

234     public abstract int size();
235
236     /**
237      * Returns true if this map or collection contains no mappings or elements.
238      * This method conforms to the {@link java.util.Collection#isEmpty} and
239      * {@link java.util.Map#isEmpty} interfaces.
240      *
241      * @return whether the container is empty.
242      *
243      * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is thrown.
244      */

245     public boolean isEmpty() {
246
247         try {
248             return view.isEmpty();
249         } catch (Exception JavaDoc e) {
250             throw convertException(e);
251         }
252     }
253
254     /**
255      * Removes all mappings or elements from this map or collection (optional
256      * operation).
257      * This method conforms to the {@link java.util.Collection#clear} and
258      * {@link java.util.Map#clear} interfaces.
259      *
260      * @throws UnsupportedOperationException if the container is read-only.
261      *
262      * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is thrown.
263      */

264     public void clear() {
265
266         boolean doAutoCommit = beginAutoCommit();
267         try {
268             view.clear();
269             commitAutoCommit(doAutoCommit);
270         } catch (Exception JavaDoc e) {
271             throw handleException(e, doAutoCommit);
272         }
273     }
274
275     Object JavaDoc get(Object JavaDoc key) {
276
277         DataCursor cursor = null;
278         try {
279             cursor = new DataCursor(view, false);
280             if (OperationStatus.SUCCESS ==
281                 cursor.getSearchKey(key, null, false)) {
282                 return cursor.getCurrentValue();
283             } else {
284                 return null;
285             }
286         } catch (Exception JavaDoc e) {
287             throw StoredContainer.convertException(e);
288         } finally {
289             closeCursor(cursor);
290         }
291     }
292
293     Object JavaDoc put(final Object JavaDoc key, final Object JavaDoc value) {
294
295         DataCursor cursor = null;
296         boolean doAutoCommit = beginAutoCommit();
297         try {
298             cursor = new DataCursor(view, true);
299             Object JavaDoc[] oldValue = new Object JavaDoc[1];
300             cursor.put(key, value, oldValue, false);
301             closeCursor(cursor);
302             commitAutoCommit(doAutoCommit);
303             return oldValue[0];
304         } catch (Exception JavaDoc e) {
305             closeCursor(cursor);
306             throw handleException(e, doAutoCommit);
307         }
308     }
309
310     final boolean removeKey(final Object JavaDoc key, final Object JavaDoc[] oldVal) {
311
312         DataCursor cursor = null;
313         boolean doAutoCommit = beginAutoCommit();
314         try {
315             cursor = new DataCursor(view, true);
316             boolean found = false;
317             OperationStatus status = cursor.getSearchKey(key, null, true);
318             while (status == OperationStatus.SUCCESS) {
319                 cursor.delete();
320                 found = true;
321                 if (oldVal != null && oldVal[0] == null) {
322                     oldVal[0] = cursor.getCurrentValue();
323                 }
324                 status = areDuplicatesAllowed() ?
325                     cursor.getNextDup(true): OperationStatus.NOTFOUND;
326             }
327             closeCursor(cursor);
328             commitAutoCommit(doAutoCommit);
329             return found;
330         } catch (Exception JavaDoc e) {
331             closeCursor(cursor);
332             throw handleException(e, doAutoCommit);
333         }
334     }
335
336     boolean containsKey(Object JavaDoc key) {
337
338         DataCursor cursor = null;
339         try {
340             cursor = new DataCursor(view, false);
341             return OperationStatus.SUCCESS ==
342                    cursor.getSearchKey(key, null, false);
343         } catch (Exception JavaDoc e) {
344             throw StoredContainer.convertException(e);
345         } finally {
346             closeCursor(cursor);
347         }
348     }
349
350     final boolean removeValue(Object JavaDoc value) {
351
352         DataCursor cursor = null;
353         boolean doAutoCommit = beginAutoCommit();
354         try {
355             cursor = new DataCursor(view, true);
356             OperationStatus status = cursor.findValue(value, true);
357             if (status == OperationStatus.SUCCESS) {
358                 cursor.delete();
359             }
360             closeCursor(cursor);
361             commitAutoCommit(doAutoCommit);
362             return (status == OperationStatus.SUCCESS);
363         } catch (Exception JavaDoc e) {
364             closeCursor(cursor);
365             throw handleException(e, doAutoCommit);
366         }
367     }
368
369     boolean containsValue(Object JavaDoc value) {
370
371         DataCursor cursor = null;
372         try {
373             cursor = new DataCursor(view, false);
374             OperationStatus status = cursor.findValue(value, true);
375             return (status == OperationStatus.SUCCESS);
376         } catch (Exception JavaDoc e) {
377             throw StoredContainer.convertException(e);
378         } finally {
379             closeCursor(cursor);
380         }
381     }
382
383     /**
384      * Returns a StoredIterator if the given collection is a StoredCollection,
385      * else returns a regular/external Iterator. The iterator returned should
386      * be closed with the static method StoredIterator.close(Iterator).
387      */

388     final Iterator JavaDoc storedOrExternalIterator(Collection JavaDoc coll) {
389
390         if (coll instanceof StoredCollection) {
391             return ((StoredCollection) coll).storedIterator();
392         } else {
393             return coll.iterator();
394         }
395     }
396
397     final void closeCursor(DataCursor cursor) {
398
399         if (cursor != null) {
400             try {
401                 cursor.close();
402             } catch (Exception JavaDoc e) {
403                 throw StoredContainer.convertException(e);
404             }
405         }
406     }
407
408     final boolean beginAutoCommit() {
409
410         if (view.transactional) {
411             CurrentTransaction currentTxn = view.getCurrentTxn();
412             try {
413                 if (currentTxn.isAutoCommitAllowed()) {
414                     currentTxn.beginTransaction(null);
415                     return true;
416                 }
417             } catch (DatabaseException e) {
418                 throw new RuntimeExceptionWrapper(e);
419             }
420         }
421         return false;
422     }
423
424     final void commitAutoCommit(boolean doAutoCommit)
425         throws DatabaseException {
426
427         if (doAutoCommit) view.getCurrentTxn().commitTransaction();
428     }
429
430     final RuntimeException JavaDoc handleException(Exception JavaDoc e, boolean doAutoCommit) {
431
432         if (doAutoCommit) {
433             try {
434                 view.getCurrentTxn().abortTransaction();
435             } catch (DatabaseException ignored) {
436         /* Klockwork - ok */
437             }
438         }
439         return StoredContainer.convertException(e);
440     }
441
442     static RuntimeException JavaDoc convertException(Exception JavaDoc e) {
443
444         if (e instanceof RuntimeException JavaDoc) {
445             return (RuntimeException JavaDoc) e;
446         } else {
447             return new RuntimeExceptionWrapper(e);
448         }
449     }
450 }
451
Popular Tags