package org.neo4j.util; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.neo4j.graphdb.PropertyContainer; import org.neo4j.helpers.collection.CollectionWrapper; /** * This class uses the fact that node property values can be arrays. * It looks at one property on a node as if it was a collection of values. * * @param <T> the type of values. */ public class PropertyArraySet<T> extends AbstractSet<T> implements List<T> { private final PropertyContainer container; private final String key; public PropertyArraySet( PropertyContainer container, String key ) { this.container = container; this.key = key; } protected PropertyContainer container() { return this.container; } protected String key() { return this.key; } public boolean add( T o ) { return GraphDatabaseUtil.addValueToArray( container(), key(), o ); } public void clear() { container().removeProperty( key() ); } private List<Object> values() { return GraphDatabaseUtil.getPropertyValues( container(), key() ); } private void setValues( Collection<?> collection ) { container().setProperty( key(), GraphDatabaseUtil.asPropertyValue( collection ) ); } public boolean contains( Object o ) { return values().contains( o ); } public boolean isEmpty() { return values().isEmpty(); } public Iterator<T> iterator() { return new CollectionWrapper<T, Object>( GraphDatabaseUtil.getPropertyValues( container(), key() ) ) { @Override protected Object objectToUnderlyingObject( T object ) { return object; } @Override protected T underlyingObjectToObject( Object object ) { return ( T ) object; } }.iterator(); } public boolean remove( Object o ) { return GraphDatabaseUtil.removeValueFromArray( container(), key(), o ); } public boolean retainAll( Collection<?> c ) { Collection<Object> values = values(); boolean altered = values.retainAll( c ); if ( altered ) { if ( values.isEmpty() ) { container().removeProperty( key() ); } else { container().setProperty( key(), GraphDatabaseUtil.asPropertyValue( values ) ); } } return altered; } public int size() { return values().size(); } public Object[] toArray() { return values().toArray(); } public <R> R[] toArray( R[] a ) { return values().toArray( a ); } public T set( int index, T value ) { List<Object> values = values(); T oldValue = ( T ) values.set( index, value ); setValues( values ); return oldValue; } public T remove( int index ) { List<Object> values = values(); T oldValue = ( T ) values.remove( index ); setValues( values ); return oldValue; } public int lastIndexOf( Object value ) { return values().lastIndexOf( value ); } public int indexOf( Object value ) { return values().indexOf( value ); } public boolean addAll( int index, Collection collection ) { List<Object> values = values(); boolean result = values.addAll( collection ); if ( result ) { setValues( values ); } return result; } public void add( int index, T item ) { List<Object> values = values(); values.add( index, item ); setValues( values ); } public ListIterator<T> listIterator() { throw new UnsupportedOperationException(); } public ListIterator<T> listIterator( int index ) { throw new UnsupportedOperationException(); } public List<T> subList( int start, int end ) { throw new UnsupportedOperationException(); } public T get( int index ) { return ( T ) values().get( index ); } }