001: package org.andromda.core.profile;
002:
003: import java.net.URL;
004: import java.util.Collection;
005: import java.util.Iterator;
006: import java.util.LinkedHashMap;
007: import java.util.Map;
008:
009: import org.andromda.core.common.ComponentContainer;
010: import org.andromda.core.common.XmlObjectFactory;
011: import org.andromda.core.configuration.NamespaceProperties;
012: import org.andromda.core.configuration.Namespaces;
013: import org.andromda.core.configuration.Property;
014: import org.andromda.core.namespace.BaseNamespaceComponent;
015:
016: /**
017: * Represents an AndroMDA profile applied to a model.
018: * Profiles allow us to extend aspects of a model.
019: *
020: * @author Chad Brandon
021: */
022: public class Profile extends BaseNamespaceComponent {
023: /**
024: * The shared instance of this class.
025: */
026: private static Profile instance;
027:
028: /**
029: * Gets the shared instance of this class.
030: *
031: * @return the shared instance.
032: */
033: public static Profile instance() {
034: if (instance == null) {
035: instance = new Profile();
036: }
037: return instance;
038: }
039:
040: /**
041: * Stores the elements for the profile (by name).
042: */
043: private final Map elements = new LinkedHashMap();
044:
045: /**
046: * Adds a new element to this namespace registry.
047: */
048: public void addElement(final String name, final String value) {
049: this .elements.put(name, value);
050: }
051:
052: /**
053: * Gets the profile value (if one is available)
054: * for the given name, otherwise returns name.
055: *
056: * @param name the profile name to retrieve.
057: * @return the value.
058: */
059: public String get(final String name) {
060: // - attempt to get the profile value from the profile defined
061: // by the profile mappings uri first
062: String value = (String) this .elements.get(name);
063:
064: // - if we can't get any profile value from an the override profile
065: // mapping, then we resort to the ones defined in the namespace
066: if (value == null || value.trim().length() == 0) {
067: Map namespaceElements = this .getNamespaceElements(this
068: .getNamespace());
069: if (namespaceElements != null) {
070: value = (String) namespaceElements.get(name);
071: }
072: if (value == null) {
073: namespaceElements = this
074: .getNamespaceElements(Namespaces.DEFAULT);
075: if (namespaceElements != null) {
076: value = (String) namespaceElements.get(name);
077: }
078: }
079: }
080: return value != null ? value : name;
081: }
082:
083: /**
084: * Initializes this profile instance.
085: */
086: public void initialize() {
087: final Collection profiles = ComponentContainer.instance()
088: .findComponentsOfType(Profile.class);
089: for (final Iterator iterator = profiles.iterator(); iterator
090: .hasNext();) {
091: final Profile profile = (Profile) iterator.next();
092:
093: String namespace = profile.getNamespace();
094: if (Namespaces.instance().isShared(namespace)) {
095: profile.setNamespace(Namespaces.DEFAULT);
096: }
097: this .addElements(profile);
098: }
099: }
100:
101: /**
102: * Refreshes the profile instance.
103: */
104: public void refresh() {
105: // - clear out the instance's elements
106: this .elements.clear();
107: try {
108: final Property mappingsUri = Namespaces.instance()
109: .getProperty(Namespaces.DEFAULT,
110: NamespaceProperties.PROFILE_MAPPINGS_URI,
111: false);
112: final String mappingsUriValue = mappingsUri != null ? mappingsUri
113: .getValue()
114: : null;
115: if (mappingsUriValue != null) {
116: final XmlObjectFactory factory = XmlObjectFactory
117: .getInstance(Profile.class);
118: final Profile profile = (Profile) factory
119: .getObject(new URL(mappingsUriValue.trim()));
120: this .elements.putAll(profile.elements);
121: }
122: } catch (final Throwable throwable) {
123: throw new ProfileException(throwable);
124: }
125: }
126:
127: /**
128: * Stores all elements.
129: */
130: private final Map allElements = new LinkedHashMap();
131:
132: /**
133: * Adds the elements to the interal elements map.
134: */
135: private void addElements(final Profile profile) {
136: final Collection elements = profile != null ? profile.elements
137: .keySet() : null;
138: if (elements != null) {
139: final String namespace = profile.getNamespace();
140: final Map namespaceElements = this
141: .getNamespaceElements(namespace);
142: for (final Iterator iterator = elements.iterator(); iterator
143: .hasNext();) {
144: final String name = (String) iterator.next();
145: namespaceElements.put(name, profile.elements.get(name));
146: }
147: }
148: }
149:
150: /**
151: * Adds a namespace element for the given namespace with the given name and
152: * value.
153: * @param namespace the namespace for which to add the namespace element.
154: * @param name the element name.
155: * @param value the element value.
156: */
157: public void addElement(final String namespace, final String name,
158: final String value) {
159: final Map namespaceElements = this
160: .getNamespaceElements(namespace);
161: namespaceElements.put(name, value);
162: }
163:
164: /**
165: * Retrieves the namespace elements map for the given namespace.
166: * If one doesn't exist, then a new one is created.
167: * @param namespace the namespace for which to retrieve the namespace elements
168: * @return the namespace element map
169: */
170: private Map getNamespaceElements(final String namespace) {
171: Map namespaceElements = (Map) this .allElements.get(namespace);
172: if (namespaceElements == null) {
173: namespaceElements = new LinkedHashMap();
174: this .allElements.put(namespace, namespaceElements);
175: }
176: return namespaceElements;
177: }
178:
179: /**
180: * Shuts down the shared instance and releases any used resources.
181: */
182: public void shutdown() {
183: instance = null;
184: }
185: }
|