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 );
}
}
}