/* File: CheckedBag.java Originally written by Doug Lea and released into the public domain. Thanks for the assistance and support of Sun Microsystems Labs, Agorics Inc, Loral, and everyone contributing, testing, and using this code. History: Date Who What 24Sep95 dl@cs.oswego.edu Create from collections.java working file 13Oct95 dl Misc clean up 19Oct95 dl More misc clean up */ package collections; import java.util.Enumeration; import java.util.NoSuchElementException; /** * * @author Doug Lea * @version 0.94 * *

For an introduction to this package see Overview . **/ public class CheckedBag extends CheckedCollection implements UpdatableBag { /** * Wrap Bag b inside a checker **/ public CheckedBag(UpdatableBag b) { super(b); } /** * Make a Checked clone of underlying collection **/ protected Object clone() throws CloneNotSupportedException { return new CheckedBag((UpdatableBag)(thys.duplicate())); } /** * return casted version of CheckedCollection.thys. **/ public UpdatableBag thys() { return (UpdatableBag)thys; } /** * return casted version of CheckedCollection.prev. **/ public UpdatableBag prev() { return (UpdatableBag)prev; } /** * Checks collections.UpdatableBag.addIfAbsent according to its specification * @see collections.UpdatableBag#addIfAbsent **/ public synchronized void addIfAbsent(Object element) throws IllegalElementException { preCheck(); try { thys().addIfAbsent(element); checkAdd(thys, prev, element, true, true); postCheck(); } catch (IllegalElementException ex) { assert(!prev.canInclude(element)); assert(thys.sameStructure(prev)); assert(thys.sameStructure(prev)); postCheck(); throw ex; } } /** * Checks collections.Bag.addingIfAbsent * @see collections.Bag#addingIfAbsent **/ public synchronized Bag addingIfAbsent(Object element) throws IllegalElementException { preCheck(); try { Bag nc = thys().addingIfAbsent(element); checkAdd(nc, thys, element, true, false); assert(thys.sameStructure(prev)); postCheck(); return nc; } catch (IllegalElementException ex) { assert(!prev.canInclude(element)); assert(thys.sameStructure(prev)); postCheck(); throw ex; } } /** * Checks collections.UpdatableBag.add according to its specification * @see collections.UpdatableBag#add **/ public synchronized void add(Object element) throws IllegalElementException { preCheck(); try { thys().add(element); checkAdd(thys, prev, element, false, true); postCheck(); } catch (IllegalElementException ex) { assert(!prev.canInclude(element)); assert(thys.sameStructure(prev)); postCheck(); throw ex; } } /** * Checks collections.Bag.adding * @see collections.Bag#adding **/ public synchronized Bag adding(Object element) throws IllegalElementException { preCheck(); try { Bag nc = thys().adding(element); checkAdd(nc, thys, element, false, false); assert(thys.sameStructure(prev)); postCheck(); return nc; } catch (IllegalElementException ex) { assert(!prev.canInclude(element)); assert(thys.sameStructure(prev)); postCheck(); throw ex; } } /** * Checks collections.UpdatableBag.addElements * @see collections.UpdatableBag#addElements **/ public synchronized void addElements(Enumeration e) throws IllegalElementException, CorruptedEnumerationException { preCheck(); thys().addElements(e); // can't check for elements because e is exhausted postCheck(); } /** * Helper for checking add* **/ protected void checkAdd(Collection nc, Collection oc, Object element, boolean ifAbsent, boolean verchk) { assert(nc.canInclude(element)); int oOcc = oc.occurrencesOf(element); int reqOcc = oOcc + 1; if (ifAbsent && oOcc != 0) reqOcc = oOcc; int nOcc = nc.occurrencesOf(element); assert(nOcc == reqOcc); assert(nc.size() == oc.size() + (reqOcc - oOcc)); if (verchk) { int nv = ((UpdatableCollection)nc).version(); assert((nv == prevVersion) == (nOcc == oOcc)); } // all other elements the same CollectionEnumeration os = oc.elements(); while (os.hasMoreElements()) { Object v = os.nextElement(); assert((v.equals(element) || (nc.occurrencesOf(v) == oc.occurrencesOf(v)))); } nc.checkImplementation(); } }