View Javadoc
1   package org.andromda.core.metafacade;
2   
3   import java.io.Serializable;
4   import java.util.HashMap;
5   import java.util.Map;
6   
7   /**
8    * A global cache for metafacades. Used by the {@link MetafacadeFactory}when constructing or retrieving metafacade
9    * instances. If the cache constains the metafacade it should not be constructed again.
10   *
11   * @author Chad Brandon
12   */
13  public final class MetafacadeCache
14      implements Serializable
15  {
16      private static final long serialVersionUID = 34L;
17  
18      /**
19       * Constructs a new instance of this class.
20       *
21       * @return the new instance
22       */
23      public static MetafacadeCache newInstance()
24      {
25          return new MetafacadeCache();
26      }
27  
28      private MetafacadeCache()
29      {
30          // don't allow instantiation
31      }
32  
33      /**
34       * The namespace to which the cache currently applies
35       */
36      private String namespace;
37  
38      /**
39       * Sets the namespace to which the cache currently applies.
40       *
41       * @param namespace the current namespace.
42       */
43      public final void setNamespace(final String namespace)
44      {
45          this.namespace = namespace;
46      }
47  
48      /**
49       * The cache for already created metafacades.
50       */
51      private final Map<Object, Map<Class, Map<String, MetafacadeBase>>> metafacadeCache = new HashMap<Object, Map<Class, Map<String, MetafacadeBase>>>();
52  
53      /**
54       * <p>
55       * Returns the metafacade from the metafacade cache. The Metafacades are cached first by according to its
56       * <code>mappingObject</code>, next the <code>metafacadeClass</code>, and finally by the current namespace. </p>
57       * <p>
58       * Metafacades must be cached in order to keep track of the state of its validation. If we keep creating a new one
59       * each time, we can never tell whether or not a metafacade has been previously validated. Not to mention tremendous
60       * performance gains. </p>
61       *
62       * @param mappingObject   the object to which the mapping applies
63       * @param metafacadeClass the class of the metafacade.
64       * @return MetafacadeBase stored in the cache.
65       */
66      public final MetafacadeBase get(
67          final Object mappingObject,
68          final Class metafacadeClass)
69      {
70          MetafacadeBase metafacade = null;
71          final Map<Class, Map<String, MetafacadeBase>> namespaceMetafacadeCache = this.metafacadeCache.get(mappingObject);
72          if (namespaceMetafacadeCache != null)
73          {
74              final Map<String, MetafacadeBase> metafacadeCache = namespaceMetafacadeCache.get(metafacadeClass);
75              if (metafacadeCache != null)
76              {
77                  metafacade = metafacadeCache.get(this.namespace);
78              }
79          }
80          return metafacade;
81      }
82  
83      /**
84       * Adds the <code>metafacade</code> to the cache according to first <code>mappingObject</code>, second the
85       * <code>metafacade</code>, and finally by the current <code>namespace</code>.
86       *
87       * @param mappingObject the mappingObject for which to cache the metafacade.
88       * @param metafacade the metafacade to cache.
89       */
90      public final void add(
91          final Object mappingObject,
92          final MetafacadeBase metafacade)
93      {
94          Map<Class, Map<String, MetafacadeBase>> namespaceMetafacadeCache = this.metafacadeCache.get(mappingObject);
95          if (namespaceMetafacadeCache == null)
96          {
97              namespaceMetafacadeCache = new HashMap<Class, Map<String, MetafacadeBase>>();
98              this.metafacadeCache.put(mappingObject, namespaceMetafacadeCache);
99          }
100         Map<String, MetafacadeBase> metafacadeCache = namespaceMetafacadeCache.get(metafacade.getClass());
101         if (metafacadeCache == null)
102         {
103             metafacadeCache = new HashMap<String, MetafacadeBase>();
104             namespaceMetafacadeCache.put(
105                 metafacade.getClass(),
106                 metafacadeCache);
107         }
108         metafacadeCache.put(this.namespace, metafacade);
109     }
110 
111     /**
112      * Clears the cache of any metafacades
113      */
114     public final void clear()
115     {
116         this.metafacadeCache.clear();
117     }
118 
119     /**
120      * @see Object#toString()
121      */
122     public String toString()
123     {
124         return this.metafacadeCache.toString();
125     }
126 }