diff options
Diffstat (limited to 'projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/ObservableArray.java')
| -rw-r--r-- | projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/ObservableArray.java | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/ObservableArray.java b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/ObservableArray.java new file mode 100644 index 0000000..19d39ff --- /dev/null +++ b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/ObservableArray.java @@ -0,0 +1,346 @@ +/* +Wotonomy: OpenStep design patterns for pure Java applications. +Copyright (C) 2001 Michael Powers + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, see http://www.gnu.org +*/ + +package net.wotonomy.control; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import net.wotonomy.foundation.NSMutableArray; +import net.wotonomy.foundation.NSRange; + +/** +* A package class that extends NSMutableArray but makes use +* of the fact that wotonomy's implementation extends ArrayList +* to intercept insertions and deletion and register and +* unregister objects for change notifications as appropriate. +* Since we can't be sure of ArrayList's implementation, we're +* forced to override each and every add and remove method, +* some of which probably call each other. However, +* EOObserverCenter will only register us once per object. +*/ +class ObservableArray extends NSMutableArray +{ + EOObserving observer; + + ObservableArray( EOObserving anObserver ) + { + observer = anObserver; + } + + /** + * Removes the last object from the array. + */ + public void removeLastObject () + { + remove( count() - 1 ); + } + + /** + * Removes the object at the specified index. + */ + public void removeObjectAtIndex (int index) + { + remove( index ); + } + + /** + * Adds all objects in the specified collection. + */ + public void addObjectsFromArray (Collection aCollection) + { + addAll( aCollection ); + } + + /** + * Removes all objects from the array. + */ + public void removeAllObjects () + { + clear(); + } + + /** + * Removes all objects equivalent to the specified object + * within the range of specified indices. + */ + public void removeObject (Object anObject, NSRange aRange) + { + if ( ( anObject == null ) || ( aRange == null ) ) return; + + int loc = aRange.location(); + int max = aRange.maxRange(); + for ( int i = loc; i < max; i++ ) + { + if ( anObject.equals( get( i ) ) ) + { + remove( i ); + i = i - 1; + max = max - 1; + } + } + } + + /** + * Removes all instances of the specified object within the + * range of specified indices, comparing by reference. + */ + public void removeIdenticalObject (Object anObject, NSRange aRange) + { + if ( ( anObject == null ) || ( aRange == null ) ) return; + + int loc = aRange.location(); + int max = aRange.maxRange(); + for ( int i = loc; i < max; i++ ) + { + if ( anObject == get( i ) ) + { + remove( i ); + i = i - 1; + max = max - 1; + } + } + } + + /** + * Removes all objects in the specified collection from the array. + */ + public void removeObjectsInArray (Collection aCollection) + { + removeAll( aCollection ); + } + + /** + * Removes all objects in the indices within the specified range + * from the array. + */ + public void removeObjectsInRange (NSRange aRange) + { + if ( aRange == null ) return; + + for ( int i = 0; i < aRange.length(); i++ ) + { + remove( aRange.location() ); + } + } + + /** + * Replaces objects in the current range with objects from + * the specified range of the specified array. If currentRange + * is larger than otherRange, the extra objects are removed. + * If otherRange is larger than currentRange, the extra objects + * are added. + */ + public void replaceObjectsInRange (NSRange currentRange, + List otherArray, NSRange otherRange) + { + if ( ( currentRange == null ) || ( otherArray == null ) || + ( otherRange == null ) ) return; + + // transform otherRange if out of bounds for array + if ( otherRange.maxRange() > otherArray.size() ) + { + // TODO: Test this logic. + int loc = Math.min( otherRange.location(), otherArray.size() - 1 ); + otherRange = new NSRange( loc, otherArray.size() - loc ); + } + + Object o; + List subList = subList( + currentRange.location(), currentRange.maxRange() ); + int otherIndex = otherRange.location(); + // TODO: Test this logic. + for ( int i = 0; i < subList.size(); i++ ) + { + if ( otherIndex < otherRange.maxRange() ) + { // set object + subList.set( i, otherArray.get( otherIndex ) ); + } + else + { // remove extra elements from currentRange + subList.remove( i ); + i--; + } + otherIndex++; + } + // TODO: Test this logic. + for ( int i = otherIndex; i < otherRange.maxRange(); i++ ) + { + add( otherArray.get( i ) ); + } + } + + /** + * Clears the current array and then populates it with the + * contents of the specified collection. + */ + public void setArray (Collection aCollection) + { + clear(); + addAll( aCollection ); + } + + /** + * Removes all objects equivalent to the specified object. + */ + public void removeObject (Object anObject) + { + remove( anObject ); + } + + /** + * Removes all occurences of the specified object, + * comparing by reference. + */ + public void removeIdenticalObject (Object anObject) + { + EOObserverCenter.removeObserver( observer, anObject ); + super.removeIdenticalObject( anObject ); + } + + /** + * Inserts the specified object into this array at the + * specified index. + */ + public void insertObjectAtIndex (Object anObject, int anIndex) + { + add( anIndex, anObject ); + } + + /** + * Replaces the object at the specified index with the + * specified object. + */ + public void replaceObjectAtIndex (int anIndex, Object anObject) + { + set( anIndex, anObject ); + } + + /** + * Adds the specified object to the end of this array. + */ + public void addObject (Object anObject) + { + add( anObject ); + } + + // interface List: mutators + + public void add(int index, Object element) + { + EOObserverCenter.addObserver( observer, element ); + super.add( index, element ); + } + + public boolean add(Object o) + { + EOObserverCenter.addObserver( observer, o ); + return super.add(o); + } + + public boolean addAll(Collection coll) + { + Iterator it = coll.iterator(); + while ( it.hasNext() ) + { + EOObserverCenter.addObserver( observer, it.next() ); + } + return super.addAll(coll); + } + + public boolean addAll(int index, Collection c) + { + Iterator it = c.iterator(); + while ( it.hasNext() ) + { + EOObserverCenter.addObserver( observer, it.next() ); + } + return super.addAll( index, c ); + } + + public void clear() + { + Iterator it = iterator(); + while ( it.hasNext() ) + { + EOObserverCenter.removeObserver( observer, it.next() ); + } + super.clear(); + } + + public Object remove(int index) + { + EOObserverCenter.removeObserver( observer, get(index) ); + return super.remove( index ); + } + + public boolean remove(Object o) + { + EOObserverCenter.removeObserver( observer, o ); + return super.remove(o); + } + + public boolean removeAll(Collection coll) + { + Iterator it = coll.iterator(); + while ( it.hasNext() ) + { + EOObserverCenter.removeObserver( observer, it.next() ); + } + return super.removeAll(coll); + } + + public boolean retainAll(Collection coll) + { + throw new UnsupportedOperationException(); + } + + public Object set(int index, Object element) + { + EOObserverCenter.removeObserver( observer, get(index) ); + EOObserverCenter.addObserver( observer, element ); + return super.set( index, element ); + } +} + +/* + * $Log$ + * Revision 1.2 2006/02/16 16:47:14 cgruber + * Move some classes in to "internal" packages and re-work imports, etc. + * + * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions. + * + * Revision 1.1 2006/02/16 13:19:57 cgruber + * Check in all sources in eclipse-friendly maven-enabled packages. + * + * Revision 1.1 2002/10/24 21:15:35 mpowers + * New implementations of NSArray and subclasses. + * + * Revision 1.1 2001/02/20 16:38:55 mpowers + * MasterDetailAssociations now observe their controlled display group's + * objects for changes to that the parent object will be marked as updated. + * Before, only inserts and deletes to an object's items are registered. + * Also, moved ObservableArray to package access. + * + * Revision 1.1 2001/01/24 14:37:24 mpowers + * Contributing a delegate useful for debugging. + * + * + */ + |
