001package org.andromda.core.namespace;
002
003import java.net.URL;
004import java.util.ArrayList;
005import java.util.Collection;
006import java.util.LinkedHashMap;
007import java.util.Map;
008
009/**
010 * Represents a namespace registry.  This is where
011 * all components within a namespace are registered.
012 *
013 * @author Chad Brandon
014 * @author Bob Fields
015 */
016public class NamespaceRegistry
017{
018    /**
019     * The name of the namespace registry
020     */
021    private String name;
022
023    /**
024     * Gets the name of the namespace registry.
025     *
026     * @return Returns the name.
027     */
028    public String getName()
029    {
030        return this.name;
031    }
032
033    /**
034     * SEts the name of the namespace registry.
035     *
036     * @param name The name to set.
037     */
038    public void setName(String name)
039    {
040        this.name = name;
041    }
042
043    /**
044     * Whether or not this is a shared namespace.
045     */
046    private boolean shared = false;
047
048    /**
049     * Gets whether or not the namespace defined by this registry
050     * is shared. By default namespaces are <strong>NOT </strong> shared.
051     *
052     * @return Returns the shared.
053     */
054    public boolean isShared()
055    {
056        return shared;
057    }
058
059    /**
060     * Sets whether or not the namespace defined by this registry is shared.
061     *
062     * @param shared The shared to set.
063     */
064    public void setShared(final boolean shared)
065    {
066        this.shared = shared;
067    }
068
069    /**
070     * Stores the names of the components registered
071     * within this namespace registry and the paths from which
072     * they can be initialized.
073     */
074    private final Map<String, String[]> components = new LinkedHashMap<String, String[]>();
075
076    /**
077     * Registers the component with the
078     * give name in this registry.
079     *
080     * @param component the component of the registry.
081     */
082    public void registerComponent(final Component component)
083    {
084        if (component != null)
085        {
086            this.components.put(
087                component.getName(),
088                component.getPaths());
089        }
090    }
091
092    /**
093     * Gets the names registered components.
094     *
095     * @return the names of the registered components.
096     */
097    public String[] getRegisteredComponents()
098    {
099        return this.components.keySet().toArray(new String[this.components.size()]);
100    }
101
102    /**
103     * Gets the initialization paths for the given component name.
104     *
105     * @param name the name of the component.
106     * @return the paths or null if none are found.
107     */
108    public String[] getPaths(final String name)
109    {
110        return this.components.get(name);
111    }
112
113    /**
114     * Stores the property definitions.
115     */
116    private final Map<String, PropertyDefinition> definitions = new LinkedHashMap<String, PropertyDefinition>();
117
118    /**
119     * Attempts to retrieve the property definition for the given
120     * <code>name</code>.
121     * @param name
122     * @return the property definition or null if one could not be found.
123     */
124    public PropertyDefinition getPropertyDefinition(final String name)
125    {
126        return this.definitions.get(name);
127    }
128
129    /**
130     * Adds all property definitions to the current property definitions.
131     *
132     * @param propertyDefinitions the collection of property definitions.
133     */
134    public void addPropertyDefinitions(final PropertyDefinition[] propertyDefinitions)
135    {
136        for (PropertyDefinition propertyDefinition : propertyDefinitions)
137        {
138            this.addPropertyDefinition(propertyDefinition);
139        }
140    }
141
142    /**
143     * Copies all contents from the <code>registry</code>
144     * to this instance.
145     *
146     * @param registry the registry to copy.
147     */
148    final void copy(final NamespaceRegistry registry)
149    {
150        if (registry != null)
151        {
152            this.addPropertyDefinitions(registry.getPropertyDefinitions());
153            this.components.putAll(registry.components);
154            if (registry.isShared())
155            {
156                this.shared = registry.isShared();
157            }
158            this.resourceRoots.addAll(registry.resourceRoots);
159        }
160    }
161
162    /**
163     * Gets all property definitions belonging to this registry.
164     *
165     * @return all property definitions.
166     */
167    public PropertyDefinition[] getPropertyDefinitions()
168    {
169        return this.definitions.values().toArray(new PropertyDefinition[this.definitions.size()]);
170    }
171
172    /**
173     * Adds a property definition to the group of defintions.
174     *
175     * @param propertyDefinition the property definition.
176     */
177    public void addPropertyDefinition(final PropertyDefinition propertyDefinition)
178    {
179        if (propertyDefinition != null)
180        {
181            this.definitions.put(
182                propertyDefinition.getName(),
183                propertyDefinition);
184        }
185    }
186
187    /**
188     * The root of this namespace which stores all resources.
189     */
190    private Collection<URL> resourceRoots = new ArrayList<URL>();
191
192    /**
193     * Gets the resource root of this namespace.
194     *
195     * @return Returns the resource.
196     */
197    public URL[] getResourceRoots()
198    {
199        return this.resourceRoots.toArray(new URL[this.resourceRoots.size()]);
200    }
201
202    /**
203     * Adds a resource root to this namespace (since a namespace can consist of multiple
204     * locations)
205     *
206     * @param resourceRoot The resource root to set.
207     */
208    final void addResourceRoot(final URL resourceRoot)
209    {
210        this.resourceRoots.add(resourceRoot);
211    }
212
213    /**
214     * @see Object#toString()
215     */
216    public String toString()
217    {
218        return super.toString() + '[' + this.getName() + ']';
219    }
220}