package org.neo4j.helpers.collection; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; /** * Wraps a {@link Collection}, making it look (and function) like a collection * holding another type of items. The wrapper delegates to its underlying * collection instead of keeping track of the items itself. * * @param <T> the type of items * @param <U> the type of items of the underlying/wrapped collection */ public abstract class CollectionWrapper<T, U> implements Collection<T> { private Collection<U> collection; public CollectionWrapper( Collection<U> underlyingCollection ) { this.collection = underlyingCollection; } protected abstract U objectToUnderlyingObject( T object ); protected abstract T underlyingObjectToObject( U object ); public boolean add( T o ) { return collection.add( objectToUnderlyingObject( o ) ); } public void clear() { collection.clear(); } public boolean contains( Object o ) { return collection.contains( objectToUnderlyingObject( ( T ) o ) ); } public boolean isEmpty() { return collection.isEmpty(); } public Iterator<T> iterator() { return new WrappingIterator( collection.iterator() ); } public boolean remove( Object o ) { return collection.remove( objectToUnderlyingObject( ( T ) o ) ); } public int size() { return collection.size(); } protected Collection<U> convertCollection( Collection c ) { Collection<U> converted = new HashSet<U>(); for ( Object item : c ) { converted.add( objectToUnderlyingObject( ( T ) item ) ); } return converted; } public boolean retainAll( Collection c ) { return collection.retainAll( convertCollection( c ) ); } public boolean addAll( Collection c ) { return collection.addAll( convertCollection( c ) ); } public boolean removeAll( Collection c ) { return collection.removeAll( convertCollection( c ) ); } public boolean containsAll( Collection c ) { return collection.containsAll( convertCollection( c ) ); } public Object[] toArray() { Object[] array = collection.toArray(); Object[] result = new Object[ array.length ]; for ( int i = 0; i < array.length; i++ ) { result[ i ] = underlyingObjectToObject( ( U ) array[ i ] ); } return result; } public <R> R[] toArray( R[] a ) { Object[] array = collection.toArray(); ArrayList<R> result = new ArrayList<R>(); for ( int i = 0; i < array.length; i++ ) { result.add( ( R ) underlyingObjectToObject( ( U ) array[ i ] ) ); } return result.toArray( a ); } private class WrappingIterator extends IteratorWrapper<T, U> { WrappingIterator( Iterator<U> iterator ) { super( iterator ); } @Override protected T underlyingObjectToObject( U object ) { return CollectionWrapper.this.underlyingObjectToObject( object ); } } }