Profile.java
package org.andromda.core.profile;
import java.io.Serializable;
import java.net.URL;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import org.andromda.core.common.ComponentContainer;
import org.andromda.core.common.XmlObjectFactory;
import org.andromda.core.configuration.NamespaceProperties;
import org.andromda.core.configuration.Namespaces;
import org.andromda.core.configuration.Property;
import org.andromda.core.namespace.BaseNamespaceComponent;
import org.apache.commons.lang.StringUtils;
/**
* Represents an AndroMDA profile applied to a model.
* Profiles allow us to extend aspects of a model.
*
* @author Chad Brandon
* @author Bob Fields
*/
public class Profile
extends BaseNamespaceComponent
implements Serializable
{
private static final long serialVersionUID = 34L;
/**
* The shared instance of this class.
*/
private static Profile instance;
/**
* Gets the shared instance of this class.
*
* @return the shared instance.
*/
public static Profile instance()
{
if (instance == null)
{
instance = new Profile();
}
return instance;
}
/**
* Stores the elements for the profile (by name).
*/
private final Map<String, String> elements = new LinkedHashMap<String, String>();
/**
* Adds a new element to this namespace registry.
* @param name
* @param value
*/
public void addElement(
final String name,
final String value)
{
this.elements.put(
name,
value);
}
/**
* Gets the profile value (if one is available)
* for the given name, otherwise returns name.
*
* @param name the profile name to retrieve.
* @return the value.
*/
public String get(String name)
{
name = StringUtils.trim(name);
// - attempt to get the profile value from the profile defined
// by the profile mappings uri first
String value = this.elements.get(name);
// - if we can't get any profile value from an the override profile
// mapping, then we resort to the ones defined in the namespace
if (StringUtils.isBlank(value))
{
Map<String, String> namespaceElements = this.getNamespaceElements(this.getNamespace());
if (namespaceElements != null)
{
value = namespaceElements.get(name);
}
if (value == null)
{
namespaceElements = this.getNamespaceElements(Namespaces.DEFAULT);
if (namespaceElements != null)
{
value = namespaceElements.get(name);
}
}
}
return value != null ? value : name;
}
/**
* Initializes this profile instance.
*/
public void initialize()
{
final Collection<Profile> profiles = ComponentContainer.instance().findComponentsOfType(Profile.class);
for (final Profile profile : profiles)
{
String namespace = profile.getNamespace();
if (Namespaces.instance().isShared(namespace))
{
profile.setNamespace(Namespaces.DEFAULT);
}
this.addElements(profile);
}
}
/**
* Refreshes the profile instance.
*/
public void refresh()
{
// - clear out the instance's elements
this.elements.clear();
try
{
final Property mappingsUri =
Namespaces.instance().getProperty(
Namespaces.DEFAULT,
NamespaceProperties.PROFILE_MAPPINGS_URI,
false);
final String mappingsUriValue = mappingsUri != null ? mappingsUri.getValue() : null;
if (mappingsUriValue != null)
{
final XmlObjectFactory factory = XmlObjectFactory.getInstance(Profile.class);
final Profile profile = (Profile)factory.getObject(new URL(mappingsUriValue.trim()));
this.elements.putAll(profile.elements);
}
}
catch (final Throwable throwable)
{
throw new ProfileException(throwable);
}
}
/**
* Stores all elements.
*/
private final Map<String, Map<String, String>> allElements = new LinkedHashMap<String, Map<String, String>>();
/**
* Adds the elements to the internal elements map.
* @param profile Profile
*/
private void addElements(final Profile profile)
{
final Collection<String> elements = profile != null ? profile.elements.keySet() : null;
if (elements != null && profile != null)
{
final String namespace = profile.getNamespace();
final Map<String, String> namespaceElements = this.getNamespaceElements(namespace);
for (final String name : elements)
{
namespaceElements.put(
name,
profile.elements.get(name));
}
}
}
/**
* Adds a namespace element for the given namespace with the given name and
* value.
* @param namespace the namespace for which to add the namespace element.
* @param name the element name.
* @param value the element value.
*/
public void addElement(
final String namespace,
final String name,
final String value)
{
final Map<String, String> namespaceElements = this.getNamespaceElements(namespace);
namespaceElements.put(
name,
value);
}
/**
* Retrieves the namespace elements map for the given namespace.
* If one doesn't exist, then a new one is created.
* @param namespace the namespace for which to retrieve the namespace elements
* @return the namespace element map
*/
private Map<String, String> getNamespaceElements(final String namespace)
{
Map<String, String> namespaceElements = this.allElements.get(namespace);
if (namespaceElements == null)
{
namespaceElements = new LinkedHashMap<String, String>();
this.allElements.put(
namespace,
namespaceElements);
}
return namespaceElements;
}
/**
* Shuts down the shared instance and releases any used resources.
*/
public void shutdown()
{
Profile.instance = null;
}
}