HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Bean-Managed Persistence Using a Proxy List"
Vol 5 Issue 6, p.132

	

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



 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.