00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 package com.sleepycat.collections;
00011
00012 import com.sleepycat.compat.DbCompat;
00013 import com.sleepycat.db.CursorConfig;
00014 import com.sleepycat.db.DatabaseException;
00015 import com.sleepycat.db.OperationStatus;
00016 import com.sleepycat.util.RuntimeExceptionWrapper;
00017
00051 public abstract class StoredContainer implements Cloneable {
00052
00053 DataView view;
00054
00055 StoredContainer(DataView view) {
00056
00057 this.view = view;
00058 }
00059
00068 public final boolean isWriteAllowed() {
00069
00070 return view.writeAllowed;
00071 }
00072
00084 public final CursorConfig getCursorConfig() {
00085
00086 return DbCompat.cloneCursorConfig(view.cursorConfig);
00087 }
00088
00105 public final boolean isDirtyReadAllowed() {
00106
00107 return view.readUncommittedAllowed;
00108 }
00109
00115 public final boolean isDirtyRead() {
00116
00117 return view.cursorConfig.getReadUncommitted();
00118 }
00119
00131 public final boolean isTransactional() {
00132
00133 return view.transactional;
00134 }
00135
00139 final StoredContainer configuredClone(CursorConfig config) {
00140
00141 try {
00142 StoredContainer cont = (StoredContainer) clone();
00143 cont.view = cont.view.configuredView(config);
00144 cont.initAfterClone();
00145 return cont;
00146 } catch (CloneNotSupportedException willNeverOccur) { return null; }
00147 }
00148
00152 void initAfterClone() {
00153 }
00154
00165 public final boolean areDuplicatesAllowed() {
00166
00167 return view.dupsAllowed;
00168 }
00169
00181 public final boolean areDuplicatesOrdered() {
00182
00183 return view.dupsOrdered;
00184 }
00185
00197 public final boolean areKeysRenumbered() {
00198
00199 return view.keysRenumbered;
00200 }
00201
00213 public final boolean isOrdered() {
00214
00215 return view.ordered;
00216 }
00217
00226 public final boolean isSecondary() {
00227
00228 return view.isSecondary();
00229 }
00230
00241 public int size() {
00242
00243 throw new UnsupportedOperationException(
00244 "collection size not available");
00245 }
00246
00256 public boolean isEmpty() {
00257
00258 try {
00259 return view.isEmpty();
00260 } catch (Exception e) {
00261 throw convertException(e);
00262 }
00263 }
00264
00275 public void clear() {
00276
00277 boolean doAutoCommit = beginAutoCommit();
00278 try {
00279 view.clear();
00280 commitAutoCommit(doAutoCommit);
00281 } catch (Exception e) {
00282 throw handleException(e, doAutoCommit);
00283 }
00284 }
00285
00286 Object get(Object key) {
00287
00288 DataCursor cursor = null;
00289 try {
00290 cursor = new DataCursor(view, false);
00291 if (OperationStatus.SUCCESS ==
00292 cursor.getSearchKey(key, null, false)) {
00293 return cursor.getCurrentValue();
00294 } else {
00295 return null;
00296 }
00297 } catch (Exception e) {
00298 throw StoredContainer.convertException(e);
00299 } finally {
00300 closeCursor(cursor);
00301 }
00302 }
00303
00304 Object put(final Object key, final Object value) {
00305
00306 DataCursor cursor = null;
00307 boolean doAutoCommit = beginAutoCommit();
00308 try {
00309 cursor = new DataCursor(view, true);
00310 Object[] oldValue = new Object[1];
00311 cursor.put(key, value, oldValue, false);
00312 closeCursor(cursor);
00313 commitAutoCommit(doAutoCommit);
00314 return oldValue[0];
00315 } catch (Exception e) {
00316 closeCursor(cursor);
00317 throw handleException(e, doAutoCommit);
00318 }
00319 }
00320
00321 final boolean removeKey(final Object key, final Object[] oldVal) {
00322
00323 DataCursor cursor = null;
00324 boolean doAutoCommit = beginAutoCommit();
00325 try {
00326 cursor = new DataCursor(view, true);
00327 boolean found = false;
00328 OperationStatus status = cursor.getSearchKey(key, null, true);
00329 while (status == OperationStatus.SUCCESS) {
00330 cursor.delete();
00331 found = true;
00332 if (oldVal != null && oldVal[0] == null) {
00333 oldVal[0] = cursor.getCurrentValue();
00334 }
00335 status = areDuplicatesAllowed() ?
00336 cursor.getNextDup(true): OperationStatus.NOTFOUND;
00337 }
00338 closeCursor(cursor);
00339 commitAutoCommit(doAutoCommit);
00340 return found;
00341 } catch (Exception e) {
00342 closeCursor(cursor);
00343 throw handleException(e, doAutoCommit);
00344 }
00345 }
00346
00347 boolean containsKey(Object key) {
00348
00349 DataCursor cursor = null;
00350 try {
00351 cursor = new DataCursor(view, false);
00352 return OperationStatus.SUCCESS ==
00353 cursor.getSearchKey(key, null, false);
00354 } catch (Exception e) {
00355 throw StoredContainer.convertException(e);
00356 } finally {
00357 closeCursor(cursor);
00358 }
00359 }
00360
00361 final boolean removeValue(Object value) {
00362
00363 DataCursor cursor = null;
00364 boolean doAutoCommit = beginAutoCommit();
00365 try {
00366 cursor = new DataCursor(view, true);
00367 OperationStatus status = cursor.find(value, true);
00368 if (status == OperationStatus.SUCCESS) {
00369 cursor.delete();
00370 }
00371 closeCursor(cursor);
00372 commitAutoCommit(doAutoCommit);
00373 return (status == OperationStatus.SUCCESS);
00374 } catch (Exception e) {
00375 closeCursor(cursor);
00376 throw handleException(e, doAutoCommit);
00377 }
00378 }
00379
00380 boolean containsValue(Object value) {
00381
00382 DataCursor cursor = null;
00383 try {
00384 cursor = new DataCursor(view, false);
00385 OperationStatus status = cursor.find(value, true);
00386 return (status == OperationStatus.SUCCESS);
00387 } catch (Exception e) {
00388 throw StoredContainer.convertException(e);
00389 } finally {
00390 closeCursor(cursor);
00391 }
00392 }
00393
00394 final void closeCursor(DataCursor cursor) {
00395
00396 if (cursor != null) {
00397 try {
00398 cursor.close();
00399 } catch (Exception e) {
00400 throw StoredContainer.convertException(e);
00401 }
00402 }
00403 }
00404
00405 final boolean beginAutoCommit() {
00406
00407 if (view.transactional) {
00408 CurrentTransaction currentTxn = view.getCurrentTxn();
00409 try {
00410 if (currentTxn.isAutoCommitAllowed()) {
00411 currentTxn.beginTransaction(null);
00412 return true;
00413 }
00414 } catch (DatabaseException e) {
00415 throw new RuntimeExceptionWrapper(e);
00416 }
00417 }
00418 return false;
00419 }
00420
00421 final void commitAutoCommit(boolean doAutoCommit)
00422 throws DatabaseException {
00423
00424 if (doAutoCommit) view.getCurrentTxn().commitTransaction();
00425 }
00426
00427 final RuntimeException handleException(Exception e, boolean doAutoCommit) {
00428
00429 if (doAutoCommit) {
00430 try {
00431 view.getCurrentTxn().abortTransaction();
00432 } catch (DatabaseException ignored) {
00433
00434 }
00435 }
00436 return StoredContainer.convertException(e);
00437 }
00438
00439 static RuntimeException convertException(Exception e) {
00440
00441 if (e instanceof RuntimeException) {
00442 return (RuntimeException) e;
00443 } else {
00444 return new RuntimeExceptionWrapper(e);
00445 }
00446 }
00447 }