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;
19
20 import java.util.Iterator;
21 import java.util.Map;
22 import java.util.HashMap;
23
24 import org.apache.jdo.model.java.JavaModel;
25 import org.apache.jdo.model.jdo.JDOModel;
26 import org.apache.jdo.model.jdo.JDOModelFactory;
27
28 /***
29 * Factory for dynamic JDOModel instances. The factory provides a
30 * mechanism to cache JDOModel instances per JavaModel instances.
31 * <p>
32 * TBD:
33 * <ul>
34 * <li> Check synchronization.
35 * </ul>
36 *
37 * @author Michael Bouschen
38 * @since 1.1
39 * @version 2.0
40 */
41 public class JDOModelFactoryImplDynamic implements JDOModelFactory {
42
43 /***
44 * Map of JDOModel instances, key is the JavaModel
45 * {@link #getJDOModel(JavaModel javaModel)}
46 */
47 private Map modelCache = new HashMap();
48
49 /*** The singleton JDOModelFactory instance. */
50 private static JDOModelFactory jdoModelFactory =
51 new JDOModelFactoryImplDynamic();
52
53 /***
54 * Creates new JDOModelFactory. This constructor should not be
55 * called directly; instead, the singleton access method
56 * {@link #getInstance} should be used.
57 */
58 protected JDOModelFactoryImplDynamic() {}
59
60 /***
61 * Get an instance of JDOModelFactory.
62 * @return an instance of JDOModelFactory
63 */
64 public static JDOModelFactory getInstance() {
65 return jdoModelFactory;
66 }
67
68 /***
69 * Creates a new empty JDOModel instance.
70 * The returned JDOModel instance uses the specified flag
71 * <code>loadXMLMetadataDefault</code> to set the default behavior
72 * for the creation of new JDOClass instances using methods
73 * {@link JDOModel#createJDOClass(String)} and
74 * {@link JDOModel#getJDOClass(String)} for which the caller doesn't
75 * explicitly specify whether to read XML metatdata or not.
76 * @param loadXMLMetadataDefault the default setting for whether to
77 * read XML metatdata in JDOModel's methods for JDOClass creation.
78 */
79 public JDOModel createJDOModel(JavaModel javaModel,
80 boolean loadXMLMetadataDefault) {
81 return new JDOModelImplDynamic(javaModel, loadXMLMetadataDefault);
82 }
83
84 /***
85 * Returns the JDOModel instance for the specified javaModel.
86 * @param javaModel the javaModel used to cache the returned JDOModel
87 * instance.
88 */
89 public JDOModel getJDOModel(JavaModel javaModel) {
90 return getJDOModel(javaModel, true);
91 }
92
93 /***
94 * Returns the JDOModel instance for the specified javaModel.
95 * The returned JDOModel instance uses the specified flag
96 * <code>loadXMLMetadataDefault</code> to set the default behavior
97 * for the creation of new JDOClass instances using methods
98 * {@link JDOModel#createJDOClass(String)} and
99 * {@link JDOModel#getJDOClass(String)} for which the caller doesn't
100 * explicitly specify whether to read XML metatdata or not.
101 * @param loadXMLMetadataDefault the default setting for whether to
102 * read XML metatdata in JDOModel's methods for JDOClass creation.
103 */
104 public JDOModel getJDOModel(JavaModel javaModel,
105 boolean loadXMLMetadataDefault) {
106 synchronized (modelCache) {
107 JDOModel jdoModel = (JDOModel)modelCache.get(javaModel);
108 if (jdoModel == null) {
109
110 jdoModel = createJDOModel(javaModel, loadXMLMetadataDefault);
111 modelCache.put(javaModel, jdoModel);
112 }
113 return jdoModel;
114 }
115 }
116
117 /***
118 * Removes the specified jdoModel from the JDOModel cache. Note, if
119 * there are multiple entries in the cache with the specified jdoModel
120 * as value, then all of them get removed. The method does not have an
121 * effect, if this factory does not have the specified jdoModel.
122 * @param jdoModel the JDOModel to be removed.
123 * @since 2.0
124 */
125 public void removeJDOModel(JDOModel jdoModel) {
126 if (jdoModel == null) {
127
128 return;
129 }
130
131 synchronized (modelCache) {
132 for (Iterator i = modelCache.entrySet().iterator(); i.hasNext();) {
133 Map.Entry entry = (Map.Entry) i.next();
134 Object value = entry.getValue();
135 if (jdoModel.equals(value)) {
136
137 i.remove();
138 }
139 }
140 }
141 }
142
143 /***
144 * Removes the JDOModel for the specified javaModel from the JDOModel
145 * cache. The method does not have an effect, if this factory does not
146 * have a JDOModel for the the specified javaModel.
147 * @param javaModel the javaModel used to find the JDOModel instance to be
148 * removed.
149 * @since 2.0
150 */
151 public void removeJDOModel(JavaModel javaModel) {
152 synchronized (modelCache) {
153 modelCache.remove(javaModel);
154 }
155 }
156 }