Listing 1: ListInvocationHandler.java
package orders.demandlist;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.*;
public class ListInvocationHandler implements
InvocationHandler,PersistentOperations
{
private List backingList;
private DataStore dataStore;
private boolean dataLoaded = false;
private List deletedItems = new LinkedList();
private Set originalSet = new HashSet();
public ListInvocationHandler( List list,
DataStore dataStore )
{
this.backingList = list;
this.dataStore = dataStore;
}
public Object invoke(Object proxy,
Method method, Object[] args) throws Throwable
{
// persistent operations interface
if (method.getDeclaringClass().equals(
orders.demandlist.PersistentOperations.class
))
return method.invoke( this, args );
else
{
// list interface
if (!dataLoaded)
{
dataStore.load( this );
dataLoaded = true;
}
processDeletedItems( method, args );
Object obj = method.invoke( backingList,
args );
if (obj instanceof Iterator)
{
return DemandListIteratorFactory.
getDemandListIterator( (Iterator)obj,
this );
}
else if (obj instanceof List)
{
return Collections.unmodifiableList(
(List)obj);
}
else
return obj;
}
}
// PersistentOperations implementation
public void loadFromStore()
{
dataStore.load( this );
}
public void saveToStore()
{
if (dataLoaded)
{
dataStore.persist( this );
originalSet.addAll( backingList );
}
}
public List getDeletedObjects()
{
return Collections.unmodifiableList(
deletedItems );
}
public Set getOriginalSet()
{
return Collections.unmodifiableSet(
originalSet );
}
public List getCurrentList()
{
return Collections.unmodifiableList(
backingList );
}
public void addFromStore( Object obj )
{
backingList.add( obj );
originalSet.add( obj );
}
// package protected iterator support
void notifyObjectRemoved( Object obj )
{
deletedItems.add( obj );
}
// implementation
private void processDeletedItems(Method method,
Object[] args)
{
String methodName = method.getName();
if (methodName.equals("clear"))
{
deletedItems.addAll( backingList );
}
else if (methodName.equals("removeAll"))
{
deletedItems.addAll( (Collection)args[0] );
}
else if (methodName.equals("retainAll"))
{
List tempList = new LinkedList();
tempList.addAll( backingList );
tempList.removeAll( (Collection)args[0] );
deletedItems.addAll( tempList );
}
else if (methodName.equals("remove"))
{
Class[] paramTypes =
method.getParameterTypes();
if (paramTypes[0].equals( Integer.TYPE ))
{
Object obj = backingList.get(
((Integer)args[0]).intValue() );
deletedItems.add( obj );
}
else
{
deletedItems.add( args[0] );
}
}
}
}
Listing 2: DemandListIteratorFactory.java
import java.util.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
public class DemandListIteratorFactory
{
public static Iterator getDemandListIterator(
final Iterator iterator,
final ListInvocationHandler invocationHandler)
{
InvocationHandler handler =
new InvocationHandler()
{
private Object cacheLastRetrieval = null;
public Object invoke(Object proxy,
Method method, Object[] args)
throws Throwable
{
String methodName = method.getName();
if (methodName.equals("next") ||
methodName.equals("previous") )
{
Object obj = method.invoke(
iterator, args );
cacheLastRetrieval = obj;
return obj;
}
else if (methodName.equals("remove"))
{
Object obj = method.invoke(
iterator, args );
invocationHandler.notifyObjectRemoved(
cacheLastRetrieval );
return obj;
}
return method.invoke( iterator, args );
}
};
Class clazz = null;
if (iterator instanceof ListIterator)
clazz = java.util.ListIterator.class;
else
clazz = java.util.Iterator.class;
return (Iterator) Proxy.newProxyInstance(
java.util.List.class.getClassLoader(),
new Class[] { clazz }, handler);
}
}
Listing 3: PersistentOperations.java
package orders.demandlist;
import java.util.*;
public interface PersistentOperations
{
public void loadFromStore();
public void saveToStore();
public void addFromStore( Object obj );
public List getDeletedObjects();
public Set getOriginalSet();
public List getCurrentList();
}
Listing 4: DataStore.java
package orders.demandlist;
import java.util.*;
public interface DataStore
{
public void load(
PersistentOperations persistOp );
public void persist(
PersistentOperations persistOp );
}
Listing 5: DemandList Factory.java
package orders.demandlist;
import java.util.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class DemandListFactory
{
public static List getDemandList( final List
list, final DataStore dataStore )
{
InvocationHandler handler =
new ListInvocationHandler(list, dataStore);
return (List) Proxy.newProxyInstance(
PersistentOperations.class.getClassLoader(),
new Class[] { List.class,
PersistentOperations.class }, handler);
}
}
No comments:
Post a Comment