View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at 
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
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                 // create new model and store it using the specified javaModel
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             // nothing to be removed => return
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                     // found jdoModel => remove the entry
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 }