View Javadoc

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