FileDocCategorySizeDatePackage
Memento.javaAPI DocExample4646Fri Aug 25 08:31:48 BST 2000com.imaginary.lwp

Memento

public class Memento extends Object implements Serializable
Captures the classic memento pattern for Java. The memento pattern decouples a business object from its state so that systems like the lightweight persistence engine can manage storage and retrieval of an object's state to and from a data store.
Last modified $Date$
version
$Revision$
author
George Reese

Fields Summary
public static final int
NOSAVE
The bitmask meaning an attribute should not be saved.
private HashMap
values
The values representing the state of the object behind this memento.
Constructors Summary
public Memento()
Constructs a new, empty memento.


              
      
        super();
    
public Memento(Object ob)
Constructs a memento representing the state of the specified object.

param
ob the object to be represented

        super();
        {
            Class cls = ob.getClass();
            
            while( !cls.equals(Object.class) ) {
                Field[] attrs = cls.getDeclaredFields();
                HashMap map = new HashMap();
                
                values.put(cls, map);
                for(int i=0; i<attrs.length; i++) {
                    attrs[i].setAccessible(true);
                    if( isSaved(attrs[i]) ) {
                        try {
                            map.put(attrs[i].getName(), attrs[i].get(ob));
                        }
                        catch( IllegalAccessException e ) {
                            throw new SecurityException(e.getMessage());
                        }
                    }
                }
                cls = cls.getSuperclass();
            }
        }
    
Methods Summary
public java.lang.Objectget(java.lang.Class cls, java.lang.String attr)
Provides the value for the attribute of the specified class.

param
cls the class in which the attribute is declared
param
attr the name of the attribute
return
the value of the attribute

        HashMap map;

        if( !values.containsKey(cls) ) {
            return null;
        }
        map = (HashMap)values.get(cls);
        return map.get(attr);
    
public static booleanisSaved(java.lang.reflect.Field f)
Determines whether or not a given field should be saved. A field should not be saved if it is final, static, or transient.

param
f the field to be tested
return
true if the field should be saved


                                               
         
        int mod = f.getModifiers();
        
        if( (mod & Memento.NOSAVE) == 0 ) {
            return true;
        }
        else {
            return false;
        }
    
public voidmap(java.lang.Object ob)
Maps the values currently in the memento to the object in question.

param
ob the object who should be assigned values from the memento
throws
java.lang.NoSuchFieldException the object in question does not have a field for one of the memento values

        Iterator keys = values.keySet().iterator();

        while( keys.hasNext() ) {
            Class cls = (Class)keys.next();
            HashMap vals = (HashMap)values.get(cls);
            Iterator attrs = vals.keySet().iterator();

            while( attrs.hasNext() ) {
                String attr = (String)attrs.next();
                Object val = vals.get(attr);
                Field f = cls.getDeclaredField(attr);

                f.setAccessible(true);
                try {
                    f.set(ob, val);
                }
                catch( IllegalAccessException e ) {
                    throw new SecurityException(e.getMessage());
                }
            }
        }
    
public voidput(java.lang.Class cls, java.lang.String attr, java.lang.Object val)
Places the specified value into the memento based on the field's declaring class and name.

param
cls the class in which the field is declared
param
attr the name of the attribute
param
val the value being stored

        HashMap map;
        
        if( values.containsKey(cls) ) {
            map = (HashMap)values.get(cls);
        }
        else {
            map = new HashMap();
            values.put(cls, map);
        }
        map.put(attr, val);