/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2000 Blacksmith, Inc. 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.foundation; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * NSMutableArray extends NSArray to allow modification. * * @author michael@mpowers.net * @author $Author: cgruber $ * @version $Revision: 893 $ */ public class NSMutableArray extends NSArray { private static final long serialVersionUID = 2414783500843649556L; /** * Returns an NSArray backed by the specified List. This is useful to "protect" * an internal representation that is returned by a method of return type * NSArray. */ public static NSMutableArray mutableArrayBackedByList(List aList) { return new NSMutableArray<>(aList, null); } NSMutableArray(List aList, Object ignored) // differentiates { super(aList, ignored); } /** * Default constructor returns an empty array. */ public NSMutableArray() { super(); //System.out.println( "NSMutableArray: " + net.wotonomy.ui.swing.util.StackTraceInspector.getMyCaller() ); } /** * Constructor with a size hint. */ public NSMutableArray(int aSize) { super(); //System.out.println( "NSMutableArray: " + net.wotonomy.ui.swing.util.StackTraceInspector.getMyCaller() ); } /** * Produces an array containing only the specified object. */ public NSMutableArray(T anObject) { super(anObject); //System.out.println( "NSMutableArray: " + net.wotonomy.ui.swing.util.StackTraceInspector.getMyCaller() ); } /** * Produces an array containing the specified objects. */ public NSMutableArray(T[] anArray) { super(anArray); //System.out.println( "NSMutableArray: " + net.wotonomy.ui.swing.util.StackTraceInspector.getMyCaller() ); } /** * Produces an array containing the objects in the specified collection. */ public NSMutableArray(Collection aCollection) { super(aCollection); //System.out.println( "NSMutableArray: " + net.wotonomy.ui.swing.util.StackTraceInspector.getMyCaller() ); } /** * Removes the last object from the array. */ public void removeLastObject() { list.remove(count() - 1); } /** * Removes the object at the specified index. */ public void removeObjectAtIndex(int index) { list.remove(index); } /** * Adds all objects in the specified collection. */ public void addObjectsFromArray(Collection aCollection) { list.addAll(aCollection); } /** * Removes all objects from the array. */ public void removeAllObjects() { list.clear(); } /** * Removes all objects equivalent to the specified object within the range of * specified indices. */ public void removeObject(T 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(list.get(i))) { list.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(T 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 == list.get(i)) { list.remove(i); i = i - 1; max = max - 1; } } } /** * Removes all objects in the specified collection from the array. */ public void removeObjectsInArray(Collection aCollection) { list.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++) { list.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); } List subList = list.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++) { list.add(otherArray.get(i)); } } /** * Clears the current array and then populates it with the contents of the * specified collection. */ public void setArray(Collection aCollection) { list.clear(); list.addAll(aCollection); } /** * Sorts this array using the values from the specified selector. */ public void sortUsingSelector(NSSelector aSelector) { // TODO: implement throw new UnsupportedOperationException("Not implemented yet."); } /** * Removes all objects equivalent to the specified object. */ public void removeObject(Object anObject) { list.remove(anObject); } /** * Removes all occurences of the specified object, comparing by reference. */ public void removeIdenticalObject(T anObject) { Iterator it = list.iterator(); while (it.hasNext()) { if (it.next() == anObject) { it.remove(); } } } /** * Inserts the specified object into this array at the specified index. */ public void insertObjectAtIndex(T anObject, int anIndex) { list.add(anIndex, anObject); } /** * Replaces the object at the specified index with the specified object. */ public void replaceObjectAtIndex(int anIndex, T anObject) { list.set(anIndex, anObject); } /** * Adds the specified object to the end of this array. */ public void addObject(T anObject) { list.add(anObject); } @Override public Object clone() { return new NSMutableArray<>(list); } @Override public NSArray immutableClone() { return new NSArray<>(this); } @Override public NSMutableArray mutableClone() { return new NSMutableArray<>(this); } // interface List: mutators @Override public void add(int index, T element) { list.add(index, element); } @Override public boolean add(T o) { return list.add(o); } @Override public boolean addAll(Collection coll) { return list.addAll(coll); } @Override public boolean addAll(int index, Collection c) { return list.addAll(index, c); } @Override public void clear() { list.clear(); } @Override public Iterator iterator() { return list.iterator(); } @Override public ListIterator listIterator() { return list.listIterator(); } @Override public ListIterator listIterator(int index) { return list.listIterator(index); } @Override public T remove(int index) { return list.remove(index); } @Override public boolean remove(Object o) { return list.remove(o); } @Override public boolean removeAll(Collection coll) { return list.removeAll(coll); } @Override public boolean retainAll(Collection coll) { return list.retainAll(coll); } @Override public T set(int index, T element) { return list.set(index, element); } @Override public List subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } } /* * $Log$ Revision 1.2 2006/02/16 13:15:00 cgruber Check in all sources in * eclipse-friendly maven-enabled packages. * * Revision 1.8 2005/07/13 14:12:44 cgruber Add mutableClone() and * immutableClone() per. WebObjects 5.3 conformance. * * Revision 1.7 2003/08/06 23:07:52 chochos general code cleanup (mostly, * removing unused imports) * * Revision 1.6 2003/01/16 22:47:30 mpowers Compatibility changes to support * compiling woextensions source. (34 out of 56 classes compile!) * * Revision 1.5 2003/01/10 19:16:40 mpowers Implemented support for page * caching. * * Revision 1.4 2002/10/24 21:15:36 mpowers New implementations of NSArray and * subclasses. * * Revision 1.3 2002/10/24 18:16:30 mpowers Now enforcing NSArray's immutable * nature. * * Revision 1.2 2001/01/11 20:34:26 mpowers Implemented EOSortOrdering and added * support in framework. Added header-click to sort table columns. * * Revision 1.1.1.1 2000/12/21 15:47:31 mpowers Contributing wotonomy. * * Revision 1.3 2000/12/20 16:25:38 michael Added log to all files. * * */