1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package com.gargoylesoftware.base.objectstore;
39
40 import com.gargoylesoftware.base.resource.ManagedResource;
41 import com.gargoylesoftware.base.resource.ResourceFactory;
42 import com.gargoylesoftware.base.resource.ResourceManager;
43 import com.gargoylesoftware.base.util.DetailedNullPointerException;
44 import java.util.Iterator;
45 import java.util.Map;
46
47 /***
48 * This is a wrapper for the data layer in an application. Any code that
49 * accesses a database or some other form of data should be in a subclass of
50 * ObjectStore
51 *
52 * @version $Revision: 1.5 $
53 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
54 */
55 public abstract class ObjectStore {
56
57 private ResourceManager resourceManager_ = null;
58
59
60 /***
61 * Create an instance
62 */
63 protected ObjectStore() {
64 }
65
66
67 /***
68 * <p>Set the resource map. This defines what class is used when a specific
69 * resource factory is requested.</p>
70 *
71 * <p>It is recommended to use {@link #setResourceManager(ResourceManager)} instead</p>
72 * @param inputMap A map containing string/class pairs.
73 */
74 public final void setResourceFactoryMap( final Map inputMap ) {
75 assertNotNull("inputMap", inputMap);
76
77 Map.Entry entry;
78 final ResourceManager newResourceManager = new ResourceManager( getClass().getName() );
79
80 final Iterator iterator = inputMap.entrySet().iterator();
81 while( iterator.hasNext() ) {
82 entry = ( Map.Entry )iterator.next();
83 newResourceManager.addFactory( ( String )entry.getKey(), ( ResourceFactory )entry.getValue() );
84 }
85
86 setResourceManager( newResourceManager );
87 }
88
89
90 /***
91 * Set the resource manager
92 *
93 * @param resourceManager The new resource manager
94 */
95 public final void setResourceManager( final ResourceManager resourceManager ) {
96 if( resourceManager_ != null ) {
97 resourceManager_.releaseAllResources();
98 }
99 resourceManager_ = resourceManager;
100 }
101
102
103 /***
104 * Gets the resource manager
105 *
106 * @return The resource manager or null if a resource manager has not been
107 * set.
108 */
109 public final ResourceManager getResourceManager() {
110 return resourceManager_;
111 }
112
113
114 /***
115 * Perform the actions specified by the key and return a value. The
116 * subclasses will perform the actual work in overridden versions of
117 * executeImpl()
118 *
119 * @param command The object that tells the object store what to do
120 * @return The results of the actions or null if there are no results
121 * @exception ObjectStoreCommandNotSupportedException If the command
122 * is not supported by this store
123 * @exception ObjectStoreException If an error occurs during processing
124 * of this command.
125 * @see #executeImpl(ObjectStoreCommand)
126 */
127 public final synchronized Object execute(
128 final ObjectStoreCommand command )
129 throws
130 ObjectStoreCommandNotSupportedException,
131 ObjectStoreException {
132
133 Object result;
134 try {
135 result = executeImpl( command );
136 }
137 catch( final Exception e ) {
138 result = handleException( e );
139 }
140 catch( final Error e ) {
141 result = handleError( e );
142 }
143 catch( final Throwable practicallyImpossibleButRequiredByTheCompiler ) {
144 practicallyImpossibleButRequiredByTheCompiler.printStackTrace();
145 result = null;
146 }
147 finally {
148 if( resourceManager_ != null ) {
149 resourceManager_.releaseAllResources();
150 }
151 }
152
153 return result;
154 }
155
156
157 /***
158 * Handle an exception that occured during the processing of executeImpl().
159 * Usually these exceptions will be rethrown after logging them to some
160 * error log<p>
161 *
162 * The default behaviour is to rethrow any ObjectStoreExceptions or
163 * ObjectStoreCommandNotSupportedExceptions. All other exceptions are
164 * wrapped in a new ObjectStoreException and then that wrapper is thown
165 *
166 * @param exception the exception that had been thrown
167 * @return The object to return from execute in those cases where an
168 * exception is not thrown out of this method
169 * @exception ObjectStoreException The exception to be thrown back out of
170 * execute()
171 * @exception ObjectStoreCommandNotSupportedException the exception to be
172 * thrown back out of execute()
173 */
174 protected Object handleException( final Exception exception )
175 throws
176 ObjectStoreException,
177 ObjectStoreCommandNotSupportedException {
178
179 if( exception instanceof ObjectStoreException ) {
180 throw ( ObjectStoreException )exception;
181 }
182 if( exception instanceof ObjectStoreCommandNotSupportedException ) {
183 throw ( ObjectStoreCommandNotSupportedException )exception;
184 }
185
186 throw new ObjectStoreException( exception );
187 }
188
189
190 /***
191 * Handle an exception that occured during the processing of executeImpl().
192 * Usually these exceptions will be rethrown after logging them to some
193 * error log<p>
194 *
195 * The default behaviour is to rethrow the error
196 *
197 * @param error The error that had been thrown
198 * @return The object to return from execute in those cases where an
199 * exception is not thrown out of this method
200 */
201 protected Object handleError( final Error error ) {
202 throw error;
203 }
204
205
206 /***
207 * Return a resource from the specified factory
208 *
209 * @param name The name of the factory
210 * @return The specified resource
211 * @see #setResourceFactoryMap(Map)
212 */
213 protected final Object getResource( final String name ) {
214 return getResourceManagerOrDie().getResource( name );
215 }
216
217
218 /***
219 * Override this to provide the actual processing of the object store.
220 *
221 * @param command The object that tells the object store what to do
222 * @return The results of the actions or null if there are no results
223 * @exception ObjectStoreCommandNotSupportedException If the specified
224 * command is not understood by the object store
225 * @exception Throwable If an error occurs
226 * @see #execute(ObjectStoreCommand)
227 */
228 protected abstract Object executeImpl(
229 final ObjectStoreCommand command )
230 throws
231 Throwable,
232 ObjectStoreCommandNotSupportedException;
233
234
235 /***
236 * Release the specified resource
237 *
238 * @param object The resource to release
239 */
240 protected final void releaseResource( final ManagedResource object ) {
241 getResourceManagerOrDie().releaseResource( object );
242 }
243
244
245 /***
246 * Return the resource manager. If a resource manager has not been
247 * specified then throw an exception.
248 *
249 * @return The resource manager
250 */
251 private ResourceManager getResourceManagerOrDie() {
252 if( resourceManager_ == null ) {
253 throw new IllegalStateException( "No ResourceManager has been specified" );
254 }
255 return resourceManager_;
256 }
257
258
259 /***
260 * Throw an exception if the specified object is null
261 * @param fieldName The name of the paremeter we are checking
262 * @param object The value of the parameter we are checking
263 */
264 protected final void assertNotNull( final String fieldName, final Object object ) {
265 if( object == null ) {
266 throw new DetailedNullPointerException(fieldName);
267 }
268 }
269 }
270