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