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