View Javadoc

1   /*
2    * Created by ratt at Mar 28, 2007 on 5:47:08 AM
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          // find list of declared entities
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          // establish relationships in model
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          // establish relationships
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  //        elementHandler.link(element);
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         // todo there is no unit test for this condition yet
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             // per UML spec, interfaces can have attributes
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             //todo link extensions
167             //todo link dependencies
168             //todo link associations
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 }