KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > map > EntityResolver


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.map;
21
22 import java.io.Serializable JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30
31 import org.apache.cayenne.CayenneRuntimeException;
32 import org.apache.cayenne.ObjectId;
33 import org.apache.cayenne.Persistent;
34 import org.apache.cayenne.query.Query;
35 import org.apache.cayenne.reflect.ClassDescriptor;
36 import org.apache.cayenne.reflect.ClassDescriptorMap;
37 import org.apache.cayenne.reflect.LifecycleCallbackRegistry;
38 import org.apache.cayenne.reflect.generic.DataObjectDescriptorFactory;
39 import org.apache.cayenne.reflect.pojo.EnhancedPojoDescriptorFactory;
40 import org.apache.cayenne.reflect.valueholder.ValueHolderDescriptorFactory;
41 import org.apache.cayenne.util.Util;
42 import org.apache.commons.collections.collection.CompositeCollection;
43
44 /**
45  * Represents a virtual shared namespace for zero or more DataMaps. Unlike DataMap,
46  * EntityResolver is intended to work as a runtime container of mapping. DataMaps can be
47  * added or removed dynamically at runtime.
48  * <p>
49  * EntityResolver is thread-safe.
50  * </p>
51  *
52  * @since 1.1
53  * @author Andrus Adamchik
54  */

55 public class EntityResolver implements MappingNamespace, Serializable JavaDoc {
56
57     static final Object JavaDoc DUPLICATE_MARKER = new Object JavaDoc();
58
59     protected boolean indexedByClass;
60
61     protected transient Map JavaDoc queryCache;
62     protected transient Map JavaDoc embeddableCache;
63     protected transient Map JavaDoc entityListenerCache;
64     protected transient Map JavaDoc dbEntityCache;
65     protected transient Map JavaDoc objEntityCache;
66     protected transient Map JavaDoc procedureCache;
67     protected List JavaDoc maps;
68     protected transient Map JavaDoc entityInheritanceCache;
69     protected EntityResolver clientEntityResolver;
70
71     // must be transient, as resolver may get deserialized in another VM, and descriptor
72
// recompilation will be desired.
73
protected transient ClassDescriptorMap classDescriptorMap;
74
75     // callbacks are not serializable
76
protected transient LifecycleCallbackRegistry callbackRegistry;
77
78     /**
79      * Creates new EntityResolver.
80      */

81     public EntityResolver() {
82         this.indexedByClass = true;
83         this.maps = new ArrayList JavaDoc();
84         this.embeddableCache = new HashMap JavaDoc();
85         this.entityListenerCache = new HashMap JavaDoc();
86         this.queryCache = new HashMap JavaDoc();
87         this.dbEntityCache = new HashMap JavaDoc();
88         this.objEntityCache = new HashMap JavaDoc();
89         this.procedureCache = new HashMap JavaDoc();
90         this.entityInheritanceCache = new HashMap JavaDoc();
91     }
92
93     /**
94      * Creates new EntityResolver that indexes a collection of DataMaps.
95      */

96     public EntityResolver(Collection JavaDoc dataMaps) {
97         this();
98         this.maps.addAll(dataMaps); // Take a copy
99
this.constructCache();
100     }
101
102     /**
103      * Compiles internal callback registry.
104      */

105     synchronized void initCallbacks() {
106         if (callbackRegistry == null) {
107             LifecycleCallbackRegistry callbackRegistry = new LifecycleCallbackRegistry(
108                     this);
109
110             // load default callbacks
111
Iterator JavaDoc maps = this.maps.iterator();
112             while (maps.hasNext()) {
113                 DataMap map = (DataMap) maps.next();
114                 Iterator JavaDoc listeners = map.getDefaultEntityListeners().iterator();
115                 while (listeners.hasNext()) {
116                     EntityListener listener = (EntityListener) listeners.next();
117                     Object JavaDoc listenerInstance = createListener(listener);
118
119                     CallbackDescriptor[] callbacks = listener
120                             .getCallbackMap()
121                             .getCallbacks();
122                     for (int i = 0; i < callbacks.length; i++) {
123
124                         Iterator JavaDoc callbackMethods = callbacks[i]
125                                 .getCallbackMethods()
126                                 .iterator();
127                         while (callbackMethods.hasNext()) {
128                             String JavaDoc method = (String JavaDoc) callbackMethods.next();
129
130                             // note that callbacks[i].getCallbackType() == i
131
callbackRegistry.addDefaultListener(
132                                     i,
133                                     listenerInstance,
134                                     method);
135                         }
136                     }
137                 }
138             }
139
140             // load entity callbacks
141
Iterator JavaDoc entities = getObjEntities().iterator();
142             while (entities.hasNext()) {
143                 ObjEntity entity = (ObjEntity) entities.next();
144                 Class JavaDoc entityClass = entity.getJavaClass();
145
146                 // external listeners go first, entity's own callbacks go next
147
Iterator JavaDoc entityListeners = entity.getEntityListeners().iterator();
148                 while (entityListeners.hasNext()) {
149                     EntityListener listener = (EntityListener) entityListeners.next();
150                     Object JavaDoc listenerInstance = createListener(listener);
151
152                     CallbackDescriptor[] callbacks = listener
153                             .getCallbackMap()
154                             .getCallbacks();
155                     for (int i = 0; i < callbacks.length; i++) {
156
157                         Iterator JavaDoc callbackMethods = callbacks[i]
158                                 .getCallbackMethods()
159                                 .iterator();
160                         while (callbackMethods.hasNext()) {
161                             String JavaDoc method = (String JavaDoc) callbackMethods.next();
162
163                             // note that callbacks[i].getCallbackType() == i
164
callbackRegistry.addListener(
165                                     i,
166                                     entityClass,
167                                     listenerInstance,
168                                     method);
169                         }
170                     }
171                 }
172
173                 CallbackDescriptor[] callbacks = entity.getCallbackMap().getCallbacks();
174                 for (int i = 0; i < callbacks.length; i++) {
175                     Iterator JavaDoc callbackMethods = callbacks[i]
176                             .getCallbackMethods()
177                             .iterator();
178                     while (callbackMethods.hasNext()) {
179                         String JavaDoc method = (String JavaDoc) callbackMethods.next();
180
181                         // note that callbacks[i].getCallbackType() == i
182
callbackRegistry.addListener(i, entityClass, method);
183                     }
184                 }
185             }
186
187             this.callbackRegistry = callbackRegistry;
188         }
189     }
190
191     /**
192      * Creates a listener instance.
193      */

194     private Object JavaDoc createListener(EntityListener listener) {
195         Class JavaDoc listenerClass;
196
197         try {
198             listenerClass = Util.getJavaClass(listener.getClassName());
199         }
200         catch (ClassNotFoundException JavaDoc e) {
201             throw new CayenneRuntimeException("Invalid listener class: "
202                     + listener.getClassName(), e);
203         }
204
205         try {
206             return listenerClass.newInstance();
207         }
208         catch (Exception JavaDoc e) {
209             throw new CayenneRuntimeException("Listener class "
210                     + listener.getClassName()
211                     + " default constructor call failed", e);
212         }
213     }
214
215     /**
216      * Returns a {@link LifecycleCallbackRegistry} for handling callbacks. Registry is
217      * lazily initialized on first call.
218      *
219      * @since 3.0
220      */

221     public LifecycleCallbackRegistry getCallbackRegistry() {
222         if (callbackRegistry == null) {
223             initCallbacks();
224         }
225
226         return callbackRegistry;
227     }
228
229     /**
230      * Returns ClientEntityResolver with mapping information that only includes entities
231      * available on CWS Client Tier.
232      *
233      * @since 1.2
234      */

235     public EntityResolver getClientEntityResolver() {
236
237         if (clientEntityResolver == null) {
238
239             synchronized (this) {
240
241                 if (clientEntityResolver == null) {
242
243                     EntityResolver resolver = new ClientEntityResolver();
244
245                     // translate to client DataMaps
246
Iterator JavaDoc it = getDataMaps().iterator();
247                     while (it.hasNext()) {
248                         DataMap map = (DataMap) it.next();
249                         DataMap clientMap = map.getClientDataMap(this);
250
251                         if (clientMap != null) {
252                             resolver.addDataMap(clientMap);
253                         }
254                     }
255
256                     clientEntityResolver = resolver;
257                 }
258             }
259         }
260
261         return clientEntityResolver;
262     }
263
264     /**
265      * Returns all DbEntities.
266      */

267     public Collection JavaDoc getDbEntities() {
268         CompositeCollection c = new CompositeCollection();
269         Iterator JavaDoc it = getDataMaps().iterator();
270         while (it.hasNext()) {
271             DataMap map = (DataMap) it.next();
272             c.addComposited(map.getDbEntities());
273         }
274
275         return c;
276     }
277
278     public Collection JavaDoc getObjEntities() {
279         CompositeCollection c = new CompositeCollection();
280         Iterator JavaDoc it = getDataMaps().iterator();
281         while (it.hasNext()) {
282             DataMap map = (DataMap) it.next();
283             c.addComposited(map.getObjEntities());
284         }
285
286         return c;
287     }
288
289     public Collection JavaDoc getProcedures() {
290         CompositeCollection c = new CompositeCollection();
291         Iterator JavaDoc it = getDataMaps().iterator();
292         while (it.hasNext()) {
293             DataMap map = (DataMap) it.next();
294             c.addComposited(map.getProcedures());
295         }
296
297         return c;
298     }
299
300     public Collection JavaDoc getQueries() {
301         CompositeCollection c = new CompositeCollection();
302         Iterator JavaDoc it = getDataMaps().iterator();
303         while (it.hasNext()) {
304             DataMap map = (DataMap) it.next();
305             c.addComposited(map.getQueries());
306         }
307
308         return c;
309     }
310
311     public DbEntity getDbEntity(String JavaDoc name) {
312         return _lookupDbEntity(name);
313     }
314
315     public ObjEntity getObjEntity(String JavaDoc name) {
316         return _lookupObjEntity(name);
317     }
318
319     public Procedure getProcedure(String JavaDoc name) {
320         return lookupProcedure(name);
321     }
322
323     public Query getQuery(String JavaDoc name) {
324         return lookupQuery(name);
325     }
326
327     /**
328      * @since 3.0
329      */

330     public Embeddable getEmbeddable(String JavaDoc className) {
331         Embeddable result = (Embeddable) embeddableCache.get(className);
332
333         if (result == null) {
334             // reconstruct cache just in case some of the datamaps
335
// have changed and now contain the required information
336
constructCache();
337             result = (Embeddable) embeddableCache.get(className);
338         }
339
340         return result;
341     }
342
343     /**
344      * @since 3.0
345      */

346     public EntityListener getEntityListener(String JavaDoc className) {
347         EntityListener result = (EntityListener) entityListenerCache.get(className);
348
349         if (result == null) {
350             // reconstruct cache just in case some of the datamaps
351
// have changed and now contain the required information
352
constructCache();
353             result = (EntityListener) entityListenerCache.get(className);
354         }
355
356         return result;
357     }
358
359     /**
360      * Returns ClassDescriptor for the ObjEntity matching the name. Returns null if no
361      * matching entity exists.
362      *
363      * @since 1.2
364      */

365     public synchronized ClassDescriptor getClassDescriptor(String JavaDoc entityName) {
366         if (entityName == null) {
367             throw new IllegalArgumentException JavaDoc("Null entityName");
368         }
369
370         return getClassDescriptorMap().getDescriptor(entityName);
371     }
372
373     public synchronized void addDataMap(DataMap map) {
374         if (!maps.contains(map)) {
375             maps.add(map);
376             map.setNamespace(this);
377             clearCache();
378         }
379     }
380
381     /**
382      * Removes all entity mappings from the cache. Cache can be rebuilt either explicitly
383      * by calling <code>constructCache</code>, or on demand by calling any of the
384      * <code>lookup...</code> methods.
385      */

386     public synchronized void clearCache() {
387         queryCache.clear();
388         dbEntityCache.clear();
389         objEntityCache.clear();
390         procedureCache.clear();
391         entityInheritanceCache.clear();
392         entityListenerCache.clear();
393         clientEntityResolver = null;
394     }
395
396     /**
397      * Creates caches of DbEntities by ObjEntity, DataObject class, and ObjEntity name
398      * using internal list of maps.
399      */

400     protected synchronized void constructCache() {
401         clearCache();
402
403         // rebuild index
404

405         // index DbEntities separatly and before ObjEntities to avoid infinite loops when
406
// looking up DbEntities during ObjEntity index op
407
Iterator JavaDoc mapIterator0 = maps.iterator();
408         while (mapIterator0.hasNext()) {
409             DataMap map = (DataMap) mapIterator0.next();
410
411             Iterator JavaDoc dbEntities = map.getDbEntities().iterator();
412             while (dbEntities.hasNext()) {
413                 DbEntity de = (DbEntity) dbEntities.next();
414                 dbEntityCache.put(de.getName(), de);
415             }
416         }
417
418         Iterator JavaDoc mapIterator1 = maps.iterator();
419         while (mapIterator1.hasNext()) {
420             DataMap map = (DataMap) mapIterator1.next();
421
422             // index ObjEntities
423
Iterator JavaDoc objEntities = map.getObjEntities().iterator();
424             while (objEntities.hasNext()) {
425                 ObjEntity oe = (ObjEntity) objEntities.next();
426
427                 // index by name
428
objEntityCache.put(oe.getName(), oe);
429
430                 // index by class.. use class name as a key to avoid class loading here...
431
if (indexedByClass) {
432                     String JavaDoc className = oe.getJavaClassName();
433                     if (className == null) {
434                         continue;
435                     }
436
437                     String JavaDoc classKey = classKey(className);
438
439                     // allow duplicates, but put a special marker indicating that this
440
// entity can't be looked up by class
441
Object JavaDoc existing = objEntityCache.get(classKey);
442                     if (existing != null) {
443
444                         if (existing != DUPLICATE_MARKER) {
445                             objEntityCache.put(classKey, DUPLICATE_MARKER);
446                         }
447                     }
448                     else {
449                         objEntityCache.put(classKey, oe);
450                     }
451                 }
452             }
453
454             // index stored procedures
455
Iterator JavaDoc procedures = map.getProcedures().iterator();
456             while (procedures.hasNext()) {
457                 Procedure proc = (Procedure) procedures.next();
458                 procedureCache.put(proc.getName(), proc);
459             }
460
461             // index queries
462
Iterator JavaDoc queries = map.getQueries().iterator();
463             while (queries.hasNext()) {
464                 Query query = (Query) queries.next();
465                 String JavaDoc name = query.getName();
466                 Object JavaDoc existingQuery = queryCache.put(name, query);
467
468                 if (existingQuery != null && query != existingQuery) {
469                     throw new CayenneRuntimeException("More than one Query for name"
470                             + name);
471                 }
472             }
473
474             // index listeners
475
Iterator JavaDoc listeners = map.getEntityListeners().iterator();
476             while (listeners.hasNext()) {
477                 EntityListener listener = (EntityListener) listeners.next();
478                 entityListenerCache.put(listener.getClassName(), listener);
479             }
480         }
481
482         // restart the map iterator to index inheritance
483
Iterator JavaDoc mapIterator2 = maps.iterator();
484         while (mapIterator2.hasNext()) {
485             DataMap map = (DataMap) mapIterator2.next();
486
487             // index ObjEntity inheritance
488
Iterator JavaDoc objEntities = map.getObjEntities().iterator();
489             while (objEntities.hasNext()) {
490                 ObjEntity oe = (ObjEntity) objEntities.next();
491
492                 // build inheritance tree... include nodes that
493
// have no children to avoid uneeded cache rebuilding on lookup...
494
EntityInheritanceTree node = (EntityInheritanceTree) entityInheritanceCache
495                         .get(oe.getName());
496                 if (node == null) {
497                     node = new EntityInheritanceTree(oe);
498                     entityInheritanceCache.put(oe.getName(), node);
499                 }
500
501                 String JavaDoc superOEName = oe.getSuperEntityName();
502                 if (superOEName != null) {
503                     EntityInheritanceTree superNode = (EntityInheritanceTree) entityInheritanceCache
504                             .get(superOEName);
505
506                     if (superNode == null) {
507                         // do direct entity lookup to avoid recursive cache rebuild
508
ObjEntity superOE = (ObjEntity) objEntityCache.get(superOEName);
509                         if (superOE != null) {
510                             superNode = new EntityInheritanceTree(superOE);
511                             entityInheritanceCache.put(superOEName, superNode);
512                         }
513                         else {
514                             // bad mapping?
515
// TODO (Andrus, 10/18/2005) it would be nice to log something
516
// here, but since EntityResolver is used on the client, log4J
517
// is a no-go...
518
continue;
519                         }
520                     }
521
522                     superNode.addChildNode(node);
523                 }
524             }
525         }
526     }
527
528     /**
529      * Returns a DataMap matching the name.
530      */

531     public synchronized DataMap getDataMap(String JavaDoc mapName) {
532         if (mapName == null) {
533             return null;
534         }
535
536         Iterator JavaDoc it = maps.iterator();
537         while (it.hasNext()) {
538             DataMap map = (DataMap) it.next();
539             if (mapName.equals(map.getName())) {
540                 return map;
541             }
542         }
543
544         return null;
545     }
546
547     public synchronized void setDataMaps(Collection JavaDoc maps) {
548         this.maps.clear();
549         this.maps.addAll(maps);
550         clearCache();
551     }
552
553     /**
554      * Returns an unmodifiable collection of DataMaps.
555      */

556     public Collection JavaDoc getDataMaps() {
557         return Collections.unmodifiableList(maps);
558     }
559
560     /**
561      * Looks in the DataMap's that this object was created with for the DbEntity that
562      * services the specified class
563      *
564      * @return the required DbEntity, or null if none matches the specifier
565      * @deprecated since 3.0 - lookup DbEntity via ObjEntity instead.
566      */

567     public synchronized DbEntity lookupDbEntity(Class JavaDoc aClass) {
568         ObjEntity oe = lookupObjEntity(aClass);
569         return oe != null ? oe.getDbEntity() : null;
570     }
571
572     /**
573      * Looks in the DataMap's that this object was created with for the DbEntity that
574      * services the specified data Object
575      *
576      * @return the required DbEntity, or null if none matches the specifier
577      * @deprecated since 3.0 - lookup DbEntity via ObjEntity instead.
578      */

579     public synchronized DbEntity lookupDbEntity(Persistent dataObject) {
580         return lookupDbEntity(dataObject.getClass());
581     }
582
583     /**
584      * Returns EntityInheritanceTree representing inheritance hierarchy that starts with a
585      * given ObjEntity as root, and includes all its subentities. If ObjEntity has no
586      * known subentities, null is returned.
587      */

588     public EntityInheritanceTree lookupInheritanceTree(ObjEntity entity) {
589
590         EntityInheritanceTree tree = (EntityInheritanceTree) entityInheritanceCache
591                 .get(entity.getName());
592
593         if (tree == null) {
594             // since we keep inheritance trees for all entities, null means
595
// unknown entity...
596

597             // rebuild cache just in case some of the datamaps
598
// have changed and now contain the required information
599
constructCache();
600             tree = (EntityInheritanceTree) entityInheritanceCache.get(entity.getName());
601         }
602
603         // don't return "trivial" trees
604
return (tree == null || tree.getChildrenCount() == 0) ? null : tree;
605     }
606
607     /**
608      * Looks in the DataMap's that this object was created with for the ObjEntity that
609      * maps to the services the specified class
610      *
611      * @return the required ObjEntity or null if there is none that matches the specifier
612      */

613     public synchronized ObjEntity lookupObjEntity(Class JavaDoc aClass) {
614         if (!indexedByClass) {
615             throw new CayenneRuntimeException("Class index is disabled.");
616         }
617
618         return _lookupObjEntity(classKey(aClass.getName()));
619     }
620
621     /**
622      * Looks in the DataMap's that this object was created with for the ObjEntity that
623      * services the specified data Object
624      *
625      * @return the required ObjEntity, or null if none matches the specifier
626      */

627     public synchronized ObjEntity lookupObjEntity(Object JavaDoc object) {
628         if (object instanceof ObjEntity) {
629             return (ObjEntity) object;
630         }
631
632         if (object instanceof Persistent) {
633             ObjectId id = ((Persistent) object).getObjectId();
634             if (id != null) {
635                 return _lookupObjEntity(id.getEntityName());
636             }
637         }
638         else if (object instanceof Class JavaDoc) {
639             return lookupObjEntity((Class JavaDoc) object);
640         }
641
642         return lookupObjEntity(object.getClass());
643     }
644
645     /**
646      * Looks in the DataMap's that this object was created with for the ObjEntity that
647      * maps to the services the class with the given name
648      *
649      * @return the required ObjEntity or null if there is none that matches the specifier
650      * @deprecated since 3.0 - use getObjEntity() instead.
651      */

652     public synchronized ObjEntity lookupObjEntity(String JavaDoc entityName) {
653         return _lookupObjEntity(entityName);
654     }
655
656     public Procedure lookupProcedure(Query q) {
657         return q.getMetaData(this).getProcedure();
658     }
659
660     public Procedure lookupProcedure(String JavaDoc procedureName) {
661
662         Procedure result = (Procedure) procedureCache.get(procedureName);
663         if (result == null) {
664             // reconstruct cache just in case some of the datamaps
665
// have changed and now contain the required information
666
constructCache();
667             result = (Procedure) procedureCache.get(procedureName);
668         }
669
670         return result;
671     }
672
673     /**
674      * Returns a named query or null if no query exists for a given name.
675      */

676     public synchronized Query lookupQuery(String JavaDoc name) {
677         Query result = (Query) queryCache.get(name);
678
679         if (result == null) {
680             // reconstruct cache just in case some of the datamaps
681
// have changed and now contain the required information
682
constructCache();
683             result = (Query) queryCache.get(name);
684         }
685         return result;
686     }
687
688     public synchronized void removeDataMap(DataMap map) {
689         if (maps.remove(map)) {
690             clearCache();
691         }
692     }
693
694     public boolean isIndexedByClass() {
695         return indexedByClass;
696     }
697
698     public void setIndexedByClass(boolean b) {
699         indexedByClass = b;
700     }
701
702     /**
703      * Generates a map key for the object class.
704      *
705      * @since 3.0
706      */

707     protected String JavaDoc classKey(String JavaDoc className) {
708         // need to ensure that there is no conflict with entity names... I guess such
709
// prefix is enough to guarantee that:
710
return "^cl^" + className;
711     }
712
713     /**
714      * Internal usage only - provides the type-unsafe implementation which services the
715      * four typesafe public lookupDbEntity methods Looks in the DataMap's that this object
716      * was created with for the ObjEntity that maps to the specified object. Object may be
717      * a Entity name, ObjEntity, DataObject class (Class object for a class which
718      * implements the DataObject interface), or a DataObject instance itself
719      *
720      * @return the required DbEntity, or null if none matches the specifier
721      */

722     protected DbEntity _lookupDbEntity(Object JavaDoc object) {
723         if (object instanceof DbEntity) {
724             return (DbEntity) object;
725         }
726
727         Object JavaDoc result = dbEntityCache.get(object);
728         if (result == null) {
729             // reconstruct cache just in case some of the datamaps
730
// have changed and now contain the required information
731
constructCache();
732             result = dbEntityCache.get(object);
733         }
734
735         if (result == DUPLICATE_MARKER) {
736             throw new CayenneRuntimeException(
737                     "Can't perform lookup. There is more than one DbEntity mapped to "
738                             + object);
739         }
740
741         return (DbEntity) result;
742     }
743
744     /**
745      * Internal usage only - provides the type-unsafe implementation which services the
746      * three typesafe public lookupObjEntity methods Looks in the DataMap's that this
747      * object was created with for the ObjEntity that maps to the specified object. Object
748      * may be a Entity name, DataObject instance or DataObject class (Class object for a
749      * class which implements the DataObject interface)
750      *
751      * @return the required ObjEntity or null if there is none that matches the specifier
752      */

753     protected ObjEntity _lookupObjEntity(String JavaDoc key) {
754
755         Object JavaDoc result = objEntityCache.get(key);
756         if (result == null) {
757             // reconstruct cache just in case some of the datamaps
758
// have changed and now contain the required information
759
constructCache();
760             result = objEntityCache.get(key);
761         }
762
763         if (result == DUPLICATE_MARKER) {
764             throw new CayenneRuntimeException(
765                     "Can't perform lookup. There is more than one ObjEntity mapped to "
766                             + key);
767         }
768
769         return (ObjEntity) result;
770     }
771
772     /**
773      * Returns an object that compiles and stores {@link ClassDescriptor} instances for
774      * all entities.
775      *
776      * @since 3.0
777      */

778     public ClassDescriptorMap getClassDescriptorMap() {
779         if (classDescriptorMap == null) {
780             ClassDescriptorMap classDescriptorMap = new ClassDescriptorMap(this);
781
782             // add factories in reverse of the desired chain order
783
classDescriptorMap.addFactory(new ValueHolderDescriptorFactory(
784                     classDescriptorMap));
785             classDescriptorMap.addFactory(new EnhancedPojoDescriptorFactory(
786                     classDescriptorMap));
787             classDescriptorMap.addFactory(new DataObjectDescriptorFactory(
788                     classDescriptorMap));
789
790             this.classDescriptorMap = classDescriptorMap;
791         }
792
793         return classDescriptorMap;
794     }
795 }
796
Popular Tags