View Javadoc

1   package org.sourceforge.jemm;
2   
3   import org.sourceforge.jemm.client.DatabaseAdapter;
4   import org.sourceforge.jemm.client.JEMMObjectCreator;
5   import org.sourceforge.jemm.client.JEMMObjectCreatorImpl;
6   import org.sourceforge.jemm.client.LifecycleListenerImpl;
7   import org.sourceforge.jemm.client.ObjectDatabase;
8   import org.sourceforge.jemm.client.ObjectOperationsFacade;
9   import org.sourceforge.jemm.client.RegistrationCache;
10  import org.sourceforge.jemm.client.SynchronousLockDecorator;
11  import org.sourceforge.jemm.client.TrackingDatabase;
12  import org.sourceforge.jemm.client.events.EntitiesContext;
13  import org.sourceforge.jemm.client.events.LockTracer;
14  import org.sourceforge.jemm.client.events.LockTracerImpl;
15  import org.sourceforge.jemm.client.events.StackTracer;
16  import org.sourceforge.jemm.client.id.TrackedIDFactory;
17  import org.sourceforge.jemm.client.id.TrackedIDFactoryImpl;
18  import org.sourceforge.jemm.database.ClientId;
19  import org.sourceforge.jemm.database.Database;
20  import org.sourceforge.jemm.database.debug.DebugDatabase;
21  import org.sourceforge.jemm.lifecycle.ConstructorLifecycle;
22  import org.sourceforge.jemm.lifecycle.TypeConstructorLifecycle;
23  import org.sourceforge.jemm.util.JEMMObject;
24  
25  /**
26   * Internal base class for implementing stores.
27   * <P>
28   * <B> N.b. extending classes must call setup() once their constructor initialisation is finished. </B>
29   * 
30   * @author Rory Graves
31   */
32  public abstract class AbstractStore implements Store {
33  
34  	protected ObjectDatabase db;
35  	protected LifecycleListenerImpl listener;
36  	private final boolean debug;
37  
38  	public AbstractStore() {
39  		this(false);
40  	}
41  
42  	public AbstractStore(boolean debug) {
43  		this.debug = debug;
44  	}
45  	
46  	protected void setup() {	
47  		try {
48  			TrackedIDFactory idFactory = new TrackedIDFactoryImpl();
49  			
50  			Database baseDatabase = createUnderlyingDatabase();
51  			baseDatabase = new TrackingDatabase(baseDatabase,idFactory);
52  			RegistrationCache regCache;
53  			if(debug) {
54  				DebugDatabase dd = new DebugDatabase(baseDatabase);
55  				regCache = new RegistrationCache(dd);
56  			}else
57  				regCache = new RegistrationCache(baseDatabase);
58  			
59  			
60  			DatabaseAdapter adapter = new DatabaseAdapter(regCache);
61  			
62  			SynchronousLockDecorator lockDB = new SynchronousLockDecorator(new ClientId("CLIENT"),adapter);
63  			
64  			this.db = lockDB;
65  			
66  			ObjectOperationsFacade oof = new ObjectOperationsFacade(db);
67  			LockTracer lockTracer = new LockTracerImpl(oof);
68  			StackTracer stackTracer = new EntitiesContext(lockTracer,oof);
69  			
70  			this.listener = new LifecycleListenerImpl(db,stackTracer,lockTracer);
71  			
72  			JEMMObjectCreator creator = new JEMMObjectCreatorImpl(listener,db);
73  			
74  			listener.setObjectCreator(creator);
75  			adapter.setObjectCreator(creator);
76  		}catch(Exception e) {
77  			e.printStackTrace();
78  			System.exit(1);
79  		}		
80  	}
81  
82  	protected abstract Database createUnderlyingDatabase();
83  	
84  	protected abstract void shutdownUnderlyingDatabase();
85  	
86  
87  	public void initialise() {
88  		ConstructorLifecycle.addListener(listener);
89  		TypeConstructorLifecycle.addListener(listener);
90  	}
91  	
92  	public void shutdown() {
93  		ConstructorLifecycle.clearListeners();
94  		shutdownUnderlyingDatabase();
95  	}
96  	
97  	public Object getRoot(String rootName) {
98  		return db.getRoot(rootName);
99  	}
100 
101 	public void setRoot(String rootName, Object value) {
102 		if(!(value instanceof JEMMObject))
103 			throw new JEMMInternalException("value must be an enhanced class");
104 		
105 		db.setRoot(rootName, (JEMMObject)value);
106 	}
107 
108 	/**
109 	 * Set the root 'rootName' to the given value if it is not already set.
110 	 * @param rootName The name of the root.
111 	 * @param value The value to store (must be an entity)
112 	 * @return If the stored value was null, the value passed (the new stored value), otherwise
113 	 *         the current value stored. 
114 	 */	
115 	public Object setRootIfNull(String rootName, Object value) {
116 		if(!(value instanceof JEMMObject))
117 			throw new JEMMInternalException("value must be an enhanced class");
118 		
119 		return db.setRootIfNull(rootName, (JEMMObject)value);
120 	}
121 }