1 package net.sf.quarrel.uml;
2
3 import net.sf.quarrel.uml.impl.RelationshipImpl;
4 import org.apache.commons.collections.IteratorUtils;
5 import org.apache.commons.logging.Log;
6 import org.apache.commons.logging.LogFactory;
7
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14
15 /***
16 * Represents a UML model. Top level container for all other parts of the UML code.
17 */
18 public class Model {
19
20 /***
21 * The logging instance
22 */
23 private static final Log LOG = LogFactory.getLog(Model.class);
24
25 /***
26 * A mapping of Element objects where the key is the name of the element.
27 */
28 private final Map _elements = new HashMap();
29
30 /***
31 * A list of Relationship objects.
32 */
33 private final List _relationships = new ArrayList();
34
35 /***
36 * Returns an Iterator for the set of Elements in the model. The underlying
37 * List can not be modified using this Iterator.
38 *
39 * @return an Iterator over the set of Elements
40 */
41 public Iterator elements() {
42 return Collections.unmodifiableCollection(_elements.values()).iterator();
43 }
44
45 /***
46 * Adds an element to the model. Package level access so that other classes
47 * can not manipulate the model.
48 *
49 * @param element the element to add
50 */
51 void addElement(Element element) {
52
53 _elements.put(element.getName(), element);
54 }
55
56 /***
57 * Returns an instance of Element representing the name specified. Multiple
58 * calls with the same name String will return the same element. If an
59 * instance does not exist, one will be created.
60 * <p/>
61 * Package level access so that other classes can not manipulate the model.
62 *
63 * @param name the name of the element to find.
64 * @return an instanct of Element if one exists
65 */
66 Element getElement(String name) {
67
68 Element element = (Element) _elements.get(name);
69
70 if (element == null) {
71 element = new ElementStub(name);
72 _elements.put(name, element);
73 }
74
75 return element;
76
77 }
78
79 /***
80 * A do nothing implementation of Element used to represent elements which
81 * are referenced but never declared.
82 */
83 private static class ElementStub
84 implements Element, AttributeAggregator {
85
86 /***
87 * The name of the element.
88 */
89 private final String _name;
90
91 /***
92 * Creates a stub element instance with the specified name
93 *
94 * @param name a String identifying the element.
95 */
96 public ElementStub(final String name) {
97 _name = name;
98 }
99
100 /***
101 * {@inheritDoc}
102 */
103 public String getName() {
104 return _name;
105 }
106
107 /***
108 * Returns an empty iterator representing the set of attributes.
109 *
110 * @return an Iterator with nothing in it.
111 */
112 public Iterator attributes() {
113 return IteratorUtils.emptyIterator();
114 }
115
116 /***
117 * {@inheritDoc}
118 */
119 public void addAttribute(String attributeName) {
120
121
122 }
123
124 }
125
126 /***
127 * Returns an iterator over the set of relationships in the model
128 *
129 * @return an Iterator over the set of Relationship objects.
130 */
131 public Iterator relationships() {
132
133 return _relationships.iterator();
134 }
135
136 /***
137 * Adds a relationship between two elements.
138 *
139 * @param relationshipType the type of the Relationship to create
140 * @param client the dependent Element
141 * @param supplier the independent Element
142 */
143 void addRelationship(RelationshipType relationshipType,
144 Element client,
145 Element supplier) {
146
147 _relationships.add(new RelationshipImpl(relationshipType, client, supplier));
148
149 }
150
151 /***
152 * Returns a boolean value indicating if an element exists by name.
153 *
154 * @param name the name of the requested element
155 *
156 * @return true if an element exists with the specified name.
157 *
158 * @deprecated this method will be removed or made private in the future
159 */
160 public boolean elementExists(final String name) {
161
162 return _elements.containsKey(name);
163 }
164
165 }