KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > webman > acl > ObjectFactoryBase


1 package de.webman.acl;
2
3 import java.util.Hashtable JavaDoc;
4 import java.util.Vector JavaDoc;
5 import com.teamkonzept.lib.DatabaseErrorCodes;
6 import com.teamkonzept.lib.ErrorCodes;
7 import com.teamkonzept.lib.PropertyManager;
8 import com.teamkonzept.lib.TKConfigurationException;
9 import com.teamkonzept.lib.TKException;
10 import com.teamkonzept.lib.TKVector;
11 import de.webman.acl.db.ObjectCollectionDBData;
12 import de.webman.acl.db.ObjectDBData;
13 import de.webman.acl.db.ObjectDBInterface;
14 import com.teamkonzept.webman.mainint.WebmanExceptionHandler;
15 import com.teamkonzept.webman.mainint.events.TKUserException;
16 import com.teamkonzept.webman.mainint.events.UserCodes;
17 import org.apache.log4j.Category;
18
19
20 /**
21  * Base class of factories for persistent objects. Implements handling of object
22  * identity, caching and the recycling of unused object IDs. There should be a
23  * singleton instance per persistent object class.
24  *
25  * @version 1.0
26  * @since 1.0
27  * @author © 2001 Webman AG
28  */

29 public abstract class ObjectFactoryBase
30     implements ObjectFactory
31 {
32
33     static Category cat = Category.getInstance(ObjectFactoryBase.class);
34
35
36     // $Header: /cvsroot/webman-cms/source/webman/de/webman/acl/ObjectFactoryBase.java,v 1.3.6.1 2002/05/30 10:23:54 uli Exp $
37

38     // Attributes
39

40     /**
41      * Specifies wether objects loaded from the database should be cached
42      * by the factory.
43      */

44     private boolean cacheLoadedObjects = false;
45
46     /**
47      * Specifies wether the loading of an objects associations should be
48      * deferred until the first access to the associations.
49      */

50     private boolean deferAssociationLoading = false;
51
52     /**
53      * Specifies wether the factory should load all objects at start up.
54      */

55     private boolean preLoadObjects = false;
56
57     /**
58      * Internal cache flag.
59      */

60     private boolean allObjectsCached = false;
61
62     /**
63      * Internal object identity cache.
64      */

65     private Hashtable JavaDoc cache = null;
66
67
68     // Constructors
69

70     /**
71      * Creates and configures a factory for persistent objects.
72      */

73     public ObjectFactoryBase ()
74     {
75         // NOP.
76
}
77
78
79     // Method signatures
80

81     /**
82      * Retrieves the current database interface.
83      *
84      * @return the current database interface.
85      */

86     public abstract ObjectDBInterface getDBInterface ();
87
88     /**
89      * Retrieves an object data wrapper.
90      *
91      * @param id the ID of the object.
92      * @return an object data wrapper.
93      */

94     public abstract ObjectDBData getDBData (Integer JavaDoc id);
95
96     /**
97      * Retrieves an object data wrapper.
98      *
99      * @param object the object.
100      * @return an object data wrapper.
101      */

102     public abstract ObjectDBData getDBData (WMObject object);
103
104     /**
105      * Builds an concrete object instance.
106      *
107      * @param data the initial object data.
108      * @return an concrete object instance.
109      */

110     public abstract WMObject buildObject (ObjectDBData data);
111
112
113     // Implementation of 'com.teamkonzept.lib.ConfigurationListener'.
114

115     /**
116      * Informs the factory about changes in its configuration.
117      *
118      * @exception com.teamkonzept.lib.TKException if an error occured during configuration.
119      */

120     public synchronized void configurationChanged ()
121         throws TKException
122     {
123         // Configuration value loading.
124
try
125         {
126             // Obtain property manager.
127
PropertyManager manager = PropertyManager.getPropertyManager(PROPERTY_GROUP_NAME);
128
129             // Get cache property.
130
this.cacheLoadedObjects = Boolean.valueOf(manager.getValue(PROPERTY_CACHE_LOADED_OBJECTS,
131                                                                        DEFAULT_CACHE_LOADED_OBJECTS)).booleanValue();
132
133             // Get deferral property.
134
this.deferAssociationLoading = Boolean.valueOf(manager.getValue(PROPERTY_DEFER_ASSOCIATION_LOADING,
135                                                                             DEFAULT_DEFER_ASSOCIATION_LOADING)).booleanValue();
136
137             // Get pre-loading property.
138
this.preLoadObjects = Boolean.valueOf(manager.getValue(PROPERTY_PRE_LOAD_OBJECTS,
139                                                                    DEFAULT_PRE_LOAD_OBJECTS)).booleanValue();
140         }
141         catch (TKConfigurationException tkce)
142         {
143             // Fall back to default.
144
this.cacheLoadedObjects = Boolean.valueOf(DEFAULT_CACHE_LOADED_OBJECTS).booleanValue();
145             this.deferAssociationLoading = Boolean.valueOf(DEFAULT_DEFER_ASSOCIATION_LOADING).booleanValue();
146             this.preLoadObjects = Boolean.valueOf(DEFAULT_PRE_LOAD_OBJECTS).booleanValue();
147         }
148
149         // Configuration value consolidation.
150
if (! this.cacheLoadedObjects ||
151             ! this.deferAssociationLoading)
152         {
153             // 1. It doesn't make sense to preload objects when the cache is inactive.
154
// 2. It leads to circularities when associations are loaded eagerly.
155
this.preLoadObjects = false;
156         }
157
158         // Configuration value evaluation.
159
if (this.cacheLoadedObjects && this.cache == null)
160         {
161             // Initialize cache.
162
this.cache = new Hashtable JavaDoc();
163         }
164
165         if (! this.cacheLoadedObjects && this.cache != null)
166         {
167             // Destroy cache.
168
this.cache = null;
169         }
170
171         if (this.preLoadObjects)
172         {
173             // Load objects now.
174
getObjects();
175         }
176     }
177
178
179     // Implementation of 'com.teamkonzept.webman.accesscontrol.ObjectFactory'.
180

181     /**
182      * Retrieves the specified object.
183      *
184      * @param id the specifiying ID of the object.
185      * @return the specified object.
186      * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
187      */

188     public WMObject getObject (Integer JavaDoc id)
189         throws TKException
190     {
191         WMObject object = null;
192
193         try
194         {
195             // Cache lookup.
196
object = this.cacheLoadedObjects
197                          ? (WMObject) cache.get(id)
198                          : null;
199
200             if (object == null)
201             {
202                 // Create appropriate data.
203
ObjectDBData data = getDBData(id);
204
205                 // Database lookup.
206
getDBInterface().selectPrimary(data);
207
208                 if (! data.isEmpty())
209                 {
210                     // Object creation.
211
object = buildObject(data);
212
213                     if (! this.deferAssociationLoading)
214                     {
215                         // Association loading.
216
object.loadAssociations();
217                     }
218
219                     if (this.cacheLoadedObjects)
220                     {
221                         // Object caching.
222
cache.put(object.getID(), object);
223                     }
224                 }
225             }
226         }
227         catch (Exception JavaDoc x)
228         {
229             throw WebmanExceptionHandler.getException(x);
230         }
231
232         return object;
233     }
234
235     /**
236      * Retrieves all known objects.
237      *
238      * @return all known objects.
239      * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
240      */

241     public TKVector getObjects ()
242         throws TKException
243     {
244         TKVector objects = null;
245
246         try
247         {
248             if (this.allObjectsCached)
249             {
250                 // Load objects from cache.
251
objects = new TKVector(this.cache.size());
252                 objects.fill(this.cache.elements());
253             }
254             else
255             {
256                 objects = getObjects(getObjectIDs());
257
258                 if (this.cacheLoadedObjects)
259                 {
260                     // Set flag.
261
this.allObjectsCached = true;
262                 }
263             }
264         }
265         catch (Exception JavaDoc x)
266         {
267             throw WebmanExceptionHandler.getException(x);
268         }
269
270         return objects;
271     }
272
273     /**
274      * Retrieves the specified objects.
275      *
276      * @param ids the specifiying IDs of the objects.
277      * @return the specified objects.
278      * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
279      */

280     public TKVector getObjects (TKVector ids)
281         throws TKException
282     {
283         TKVector objects = null;
284
285         try
286         {
287             if (ids != null)
288             {
289                 int index = 0;
290                 int size = ids.size();
291
292                 objects = new TKVector(size);
293
294                 while (index < size)
295                 {
296                     // Object lookup.
297
objects.addElement(getObject((Integer JavaDoc) ids.elementAt(index++)));
298                 }
299             }
300             else
301             {
302                 objects = new TKVector(0);
303             }
304         }
305         catch (Exception JavaDoc x)
306         {
307             throw WebmanExceptionHandler.getException(x);
308         }
309
310         return objects;
311     }
312
313     /**
314      * Retrieves all known object IDs.
315      *
316      * @return all known object IDs.
317      * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
318      */

319     public TKVector getObjectIDs ()
320         throws TKException
321     {
322         TKVector proxies = null;
323
324         try
325         {
326             // Create appropriate data.
327
ObjectDBData data = getDBData((Integer JavaDoc) null);
328             data.setQuery(getDBInterface().getSelectAllQuery());
329             data.setPrototype(new ObjectCollectionDBData(null,
330                                                            null,
331                                                            getDBInterface().getPrimaryKeyName(),
332                                                            null));
333
334             // Database lookup.
335
getDBInterface().selectDependent(data);
336             proxies = data.getCollection();
337         }
338         catch (Exception JavaDoc x)
339         {
340             throw WebmanExceptionHandler.getException(x);
341         }
342
343         return proxies;
344     }
345
346     /**
347      * Retrieves the specified object IDs.
348      *
349      * @param data the specifiying data of the objects.
350      * @return the specified object IDs.
351      * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
352      */

353     public TKVector getObjectIDs (ObjectDBData data)
354         throws TKException
355     {
356         TKVector proxies = null;
357
358         try
359         {
360             // Database lookup.
361
getDBInterface().selectDependent(data);
362             proxies = data.getCollection();
363         }
364         catch (Exception JavaDoc x)
365         {
366             throw WebmanExceptionHandler.getException(x);
367         }
368
369         return proxies;
370     }
371
372     /**
373      * Retrieves the associated object IDs.
374      *
375      * @param object the object.
376      * @return the associated object IDs.
377      * @exception com.teamkonzept.lib.TKException if an error occured during object retrieval.
378      */

379     public TKVector getObjectAssociations (WMObject object)
380         throws TKException
381     {
382         TKVector proxies = null;
383
384         try
385         {
386             // Create appropriate data.
387
ObjectDBData data = getDBData(object.getID());
388
389             if (! data.isIgnoreTable(null))
390             {
391                 data.setQuery(getDBInterface().getSelectDependentQuery());
392                 data.setPrototype(new ObjectCollectionDBData(getDBInterface().getPrimaryKeyName(),
393                                                                object.getID(),
394                                                                getDBInterface().getDependentKeyName(),
395                                                                null));
396
397                 // Database lookup.
398
getDBInterface().selectDependent(data);
399             }
400
401             proxies = data.getCollection();
402         }
403         catch (Exception JavaDoc x)
404         {
405             throw WebmanExceptionHandler.getException(x);
406         }
407
408         return proxies;
409     }
410
411     /**
412      * Creates the specified object.
413      *
414      * @param data the specifying object data.
415      * @return the specified object.
416      * @exception com.teamkonzept.lib.TKException if an error occured during object creation.
417      */

418     public WMObject createObject (ObjectDBData data)
419         throws TKException
420     {
421         WMObject object = null;
422
423         try
424         {
425             // Database insert.
426
getDBInterface().insert(data);
427
428             // Object creation.
429
object = buildObject(data);
430
431             if (this.cacheLoadedObjects)
432             {
433                 // Object caching.
434
cache.put(object.getID(), object);
435             }
436         }
437         catch (Exception JavaDoc x)
438         {
439             if (x instanceof TKException &&
440                 ((TKException) x).getErrorCode() == DatabaseErrorCodes.FK_CONSTRAINT_VIOLATION)
441             {
442                 throw new TKUserException("An object with the given attributes already exists.",
443                                           UserCodes.DUPLICATE_OBJECT,
444                                           ErrorCodes.USER_SEVERITY,
445                                           true,
446                                           null);
447             }
448
449             throw WebmanExceptionHandler.getException(x);
450         }
451
452         return object;
453     }
454
455     /**
456      * Modifies the given object.
457      *
458      * @param object the object.
459      * @exception com.teamkonzept.lib.TKException if an error occured during object modification.
460      */

461     public void modifyObject (WMObject object)
462         throws TKException
463     {
464         Integer JavaDoc id = null;
465
466         try
467         {
468             id = object.getID();
469
470             if (object.isModifiedAttributes() ||
471                 object.isModifiedAssociations())
472             {
473                 // Create data container and set primary data.
474
ObjectDBData data = getDBData(object);
475
476                 if (object.isModifiedAssociations())
477                 {
478                     // Set dependent data.
479
data.setQuery(getDBInterface().getInsertDependentQuery());
480                     data.setPrototype(new ObjectCollectionDBData(getDBInterface().getPrimaryKeyName(),
481                                                                    object.getID(),
482                                                                    getDBInterface().getDependentKeyName(),
483                                                                    null));
484                     data.setCollection(object.getAssociations());
485
486                     if (object.isModifiedAttributes())
487                     {
488                         // Full database update.
489
getDBInterface().updateFull(data);
490                     }
491                     else
492                     {
493                         // Dependent database update.
494
getDBInterface().updateDependent(data);
495                     }
496                 }
497                 else
498                 {
499                     // Primary database update.
500
getDBInterface().updatePrimary(data);
501                 }
502
503                 // Remove update information.
504
object.updatedAttributes();
505                 object.updatedAssociations();
506             }
507         }
508         catch (NullPointerException JavaDoc npe)
509         {
510             // Ignored.
511
}
512         catch (Exception JavaDoc x)
513         {
514             throw WebmanExceptionHandler.getException(x);
515         }
516     }
517
518     /**
519      * Deletes the given object.
520      *
521      * @param object the object.
522      * @exception com.teamkonzept.lib.TKException if an error occured during object deletion.
523      */

524     public void deleteObject (WMObject object)
525         throws TKException
526     {
527         Integer JavaDoc id = null;
528
529         try
530         {
531             id = object.getID();
532
533             // Database delete.
534
getDBInterface().delete(getDBData(id));
535
536             if (this.cacheLoadedObjects)
537             {
538                 // Uncache object.
539
cache.remove(id);
540             }
541         }
542         catch (NullPointerException JavaDoc npe)
543         {
544             // Ignored.
545
}
546         catch (Exception JavaDoc x)
547         {
548             throw WebmanExceptionHandler.getException(x);
549         }
550     }
551
552 }
553
Popular Tags