Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

StoredList.java

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2000-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: StoredList.java,v 12.1 2005/01/31 19:27:32 mark Exp $
00008  */
00009 
00010 package com.sleepycat.collections;
00011 
00012 import java.util.Collection;
00013 import java.util.Iterator;
00014 import java.util.List;
00015 import java.util.ListIterator;
00016 
00017 import com.sleepycat.bind.EntityBinding;
00018 import com.sleepycat.bind.EntryBinding;
00019 import com.sleepycat.bind.RecordNumberBinding;
00020 import com.sleepycat.db.Database;
00021 import com.sleepycat.db.DatabaseEntry;
00022 import com.sleepycat.db.DatabaseException;
00023 import com.sleepycat.db.OperationStatus;
00024 
00057 public class StoredList extends StoredCollection implements List {
00058 
00059     private static final EntryBinding DEFAULT_KEY_BINDING =
00060         new IndexKeyBinding(1);
00061 
00062     private int baseIndex = 1;
00063     private boolean isSubList;
00064 
00082     public StoredList(Database database, EntryBinding valueBinding,
00083                       boolean writeAllowed) {
00084 
00085         super(new DataView(database, DEFAULT_KEY_BINDING, valueBinding, null,
00086                            writeAllowed, null));
00087     }
00088 
00106     public StoredList(Database database, EntityBinding valueEntityBinding,
00107                       boolean writeAllowed) {
00108 
00109         super(new DataView(database, DEFAULT_KEY_BINDING, null,
00110                            valueEntityBinding, writeAllowed, null));
00111     }
00112 
00131     public StoredList(Database database, EntryBinding valueBinding,
00132                       PrimaryKeyAssigner keyAssigner) {
00133 
00134         super(new DataView(database, DEFAULT_KEY_BINDING, valueBinding,
00135                            null, true, keyAssigner));
00136     }
00137 
00156     public StoredList(Database database, EntityBinding valueEntityBinding,
00157                       PrimaryKeyAssigner keyAssigner) {
00158 
00159         super(new DataView(database, DEFAULT_KEY_BINDING, null,
00160                            valueEntityBinding, true, keyAssigner));
00161     }
00162 
00163     private StoredList(DataView view, int baseIndex) {
00164 
00165         super(view);
00166         this.baseIndex = baseIndex;
00167         this.isSubList = true;
00168     }
00169 
00182     public void add(int index, Object value) {
00183 
00184         checkIterAddAllowed();
00185         DataCursor cursor = null;
00186         boolean doAutoCommit = beginAutoCommit();
00187         try {
00188             cursor = new DataCursor(view, true);
00189             OperationStatus status =
00190                 cursor.getSearchKey(new Long(index), null, false);
00191             if (status == OperationStatus.SUCCESS) {
00192                 cursor.putBefore(value);
00193                 closeCursor(cursor);
00194             } else {
00195                 closeCursor(cursor);
00196                 cursor = null;
00197                 view.append(value, null, null);
00198             }
00199             commitAutoCommit(doAutoCommit);
00200         } catch (Exception e) {
00201             closeCursor(cursor);
00202             throw handleException(e, doAutoCommit);
00203         }
00204     }
00205 
00218     public boolean add(Object value) {
00219 
00220         checkIterAddAllowed();
00221         boolean doAutoCommit = beginAutoCommit();
00222         try {
00223             view.append(value, null, null);
00224             commitAutoCommit(doAutoCommit);
00225             return true;
00226         } catch (Exception e) {
00227             throw handleException(e, doAutoCommit);
00228         }
00229     }
00230 
00251     public int append(Object value) {
00252 
00253         boolean doAutoCommit = beginAutoCommit();
00254         try {
00255             Object[] key = new Object[1];
00256             view.append(value, key, null);
00257             commitAutoCommit(doAutoCommit);
00258             return ((Number) key[0]).intValue();
00259         } catch (Exception e) {
00260             throw handleException(e, doAutoCommit);
00261         }
00262     }
00263 
00264     void checkIterAddAllowed()
00265         throws UnsupportedOperationException {
00266 
00267         if (isSubList) {
00268             throw new UnsupportedOperationException("cannot add to subList");
00269         }
00270         if (!view.keysRenumbered) { // RECNO-RENUM
00271             throw new UnsupportedOperationException(
00272                 "requires renumbered keys");
00273         }
00274     }
00275 
00289     public boolean addAll(int index, Collection coll) {
00290 
00291         checkIterAddAllowed();
00292         DataCursor cursor = null;
00293         Iterator i = null;
00294         boolean doAutoCommit = beginAutoCommit();
00295         try {
00296             i = coll.iterator();
00297             if (!i.hasNext()) {
00298                 return false;
00299             }
00300             cursor = new DataCursor(view, true);
00301             OperationStatus status =
00302                 cursor.getSearchKey(new Long(index), null, false);
00303             if (status == OperationStatus.SUCCESS) {
00304                 while (i.hasNext()) {
00305                     cursor.putBefore(i.next());
00306                 }
00307                 closeCursor(cursor);
00308             } else {
00309                 closeCursor(cursor);
00310                 cursor = null;
00311                 while (i.hasNext()) {
00312                     view.append(i.next(), null, null);
00313                 }
00314             }
00315             StoredIterator.close(i);
00316             commitAutoCommit(doAutoCommit);
00317             return true;
00318         } catch (Exception e) {
00319             closeCursor(cursor);
00320             StoredIterator.close(i);
00321             throw handleException(e, doAutoCommit);
00322         }
00323     }
00324 
00332     public boolean contains(Object value) {
00333 
00334         return containsValue(value);
00335     }
00336 
00344     public Object get(int index) {
00345 
00346         return super.get(new Long(index));
00347     }
00348 
00357     public int indexOf(Object value) {
00358 
00359         return indexOf(value, true);
00360     }
00361 
00370     public int lastIndexOf(Object value) {
00371 
00372         return indexOf(value, false);
00373     }
00374 
00375     private int indexOf(Object value, boolean findFirst) {
00376 
00377         DataCursor cursor = null;
00378         try {
00379             cursor = new DataCursor(view, false);
00380             OperationStatus status = cursor.find(value, findFirst);
00381             return (status == OperationStatus.SUCCESS)
00382                     ? (cursor.getCurrentRecordNumber() - baseIndex)
00383                     : (-1);
00384         } catch (Exception e) {
00385             throw StoredContainer.convertException(e);
00386         } finally {
00387             closeCursor(cursor);
00388         }
00389     }
00390 
00391     int getIndexOffset() {
00392 
00393         return baseIndex;
00394     }
00395 
00409     public ListIterator listIterator() {
00410 
00411         return iterator(isWriteAllowed());
00412     }
00413 
00427     public ListIterator listIterator(int index) {
00428 
00429         StoredIterator i = iterator(isWriteAllowed());
00430         if (i.moveToIndex(index)) {
00431             return i;
00432         } else {
00433             i.close();
00434             throw new IndexOutOfBoundsException(String.valueOf(index));
00435         }
00436     }
00437 
00449     public Object remove(int index) {
00450 
00451         try {
00452             Object[] oldVal = new Object[1];
00453             removeKey(new Long(index), oldVal);
00454             return oldVal[0];
00455         } catch (IllegalArgumentException e) {
00456             throw new IndexOutOfBoundsException(e.getMessage());
00457         }
00458     }
00459 
00471     public boolean remove(Object value) {
00472 
00473         return removeValue(value);
00474     }
00475 
00491     public Object set(int index, Object value) {
00492 
00493         try {
00494             return put(new Long(index), value);
00495         } catch (IllegalArgumentException e) {
00496             throw new IndexOutOfBoundsException(e.getMessage());
00497         }
00498     }
00499 
00509     public List subList(int fromIndex, int toIndex) {
00510 
00511         if (fromIndex < 0 || fromIndex > toIndex) {
00512             throw new IndexOutOfBoundsException(String.valueOf(fromIndex));
00513         }
00514         try {
00515             int newBaseIndex = baseIndex + fromIndex;
00516             return new StoredList(
00517                 view.subView(new Long(fromIndex), true,
00518                              new Long(toIndex), false,
00519                              new IndexKeyBinding(newBaseIndex)),
00520                 newBaseIndex);
00521         } catch (KeyRangeException e) {
00522             throw new IndexOutOfBoundsException(e.getMessage());
00523         } catch (Exception e) {
00524             throw StoredContainer.convertException(e);
00525         }
00526     }
00527 
00537     public boolean equals(Object other) {
00538 
00539         if (!(other instanceof List)) return false;
00540         List otherList = (List) other;
00541         ListIterator i1 = null;
00542         ListIterator i2 = null;
00543         try {
00544             i1 = listIterator();
00545             i2 = otherList.listIterator();
00546             while (i1.hasNext()) {
00547                 if (!i2.hasNext()) return false;
00548                 if (i1.nextIndex() != i2.nextIndex()) return false;
00549                 Object o1 = i1.next();
00550                 Object o2 = i2.next();
00551                 if (o1 == null) {
00552                     if (o2 != null) return false;
00553                 } else {
00554                     if (!o1.equals(o2)) return false;
00555                 }
00556             }
00557             if (i2.hasNext()) return false;
00558             return true;
00559         } finally {
00560             StoredIterator.close(i1);
00561             StoredIterator.close(i2);
00562         }
00563     }
00564 
00565     /*
00566      * Add this in to keep FindBugs from whining at us about implementing
00567      * equals(), but not hashCode().
00568      */
00569     public int hashCode() {
00570         return super.hashCode();
00571     }
00572 
00573     Object makeIteratorData(StoredIterator iterator, DataCursor cursor)
00574         throws DatabaseException {
00575 
00576         return cursor.getCurrentValue();
00577     }
00578 
00579     boolean hasValues() {
00580 
00581         return true;
00582     }
00583 
00584     private static class IndexKeyBinding extends RecordNumberBinding {
00585 
00586         private int baseIndex;
00587 
00588         private IndexKeyBinding(int baseIndex) {
00589 
00590             this.baseIndex = baseIndex;
00591         }
00592 
00593         public Object entryToObject(DatabaseEntry data) {
00594 
00595             return new Long(entryToRecordNumber(data) - baseIndex);
00596         }
00597 
00598         public void objectToEntry(Object object, DatabaseEntry data) {
00599 
00600             recordNumberToEntry(((Number) object).intValue() + baseIndex,
00601                                 data);
00602         }
00603     }
00604 }

Generated on Sun Dec 25 12:14:31 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2