Initial commit from SVN.
This commit is contained in:
532
Common/src/com/common/util/LiteCollection.java
Normal file
532
Common/src/com/common/util/LiteCollection.java
Normal file
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Copyright (c) 2002,2008 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.common.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.common.comparison.IComparator;
|
||||
import com.common.event.*;
|
||||
import com.common.exception.*;
|
||||
|
||||
/**
|
||||
* The LiteCollection base class provides collection functionality without any event handling or synchronization.
|
||||
* If you need event handling or synchronization you should use a collection class that extends Collection.
|
||||
*/
|
||||
public abstract class LiteCollection implements ICollection {
|
||||
private boolean isChangeable = true;
|
||||
/**
|
||||
* LiteCollection constructor.
|
||||
*/
|
||||
protected LiteCollection() {
|
||||
super();
|
||||
}//LiteCollection()//
|
||||
/**
|
||||
* LiteCollection constructor.
|
||||
* @param isChangeable Whether the collection may be changed. This should be false if the collection may no longer be modified.
|
||||
*/
|
||||
protected LiteCollection(boolean isChangeable) {
|
||||
super();
|
||||
|
||||
this.isChangeable = isChangeable;
|
||||
}//LiteCollection()//
|
||||
/**
|
||||
* Ensures that the collection can hold at least the number of components specified by the minimum capacity argument.
|
||||
* @param minimumCapacity The desired minimum capacity of this collection (above what it currently holds).
|
||||
*/
|
||||
public abstract void ensureCapacity(int minimumCapacity);
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#add(java.lang.Object)
|
||||
*/
|
||||
public int add(Object value) {
|
||||
//Verify that the collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
|
||||
return internalAdd(value);
|
||||
}//add()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#addAll(java.lang.Object[])
|
||||
*/
|
||||
public boolean addAll(Object[] values) {
|
||||
return addAll(values, 0, values.length);
|
||||
}//addAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#addAll(java.lang.Object[], int, int)
|
||||
*/
|
||||
public boolean addAll(Object[] values, int offset, int length) {
|
||||
boolean result = true;
|
||||
|
||||
//Verify that the collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
//Resize the collection only once if it requires it at all.//
|
||||
ensureCapacity(length);
|
||||
|
||||
//Make sure that the collection has values.//
|
||||
if((values != null) && (values.length > 0) && (length + offset <= values.length) && (offset >= 0)) {
|
||||
Object next = null;
|
||||
|
||||
//Iterate over the items to be added and add them one at a time.//
|
||||
for(int index = offset; index < length; index++) {
|
||||
next = values[index];
|
||||
|
||||
if(internalAdd(next) == -1) {
|
||||
result = false;
|
||||
}//if//
|
||||
}//while//
|
||||
}//if//
|
||||
else {
|
||||
result = false;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//addAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#addAll(com.common.util.ICollection)
|
||||
*/
|
||||
public boolean addAll(ICollection values) {
|
||||
boolean result = true;
|
||||
|
||||
if(values instanceof IIndexedCollection) {
|
||||
result = addAll((IIndexedCollection) values, 0, values.getSize());
|
||||
}//if//
|
||||
else {
|
||||
//Verify that the collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
//Resize the collection only once if it requires it at all.//
|
||||
ensureCapacity(values.getSize());
|
||||
|
||||
//Make sure that the collection has values.//
|
||||
if((values != null) && (values.getSize() > 0)) {
|
||||
Object next = null;
|
||||
|
||||
//Iterate over the items to be added and add them one at a time.//
|
||||
for(IIterator iterator = values.iterator(); iterator.hasNext(); ) {
|
||||
next = iterator.next();
|
||||
|
||||
if(internalAdd(next) == -1) {
|
||||
result = false;
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
result = false;
|
||||
}//else//
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//addAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#addAll(com.common.util.IIndexedCollection, int, int)
|
||||
*/
|
||||
public boolean addAll(IIndexedCollection values, int offset, int length) {
|
||||
boolean result = true;
|
||||
|
||||
//Verify that the collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
//Resize the collection only once if it requires it at all.//
|
||||
ensureCapacity(length);
|
||||
|
||||
//Make sure that the collection has values.//
|
||||
if((values != null) && (length > 0)) {
|
||||
Object next = null;
|
||||
|
||||
//Iterate over the items to be added and add them one at a time.//
|
||||
for(int valuesIndex = offset, count = offset + length; valuesIndex < count; valuesIndex++) {
|
||||
next = values.get(valuesIndex);
|
||||
|
||||
if(internalAdd(next) == -1) {
|
||||
result = false;
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
result = false;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//addAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#addAll(com.common.util.IIterator)
|
||||
*/
|
||||
public boolean addAll(IIterator values) {
|
||||
boolean result = true;
|
||||
|
||||
//Verify that the collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
|
||||
//Make sure that the collection has values.//
|
||||
if(values != null) {
|
||||
Object next = null;
|
||||
|
||||
//Iterate over the items to be added and add them one at a time.//
|
||||
while(values.hasNext()) {
|
||||
next = values.next();
|
||||
|
||||
if(internalAdd(next) == -1) {
|
||||
result = false;
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
result = false;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//addAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#collect(com.common.event.ObjectHandler1, com.common.util.IList)
|
||||
*/
|
||||
public IList collect(ObjectHandler1 handler, IList results) {
|
||||
IIterator iterator = iterator();
|
||||
|
||||
if(results == null) {
|
||||
results = new LiteList(getSize());
|
||||
}//if//
|
||||
|
||||
//Iterate over the items in this collection passing them to the handler, and collect the resulting values.//
|
||||
while(iterator.hasNext()) {
|
||||
results.add(handler.evaluate(iterator.next()));
|
||||
}//while//
|
||||
|
||||
return results;
|
||||
}//collect()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#containsValue(java.lang.Object)
|
||||
*/
|
||||
public abstract boolean containsValue(Object value);
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#getSize()
|
||||
*/
|
||||
public abstract int getSize();
|
||||
/**
|
||||
* Will add a value to the collection.
|
||||
* @param value Object The value to add.
|
||||
* @return The index of the addition if the collection is indexed, 0 if the collection is not indexed, or -1 if the operation failed.
|
||||
*/
|
||||
protected abstract int internalAdd(Object value);
|
||||
/**
|
||||
* Will remove a value from the collection.
|
||||
* @param value Object The value to remove.
|
||||
* @return boolean Will return true if the operation was successful.
|
||||
*/
|
||||
protected abstract boolean internalRemove(Object value);
|
||||
/**
|
||||
* Will remove all of the values in the collection.
|
||||
* @return boolean Will return true if the operation was successful.
|
||||
*/
|
||||
protected abstract void internalRemoveAll();
|
||||
/**
|
||||
* Replaces one value with another in the collection.
|
||||
* @param oldValue Object The value to replace.
|
||||
* @param newValue Object The value to insert.
|
||||
* @return boolean Will return true if the operation was successful.
|
||||
*/
|
||||
protected abstract boolean internalReplace(Object oldValue, Object newValue);
|
||||
/**
|
||||
* Replaces the values currently in the collection with the given collection of values.
|
||||
* @param values The values to replace the ones currently in the collection.
|
||||
* @return Returns true if the operation was successful.
|
||||
*/
|
||||
protected abstract boolean internalReplaceAll(ICollection values);
|
||||
/**
|
||||
* Replaces the removed values in the current collection with those in the added values collection.
|
||||
* @param removedValues The values to be replaced.
|
||||
* @param addedValues The values to replace the removed values. Note that the collections need not be of the same size.
|
||||
* @return Whether the operation completed successfully. The operation may only partially complete if this is false.
|
||||
*/
|
||||
protected abstract boolean internalReplaceAll(ICollection removedValues, ICollection addedValues);
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#isChangeable()
|
||||
*/
|
||||
public boolean isChangeable() {
|
||||
return isChangeable;
|
||||
}//isChangeable()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#isChangeable(boolean)
|
||||
*/
|
||||
public void isChangeable(boolean isChangeable) {
|
||||
if(!isChangeable) {
|
||||
this.isChangeable = isChangeable;
|
||||
}//if//
|
||||
else if(this.isChangeable == isChangeable) {
|
||||
//Do nothing as nothing has changed.//
|
||||
}//else if//
|
||||
else {
|
||||
throw new RuntimeException("You may not change the collection to be changeable after it has been locked.");
|
||||
}//else//
|
||||
}//isChangeable()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#iterator()
|
||||
*/
|
||||
public abstract IIterator iterator();
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#perform(com.common.event.VoidHandler1)
|
||||
*/
|
||||
public void perform(VoidHandler1 handler) {
|
||||
IIterator iterator = iterator();
|
||||
|
||||
//Iterate over the items in this collection passing them to the handler to perform some function.//
|
||||
while(iterator.hasNext()) {
|
||||
handler.evaluate(iterator.next());
|
||||
}//while//
|
||||
}//perform()//
|
||||
/**
|
||||
* Will read the collection from the stream.
|
||||
* @param in java.io.ObjectInput The stream that the object data can be read from.
|
||||
*/
|
||||
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
||||
}//readExternal()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#reject(com.common.event.BooleanHandler1, com.common.util.IList)
|
||||
*/
|
||||
public IList reject(BooleanHandler1 handler, IList results) {
|
||||
IIterator iterator = iterator();
|
||||
|
||||
if(results == null) {
|
||||
results = new LiteList(10, 50);
|
||||
}//if//
|
||||
|
||||
//Iterate over the items in this collection passing them to the handler, and collect the resulting values.//
|
||||
while(iterator.hasNext()) {
|
||||
Object value = iterator.next();
|
||||
|
||||
if(!handler.evaluate(value).booleanValue()) {
|
||||
results.add(value);
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
return results;
|
||||
}//reject()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#remove(java.lang.Object)
|
||||
*/
|
||||
public boolean remove(Object value) {
|
||||
//Verify that the collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
|
||||
return internalRemove(value);
|
||||
}//remove()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#removeAll()
|
||||
*/
|
||||
public void removeAll() {
|
||||
//Verify that the collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
internalRemoveAll();
|
||||
}//removeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#removeAll(java.lang.Object[])
|
||||
*/
|
||||
public boolean removeAll(Object[] values) {
|
||||
return removeAll(values, 0, values.length);
|
||||
}//removeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#removeAll(java.lang.Object[], int, int)
|
||||
*/
|
||||
public boolean removeAll(Object[] values, int offset, int length) {
|
||||
boolean result = true;
|
||||
|
||||
//Verify that this collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
|
||||
//Make sure that there are values to remove.//
|
||||
if((values != null) && (values.length > 0) && (offset >= 0) && (offset + length <= values.length)) {
|
||||
Object next = null;
|
||||
|
||||
//Remove the values one at a time.//
|
||||
for(int index = offset; index < length; index++) {
|
||||
next = values[index];
|
||||
|
||||
if(!internalRemove(next)) {
|
||||
result = false;
|
||||
}//if//
|
||||
}//while//
|
||||
}//if//
|
||||
else {
|
||||
result = false;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//removeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#removeAll(com.common.util.ICollection)
|
||||
*/
|
||||
public boolean removeAll(ICollection values) {
|
||||
boolean result = true;
|
||||
|
||||
//Verify that this collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
|
||||
//Make sure that there are values to remove.//
|
||||
if((values != null) && (values.getSize() > 0)) {
|
||||
Object next = null;
|
||||
|
||||
//Remove the values one at a time.//
|
||||
for(IIterator iterator = values.iterator(); iterator.hasNext(); ) {
|
||||
next = iterator.next();
|
||||
|
||||
if(!internalRemove(next)) {
|
||||
result = false;
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
result = false;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//removeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#removeAll(com.common.util.ICollection)
|
||||
*/
|
||||
public boolean removeAll(IIterator values) {
|
||||
boolean result = true;
|
||||
|
||||
//Verify that this collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
|
||||
//Make sure that there are values to remove.//
|
||||
if(values != null) {
|
||||
Object next = null;
|
||||
|
||||
//Remove the values one at a time.//
|
||||
while(values.hasNext()) {
|
||||
next = values.next();
|
||||
|
||||
if(!internalRemove(next)) {
|
||||
result = false;
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
else {
|
||||
result = false;
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//removeAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#replace(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public boolean replace(Object oldValue, Object newValue) {
|
||||
//Verify that this collection can be modified.//
|
||||
verifyIsChangeable();
|
||||
|
||||
return internalReplace(oldValue, newValue);
|
||||
} //replace()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#replaceAll(com.common.util.ICollection)
|
||||
*/
|
||||
public boolean replaceAll(ICollection values) {
|
||||
return internalReplaceAll(values);
|
||||
}//replaceAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#replaceAll(com.common.util.ICollection, com.common.util.ICollection)
|
||||
*/
|
||||
public boolean replaceAll(ICollection removedValues, ICollection addedValues) {
|
||||
return internalReplaceAll(removedValues, addedValues);
|
||||
}//replaceAll()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.common.util.ICollection#select(com.common.event.BooleanHandler1, com.common.util.IList)
|
||||
*/
|
||||
public IList select(BooleanHandler1 handler, IList results) {
|
||||
IIterator iterator = iterator();
|
||||
|
||||
if(results == null) {
|
||||
results = new LiteList(10, 50);
|
||||
}//if//
|
||||
|
||||
//Iterate over the items in this collection passing them to the handler, and collect the resulting values.//
|
||||
while(iterator.hasNext()) {
|
||||
Object value = iterator.next();
|
||||
|
||||
if(handler.evaluate(value).booleanValue()) {
|
||||
results.add(value);
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
return results;
|
||||
}//select()//
|
||||
/**
|
||||
* Converts the list to an object array.
|
||||
* @return Object[] An array of the values in the collection.
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
Object[] result = new Object[getSize()];
|
||||
|
||||
toArray(result);
|
||||
|
||||
return result;
|
||||
}//toArray()//
|
||||
/* (Non-Javadoc)
|
||||
* @see ICollection.toArray(Object)
|
||||
*/
|
||||
public abstract int toArray(Object array);
|
||||
/**
|
||||
* Verifies that the collection may be modified.
|
||||
* @throws IllegalOperationException If the isImmutable flag is set.
|
||||
*/
|
||||
protected void verifyIsChangeable() {
|
||||
if(!isChangeable) {
|
||||
throw new IllegalOperationException("The collection is immutable which prevents the collection from being modified.");
|
||||
}//if//
|
||||
}//verifyIsChangeable()//
|
||||
/**
|
||||
* Writes the collection to the stream.
|
||||
* @param out java.io.ObjectOutput The stream that the object data can be written to.
|
||||
*/
|
||||
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
||||
}//writeExternal()//
|
||||
/**
|
||||
* Calculates the diffences between the old array and new array.
|
||||
* @param oldArray The old array.
|
||||
* @param newArray The new array.
|
||||
* @param comparator The optional comparator used to determine equality. If null then exact equality will be used (==).
|
||||
* @param added The optional set of items that are new in the new array (that don't exist in the old array).
|
||||
* @param removed The optional set of items that are old in the old array (that don't exist in the new array).
|
||||
* @param unchanged The optional set of items that have not changed and are in both arrays.
|
||||
*/
|
||||
public static void calculateDifferences(Object[] oldArray, Object[] newArray, IComparator comparator, ICollection added, ICollection removed, ICollection unchanged) {
|
||||
boolean[] newMatched = new boolean[newArray.length];
|
||||
|
||||
Arrays.fill(newMatched, false);
|
||||
|
||||
if(comparator == null) {
|
||||
comparator = Comparator.getIdentityComparator();
|
||||
}//if//
|
||||
|
||||
//For each old item, see if it exists in the new items and add to the appropriate collections. Mark matched items so we can easily see which items are new.//
|
||||
for(int oldIndex = 0; oldIndex < oldArray.length; oldIndex++) {
|
||||
boolean found = false;
|
||||
|
||||
//Search for a match in the new collection.//
|
||||
for(int newIndex = 0; (!found) && (newIndex < newArray.length); newIndex++) {
|
||||
if((!newMatched[newIndex]) && (Comparator.isEqual(comparator.compare(oldArray[oldIndex], newArray[newIndex])))) {
|
||||
found = true;
|
||||
newMatched[newIndex] = true;
|
||||
|
||||
if(unchanged != null) {
|
||||
unchanged.add(oldArray[oldIndex]);
|
||||
}//if//
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if((!found) && (removed != null)) {
|
||||
removed.add(oldArray[oldIndex]);
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
//If we need to collect added items then iterate over the new items and add those that are not marked as matched.//
|
||||
if(added != null) {
|
||||
for(int newIndex = 0; newIndex < newArray.length; newIndex++) {
|
||||
if(!newMatched[newIndex]) {
|
||||
added.add(newArray[newIndex]);
|
||||
}//if//
|
||||
}//for//
|
||||
}//if//
|
||||
}//calculateDifferences()//
|
||||
}//LiteCollection//
|
||||
Reference in New Issue
Block a user