1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jdo.impl.model.jdo.caching;
18
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Map;
22 import java.util.Set;
23
24 import org.apache.jdo.model.java.JavaModel;
25 import org.apache.jdo.model.jdo.JDOClass;
26 import org.apache.jdo.impl.model.jdo.JDOModelImplDynamic;
27 import org.apache.jdo.model.java.JavaType;
28
29 import org.apache.jdo.util.StringHelper;
30
31 /***
32 * A JDOModel instance bundles a number of JDOClass instances used by an
33 * application. It provides factory methods to create and retrieve JDOClass
34 * instances. A fully qualified class name must be unique within a JDOModel
35 * instance. The model supports multiple classes having the same fully qualified
36 * name by different JDOModel instances.
37 * <p>
38 * The caching JDOModel implementation caches any caclulated value to
39 * avoid re-calculating it if it is requested again. It is intended to
40 * be used in an environment where JDO metadata does NOT change
41 * (e.g. at runtime).
42 *
43 * @author Michael Bouschen
44 * @since 1.1
45 * @version 2.0
46 */
47 public class JDOModelImplCaching extends JDOModelImplDynamic {
48
49 /***
50 * This is a mapping from short names to JDOClass instances. Key is the
51 * JDOClass short name, value is the corresponding JDOClass instance.
52 */
53 private Map jdoClassesForShortNames = new HashMap();
54
55 /***
56 * This is a mapping from ObjectId classes to its JDOClass instances.
57 * Key is the type representation of the ObjectId class, value is the
58 * corresponding JDOClass instance. Note, in the case of inheritance
59 * the top most persistence-capable class is stored.
60 */
61 private Map jdoClassesForObjectIdClasses = new HashMap();
62
63 /***
64 * Set of fully qualified names of classes known to be
65 * non persistence-capable.
66 */
67 private Set nonPCClasses = new HashSet();
68
69 /***
70 * Constructor.
71 * JDOModel instances are created using the JDOModelFactory only.
72 */
73 protected JDOModelImplCaching(JavaModel javaModel,
74 boolean loadXMLMetadataDefault) {
75 super(javaModel, loadXMLMetadataDefault);
76 }
77
78 /***
79 * The method returns the JDOClass instance for the specified short name
80 * (see {@link JDOClass#getShortName()}) or <code>null</code> if it cannot
81 * find a JDOClass instance with the specified short name.
82 * <p>
83 * The method searches the list of JDOClasses currently managed by this
84 * JDOModel instance. It does not attempt to load any metadata if it
85 * cannot find a JDOClass instance with the specified short name. The
86 * metadata for a JDOClass returned by this method must have been loaded
87 * before by any of the methods
88 * {@link #createJDOClass(String className)},
89 * {@link #createJDOClass(String className, boolean loadXMLMetadataDefault)},
90 * {@link #getJDOClass(String className)}, or
91 * {@link #getJDOClass(String className, boolean loadXMLMetadataDefault)}.
92 * @param shortName the short name of the JDOClass instance to be returned
93 * @return a JDOClass instance for the specified short name
94 * or <code>null</code> if not present
95 */
96 public synchronized JDOClass getJDOClassForShortName(String shortName) {
97 if (StringHelper.isEmpty(shortName))
98 return null;
99
100
101 JDOClass jdoClass =
102 (JDOClass)jdoClassesForShortNames.get(shortName);
103 if (jdoClass == null) {
104
105 jdoClass = super.getJDOClassForShortName(shortName);
106 if (jdoClass != null) {
107
108 jdoClassesForShortNames.put(shortName, jdoClass);
109 }
110 }
111
112 return jdoClass;
113 }
114
115 /***
116 * This method returns the JDOClass instance that defines the specified type
117 * as its objectId class. In the case of an inheritance hierarchy it returns
118 * the top most persistence-capable class of the hierarchy (see
119 * {@link JDOClass#getPersistenceCapableSuperclass}).
120 * @param objectIdClass the type representation of the ObjectId class
121 * @return the JDOClass defining the specified class as ObjectId class
122 */
123 public JDOClass getJDOClassForObjectIdClass(JavaType objectIdClass)
124 {
125
126
127 if (objectIdClass == null)
128 return null;
129
130 synchronized (jdoClassesForObjectIdClasses) {
131
132 JDOClass jdoClass =
133 (JDOClass)jdoClassesForObjectIdClasses.get(objectIdClass);
134 if (jdoClass == null) {
135
136 jdoClass = super.getJDOClassForObjectIdClass(objectIdClass);
137 if (jdoClass != null) {
138
139 jdoClassesForObjectIdClasses.put(objectIdClass, jdoClass);
140 }
141 }
142
143 return jdoClass;
144 }
145 }
146
147 /*** Returns a new instance of the JDOClass implementation class. */
148 protected JDOClass newJDOClassInstance(String name) {
149 return new JDOClassImplCaching(name);
150 }
151
152 /***
153 * Checks whether the type with the specified name does NOT denote a
154 * persistence-capable class.
155 * @param typeName name of the type to be checked
156 * @return <code>true</code> if types is a name of a primitive type;
157 * <code>false</code> otherwise
158 */
159 protected boolean isKnownNonPC(String typeName) {
160 return super.isKnownNonPC(typeName) || nonPCClasses.contains(typeName);
161 }
162
163 /***
164 * Hook called when a class is known to be non persistence
165 * capable.
166 * @param className the name of the non-pc class
167 */
168 protected void knownNonPC(String className) {
169 nonPCClasses.add(className);
170 }
171 }