1 8 9 package com.sleepycat.collections; 10 11 import java.util.Iterator ; 12 import java.util.ListIterator ; 13 import java.util.NoSuchElementException ; 14 15 import com.sleepycat.je.DatabaseException; 16 import com.sleepycat.je.OperationStatus; 17 import com.sleepycat.util.RuntimeExceptionWrapper; 18 19 52 public class StoredIterator implements BaseIterator, Cloneable { 53 54 63 public static void close(Iterator i) { 64 65 if (i instanceof StoredIterator) { 66 ((StoredIterator) i).close(); 67 } 68 } 69 70 private static final int MOVE_NEXT = 1; 71 private static final int MOVE_PREV = 2; 72 private static final int MOVE_FIRST = 3; 73 74 private boolean lockForWrite; 75 private StoredCollection coll; 76 private DataCursor cursor; 77 private int toNext; 78 private int toPrevious; 79 private int toCurrent; 80 private boolean writeAllowed; 81 private boolean setAndRemoveAllowed; 82 private Object currentData; 83 84 StoredIterator(StoredCollection coll, boolean writeAllowed, 85 DataCursor joinCursor) { 86 try { 87 this.coll = coll; 88 this.writeAllowed = writeAllowed; 89 if (joinCursor == null) 90 this.cursor = new DataCursor(coll.view, writeAllowed); 91 else 92 this.cursor = joinCursor; 93 reset(); 94 } catch (Exception e) { 95 try { 96 97 close(); 98 } catch (Exception ignored) { 99 100 } 101 throw StoredContainer.convertException(e); 102 } 103 } 104 105 113 public final boolean isReadModifyWrite() { 114 115 return lockForWrite; 116 } 117 118 126 public void setReadModifyWrite(boolean lockForWrite) { 127 128 this.lockForWrite = lockForWrite; 129 } 130 131 133 142 public boolean hasNext() { 143 144 if (cursor == null) { 145 return false; 146 } 147 try { 148 if (toNext != 0) { 149 OperationStatus status = move(toNext); 150 if (status == OperationStatus.SUCCESS) { 151 toNext = 0; 152 toPrevious = MOVE_PREV; 153 toCurrent = MOVE_PREV; 154 } 155 } 156 return (toNext == 0); 157 } catch (Exception e) { 158 throw StoredContainer.convertException(e); 159 } 160 } 161 162 171 public boolean hasPrevious() { 172 173 if (cursor == null) { 174 return false; 175 } 176 try { 177 if (toPrevious != 0) { 178 OperationStatus status = move(toPrevious); 179 if (status == OperationStatus.SUCCESS) { 180 toPrevious = 0; 181 toNext = MOVE_NEXT; 182 toCurrent = MOVE_NEXT; 183 } 184 } 185 return (toPrevious == 0); 186 } catch (Exception e) { 187 throw StoredContainer.convertException(e); 188 } 189 } 190 191 200 public Object next() { 201 202 try { 203 if (toNext != 0) { 204 OperationStatus status = move(toNext); 205 if (status == OperationStatus.SUCCESS) { 206 toNext = 0; 207 } 208 } 209 if (toNext == 0) { 210 currentData = coll.makeIteratorData(this, cursor); 211 toNext = MOVE_NEXT; 212 toPrevious = 0; 213 toCurrent = 0; 214 setAndRemoveAllowed = true; 215 return currentData; 216 } 217 } catch (Exception e) { 219 throw StoredContainer.convertException(e); 220 } 221 throw new NoSuchElementException (); 222 } 223 224 233 public Object previous() { 234 235 try { 236 if (toPrevious != 0) { 237 OperationStatus status = move(toPrevious); 238 if (status == OperationStatus.SUCCESS) { 239 toPrevious = 0; 240 } 241 } 242 if (toPrevious == 0) { 243 currentData = coll.makeIteratorData(this, cursor); 244 toPrevious = MOVE_PREV; 245 toNext = 0; 246 toCurrent = 0; 247 setAndRemoveAllowed = true; 248 return currentData; 249 } 250 } catch (Exception e) { 252 throw StoredContainer.convertException(e); 253 } 254 throw new NoSuchElementException (); 255 } 256 257 274 public int nextIndex() { 275 276 if (!coll.view.recNumAccess) { 277 throw new UnsupportedOperationException ( 278 "Record number access not supported"); 279 } 280 try { 281 return hasNext() ? (cursor.getCurrentRecordNumber() - 282 coll.getIndexOffset()) 283 : Integer.MAX_VALUE; 284 } catch (Exception e) { 285 throw StoredContainer.convertException(e); 286 } 287 } 288 289 303 public int previousIndex() { 304 305 if (!coll.view.recNumAccess) { 306 throw new UnsupportedOperationException ( 307 "Record number access not supported"); 308 } 309 try { 310 return hasPrevious() ? (cursor.getCurrentRecordNumber() - 311 coll.getIndexOffset()) 312 : (-1); 313 } catch (Exception e) { 314 throw StoredContainer.convertException(e); 315 } 316 } 317 318 337 public void set(Object value) { 338 339 if (!coll.hasValues()) throw new UnsupportedOperationException (); 340 if (!setAndRemoveAllowed) throw new IllegalStateException (); 341 try { 342 moveToCurrent(); 343 cursor.putCurrent(value); 344 } catch (Exception e) { 345 throw StoredContainer.convertException(e); 346 } 347 } 348 349 366 public void remove() { 367 368 if (!setAndRemoveAllowed) throw new IllegalStateException (); 369 try { 370 moveToCurrent(); 371 cursor.delete(); 372 setAndRemoveAllowed = false; 373 } catch (Exception e) { 374 throw StoredContainer.convertException(e); 375 } 376 } 377 378 408 public void add(Object value) { 409 410 coll.checkIterAddAllowed(); 411 try { 412 OperationStatus status = OperationStatus.SUCCESS; 413 if (toNext != 0 && toPrevious != 0) { if (coll.view.keysRenumbered) { 421 close(); 422 status = coll.view.append(value, null, null); 423 cursor = new DataCursor(coll.view, writeAllowed); 424 reset(); 425 next(); } else { throw new IllegalStateException ( 428 "Collection is empty, cannot add() duplicate"); 429 } 430 } else { boolean putBefore = false; 432 if (coll.view.keysRenumbered) { moveToCurrent(); 434 if (hasNext()) { 435 status = cursor.putBefore(value); 436 putBefore = true; 437 } else { 438 status = cursor.putAfter(value); 439 } 440 } else { if (coll.areDuplicatesOrdered()) { 442 status = cursor.putNoDupData(null, value, null, true); 443 } else if (toNext == 0) { 444 status = cursor.putBefore(value); 445 putBefore = true; 446 } else { 447 status = cursor.putAfter(value); 448 } 449 } 450 if (putBefore) { 451 toPrevious = 0; 452 toNext = MOVE_NEXT; 453 } 454 } 455 if (status == OperationStatus.KEYEXIST) { 456 throw new IllegalArgumentException ("Duplicate value"); 457 } else if (status != OperationStatus.SUCCESS) { 458 throw new IllegalArgumentException ("Could not insert: " + 459 status); 460 } 461 setAndRemoveAllowed = false; 462 } catch (Exception e) { 463 throw StoredContainer.convertException(e); 464 } 465 } 466 467 469 472 private void reset() { 473 474 toNext = MOVE_FIRST; 475 toPrevious = MOVE_PREV; 476 toCurrent = 0; 477 currentData = null; 478 484 hasNext(); 485 } 486 487 500 public int count() { 501 502 if (!setAndRemoveAllowed) throw new IllegalStateException (); 503 try { 504 moveToCurrent(); 505 return cursor.count(); 506 } catch (Exception e) { 507 throw StoredContainer.convertException(e); 508 } 509 } 510 511 525 public void close() { 526 527 if (cursor != null) { 528 coll.closeCursor(cursor); 529 cursor = null; 530 } 531 } 532 533 540 public final StoredCollection getCollection() { 541 542 return coll; 543 } 544 545 547 public final ListIterator dup() { 548 549 try { 550 StoredIterator o = (StoredIterator) super.clone(); 551 o.cursor = cursor.cloneCursor(); 552 return o; 553 } catch (Exception e) { 554 throw StoredContainer.convertException(e); 555 } 556 } 557 558 public final boolean isCurrentData(Object currentData) { 559 560 return (this.currentData == currentData); 561 } 562 563 public final boolean moveToIndex(int index) { 564 565 try { 566 OperationStatus status = 567 cursor.getSearchKey(new Integer (index), null, lockForWrite); 568 setAndRemoveAllowed = (status == OperationStatus.SUCCESS); 569 return setAndRemoveAllowed; 570 } catch (Exception e) { 571 throw StoredContainer.convertException(e); 572 } 573 } 574 575 577 private void moveToCurrent() 578 throws DatabaseException { 579 580 if (toCurrent != 0) { 581 move(toCurrent); 582 toCurrent = 0; 583 } 584 } 585 586 private OperationStatus move(int direction) 587 throws DatabaseException { 588 589 switch (direction) { 590 case MOVE_NEXT: 591 if (coll.iterateDuplicates()) { 592 return cursor.getNext(lockForWrite); 593 } else { 594 return cursor.getNextNoDup(lockForWrite); 595 } 596 case MOVE_PREV: 597 if (coll.iterateDuplicates()) { 598 return cursor.getPrev(lockForWrite); 599 } else { 600 return cursor.getPrevNoDup(lockForWrite); 601 } 602 case MOVE_FIRST: 603 return cursor.getFirst(lockForWrite); 604 default: 605 throw new IllegalArgumentException (String.valueOf(direction)); 606 } 607 } 608 } 609 | Popular Tags |