001: package org.andromda.core.metafacade;
002:
003: import java.util.HashMap;
004: import java.util.Map;
005:
006: /**
007: * A global cache for metafacades. Used by the {@link MetafacadeFactory}when constructing or retrieving metafacade
008: * instances. If the cache constains the metafacade it should not be constructed again.
009: *
010: * @author Chad Brandon
011: */
012: public final class MetafacadeCache {
013: /**
014: * Constructs a new instance of this class.
015: *
016: * @return the new instance
017: */
018: public static MetafacadeCache newInstance() {
019: return new MetafacadeCache();
020: }
021:
022: private MetafacadeCache() {
023: // don't allow instantiation
024: }
025:
026: /**
027: * The namespace to which the cache currently applies
028: */
029: private String namespace;
030:
031: /**
032: * Sets the namespace to which the cache currently applies.
033: *
034: * @param namespace the current namespace.
035: */
036: public final void setNamespace(final String namespace) {
037: this .namespace = namespace;
038: }
039:
040: /**
041: * The cache for already created metafacades.
042: */
043: private final Map metafacadeCache = new HashMap();
044:
045: /**
046: * <p/>
047: * Returns the metafacade from the metafacade cache. The Metafacades are cached first by according to its
048: * <code>mappingObject</code>, next the <code>metafacadeClass</code>, and finally by the current namespace. </p>
049: * <p/>
050: * Metafacades must be cached in order to keep track of the state of its validation. If we keep creating a new one
051: * each time, we can never tell whether or not a metafacade has been previously validated. Not to mention tremendous
052: * performance gains. </p>
053: *
054: * @param mappingObject the object to which the mapping applies
055: * @param metafacadeClass the class of the metafacade.
056: * @return MetafacadeBase stored in the cache.
057: */
058: public final MetafacadeBase get(final Object mappingObject,
059: final Class metafacadeClass) {
060: MetafacadeBase metafacade = null;
061: final Map namespaceMetafacadeCache = (Map) this .metafacadeCache
062: .get(mappingObject);
063: if (namespaceMetafacadeCache != null) {
064: final Map metafacadeCache = (Map) namespaceMetafacadeCache
065: .get(metafacadeClass);
066: if (metafacadeCache != null) {
067: metafacade = (MetafacadeBase) metafacadeCache
068: .get(this .namespace);
069: }
070: }
071: return metafacade;
072: }
073:
074: /**
075: * Adds the <code>metafacade</code> to the cache according to first <code>mappingObject</code>, second the
076: * <code>metafacade</code>, and finally by the current <code>namespace</code>.
077: *
078: * @param mappingObject the mappingObject for which to cache the metafacade.
079: * @param metafacade the metafacade to cache.
080: */
081: public final void add(final Object mappingObject,
082: final MetafacadeBase metafacade) {
083: Map namespaceMetafacadeCache = (Map) this .metafacadeCache
084: .get(mappingObject);
085: if (namespaceMetafacadeCache == null) {
086: namespaceMetafacadeCache = new HashMap();
087: this .metafacadeCache.put(mappingObject,
088: namespaceMetafacadeCache);
089: }
090: Map metafacadeCache = (Map) namespaceMetafacadeCache
091: .get(metafacade.getClass());
092: if (metafacadeCache == null) {
093: metafacadeCache = new HashMap();
094: namespaceMetafacadeCache.put(metafacade.getClass(),
095: metafacadeCache);
096: }
097: metafacadeCache.put(this .namespace, metafacade);
098: }
099:
100: /**
101: * Clears the cache of any metafacades
102: */
103: public final void clear() {
104: this .metafacadeCache.clear();
105: }
106:
107: /**
108: * @see java.lang.Object#toString()
109: */
110: public String toString() {
111: return this.metafacadeCache.toString();
112: }
113: }
|