package com.kryptnostic.rhizome.hazelcast.processors;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.function.BiFunction;
import com.kryptnostic.rhizome.hazelcast.objects.SetProxy;
public abstract class AbstractUpdater<K, V extends Collection<T>, T>
extends AbstractRhizomeEntryProcessor<K, V, Void> {
private static final long serialVersionUID = -5387091209847658668L;
protected final Iterable<T> objectsToUpdate;
protected final SetEntryProcessorOperation operation;
public enum SetEntryProcessorOperation {
ADD,
REMOVE,
APPLY;
}
protected AbstractUpdater( Iterable<T> objects, SetEntryProcessorOperation operation ) {
this.objectsToUpdate = objects;
this.operation = operation;
}
public static <K, V extends Collection<T>, T> AbstractUpdater<K, Collection<T>, T> addToSetUpdater(
Iterable<T> collection ) {
return new AddToSetEntryProcessor<K, T>( collection );
}
public static <K, V extends Collection<T>, T> AbstractUpdater<K, Collection<T>, T> removeFromSetUpdater(
Iterable<T> collection ) {
return new RemoveFromSetEntryProcessor<K, T>( collection );
}
protected BiFunction<V, T, Boolean> removeFunction() {
return ( objectCollection, object ) -> objectCollection.remove( object );
}
protected BiFunction<V, T, Boolean> addFunction() {
return ( objectCollection, object ) -> objectCollection.add( object );
}
@Override
public Void process( Entry<K, V> entry ) {
V currentObjects = entry.getValue();
if ( !( currentObjects instanceof SetProxy<?, ?> ) && currentObjects == null ) {
currentObjects = newEmptyCollection();
}
BiFunction<V, T, Boolean> addOrRemoveFunction;
switch ( operation ) {
case ADD:
addOrRemoveFunction = addFunction();
break;
case REMOVE:
addOrRemoveFunction = removeFunction();
break;
case APPLY:
addOrRemoveFunction = applyFunction();
break;
default:
addOrRemoveFunction = null;
System.err.println( "Impossible, no operation specified in AbstractUpdater" );
return null;
}
for ( T object : objectsToUpdate ) {
addOrRemoveFunction.apply( currentObjects, object );
}
// Don't trigger re-serialization if handled by SetProxy.
if ( !( currentObjects instanceof SetProxy<?, ?> ) ) {
entry.setValue( currentObjects );
}
return null;
}
public Iterable<T> getBackingCollection() {
return objectsToUpdate;
}
protected abstract V newEmptyCollection();
protected BiFunction<V, T, Boolean> applyFunction() {
throw new UnsupportedOperationException(
"Override this method when you make an AbstractUpdater that uses the SetEntryProcessorOperation.APPLY operation" );
}
}