1
2
3
4 package net.sf.quarrel.uml;
5
6 import net.sf.quarrel.file.ElementType;
7 import net.sf.quarrel.file.Feature;
8 import net.sf.quarrel.file.FeatureType;
9 import net.sf.quarrel.file.FileElement;
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19
20 public final class ModelBuilder2 implements ModelBuilder {
21
22 private final Log LOG = LogFactory.getLog(ModelBuilder2.class);
23
24 private final List _unprocessed = new ArrayList();
25
26 private Model _model;
27
28 public ModelBuilder2() {
29
30 }
31
32 public Model getModel() {
33
34 if (_model == null) {
35 buildModel();
36 }
37
38 return _model;
39 }
40
41 private void buildModel() {
42
43 _model = new Model();
44
45 ElementHandler handler;
46
47
48
49 for (Iterator iterator = _unprocessed.iterator(); iterator.hasNext();) {
50 FileElement element = (FileElement) iterator.next();
51 handler = getHandler(element);
52 handler.register(element);
53 }
54
55
56 for (Iterator iterator = _unprocessed.iterator(); iterator.hasNext();) {
57 FileElement element = (FileElement) iterator.next();
58 handler = getHandler(element);
59 handler.link(element);
60 }
61
62
63
64
65 }
66
67 private ElementHandler getHandler(final FileElement element) {
68 final ElementType elementType;
69 final ElementHandler elementHandler;
70 elementType = element.getElementType();
71 elementHandler = getElementHandler(elementType);
72 return elementHandler;
73 }
74
75 /***
76 * {@inheritDoc}
77 */
78 public void add(final FileElement element) {
79
80 _unprocessed.add(element);
81
82
83
84 }
85
86 /***
87 * Finds the best ElementHandler to use for the ElementType provided.
88 *
89 * @param elementType the ElementType of interest
90 * @return the appropriate implementation of ElementHandler
91 */
92 private ElementHandler getElementHandler(final ElementType elementType) {
93
94 final ElementHandler elementHandler;
95
96 Map handlers = new HashMap();
97 handlers.put(ElementType.CLASS, new ClassElementHandler());
98 handlers.put(ElementType.INTERFACE, new InterfaceElementHandler());
99
100 elementHandler = (ElementHandler) handlers.get(elementType);
101
102
103 if (elementHandler == null) {
104 throw new IllegalArgumentException("ElementType " + elementType + " is not supported");
105 }
106
107 return elementHandler;
108
109 }
110
111 /***
112 * <p>This interface will partition off the functionality needed to adpat a
113 * FileElement to the internal UML model. There will be implementations
114 * for each of the top level elements such as Class, Interface, Use Case
115 * etc.
116 * </p>
117 * <p/>
118 * These will be implemented as non-static member classes so that they can
119 * have access to the Model instance.
120 * </p>
121 * <p/>
122 * Implementations are expected to be stateless.
123 * </p>
124 */
125 private static interface ElementHandler {
126 public void link(FileElement element);
127
128 public void register(FileElement element);
129 }
130
131 private class InterfaceElementHandler extends StructuredElementHandler {
132
133 public void link(FileElement element) {
134
135 final String name = element.getName();
136 final Element subject = _model.getElement(name);
137
138 handleExtensions(element, subject);
139
140 }
141
142
143 public void register(final FileElement element) {
144
145 final UmlInterface umlInterface = new UmlInterface(element.getName());
146
147 handleOperations(element, umlInterface);
148
149
150 handleAttributes(element, umlInterface);
151
152 _model.addElement(umlInterface);
153
154 }
155 }
156
157 private class ClassElementHandler extends StructuredElementHandler {
158
159 public void link(FileElement element) {
160
161 final String name = element.getName();
162 final UmlClass subject = (UmlClass) _model.getElement(name);
163
164 handleImplementations(element, subject);
165 handleExtensions(element, subject);
166
167
168
169
170 }
171
172
173 public void register(FileElement element) {
174
175 final UmlClass umlClass = new UmlClass(element.getName());
176 handleOperations(element, umlClass);
177 handleAttributes(element, umlClass);
178 _model.addElement(umlClass);
179
180 }
181
182 private void handleImplementations(final FileElement element,
183 final UmlClass umlClass) {
184
185 final Collection implementedInterfaces = element.getFeatures(FeatureType.IMPLEMENTS);
186 for (Iterator iterator = implementedInterfaces.iterator(); iterator.hasNext();)
187 {
188 Feature feature = (Feature) iterator.next();
189 final String supplierName = feature.getText().trim();
190 final Element supplier = _model.getElement(supplierName);
191 _model.addRelationship(RelationshipType.Realization, umlClass, supplier);
192
193 }
194
195 }
196
197 }
198
199 private abstract class StructuredElementHandler
200 implements ModelBuilder2.ElementHandler {
201
202 void handleAttributes(final FileElement element,
203 final StructuredElement structuredElement) {
204
205 final Collection attributes = element.getFeatures(FeatureType.ATTRIBUTES);
206 for (Iterator iterator = attributes.iterator(); iterator.hasNext();)
207 {
208 Feature feature = (Feature) iterator.next();
209 structuredElement.addAttribute(feature.getText());
210 }
211
212 }
213
214 void handleOperations(final FileElement element,
215 final StructuredElement structuredElement) {
216
217 final Collection operations = element.getFeatures(FeatureType.OPERATIONS);
218
219 for (Iterator iterator = operations.iterator(); iterator.hasNext();)
220 {
221 Feature feature = (Feature) iterator.next();
222 structuredElement.addOperation(feature.getText());
223 }
224
225 }
226
227 void handleExtensions(final FileElement element,
228 final Element umlClass) {
229
230 final Collection implementedInterfaces = element.getFeatures(FeatureType.EXTENDS);
231 for (Iterator iterator = implementedInterfaces.iterator(); iterator.hasNext();)
232 {
233 Feature feature = (Feature) iterator.next();
234 final String supplierName = feature.getText().trim();
235 final Element supplier = _model.getElement(supplierName);
236
237 LOG.debug("Adding relationship type " + RelationshipType.Generalization);
238 LOG.debug(" client " + umlClass.getName());
239 LOG.debug(" supplier " + supplier.getName());
240
241 _model.addRelationship(RelationshipType.Generalization, umlClass, supplier);
242
243 }
244
245 }
246 }
247
248 }