MetafacadeCache.java
package org.andromda.core.metafacade;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* A global cache for metafacades. Used by the {@link MetafacadeFactory}when constructing or retrieving metafacade
* instances. If the cache constains the metafacade it should not be constructed again.
*
* @author Chad Brandon
*/
public final class MetafacadeCache
implements Serializable
{
private static final long serialVersionUID = 34L;
/**
* Constructs a new instance of this class.
*
* @return the new instance
*/
public static MetafacadeCache newInstance()
{
return new MetafacadeCache();
}
private MetafacadeCache()
{
// don't allow instantiation
}
/**
* The namespace to which the cache currently applies
*/
private String namespace;
/**
* Sets the namespace to which the cache currently applies.
*
* @param namespace the current namespace.
*/
public final void setNamespace(final String namespace)
{
this.namespace = namespace;
}
/**
* The cache for already created metafacades.
*/
private final Map<Object, Map<Class, Map<String, MetafacadeBase>>> metafacadeCache = new HashMap<Object, Map<Class, Map<String, MetafacadeBase>>>();
/**
* <p>
* Returns the metafacade from the metafacade cache. The Metafacades are cached first by according to its
* <code>mappingObject</code>, next the <code>metafacadeClass</code>, and finally by the current namespace. </p>
* <p>
* Metafacades must be cached in order to keep track of the state of its validation. If we keep creating a new one
* each time, we can never tell whether or not a metafacade has been previously validated. Not to mention tremendous
* performance gains. </p>
*
* @param mappingObject the object to which the mapping applies
* @param metafacadeClass the class of the metafacade.
* @return MetafacadeBase stored in the cache.
*/
public final MetafacadeBase get(
final Object mappingObject,
final Class metafacadeClass)
{
MetafacadeBase metafacade = null;
final Map<Class, Map<String, MetafacadeBase>> namespaceMetafacadeCache = this.metafacadeCache.get(mappingObject);
if (namespaceMetafacadeCache != null)
{
final Map<String, MetafacadeBase> metafacadeCache = namespaceMetafacadeCache.get(metafacadeClass);
if (metafacadeCache != null)
{
metafacade = metafacadeCache.get(this.namespace);
}
}
return metafacade;
}
/**
* Adds the <code>metafacade</code> to the cache according to first <code>mappingObject</code>, second the
* <code>metafacade</code>, and finally by the current <code>namespace</code>.
*
* @param mappingObject the mappingObject for which to cache the metafacade.
* @param metafacade the metafacade to cache.
*/
public final void add(
final Object mappingObject,
final MetafacadeBase metafacade)
{
Map<Class, Map<String, MetafacadeBase>> namespaceMetafacadeCache = this.metafacadeCache.get(mappingObject);
if (namespaceMetafacadeCache == null)
{
namespaceMetafacadeCache = new HashMap<Class, Map<String, MetafacadeBase>>();
this.metafacadeCache.put(mappingObject, namespaceMetafacadeCache);
}
Map<String, MetafacadeBase> metafacadeCache = namespaceMetafacadeCache.get(metafacade.getClass());
if (metafacadeCache == null)
{
metafacadeCache = new HashMap<String, MetafacadeBase>();
namespaceMetafacadeCache.put(
metafacade.getClass(),
metafacadeCache);
}
metafacadeCache.put(this.namespace, metafacade);
}
/**
* Clears the cache of any metafacades
*/
public final void clear()
{
this.metafacadeCache.clear();
}
/**
* @see Object#toString()
*/
public String toString()
{
return this.metafacadeCache.toString();
}
}