1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package th.co.edge.jseq.argouml;
24
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.LinkedList;
28 import java.util.List;
29 import java.util.Map;
30
31 import javax.xml.parsers.DocumentBuilder;
32 import javax.xml.parsers.DocumentBuilderFactory;
33 import javax.xml.parsers.ParserConfigurationException;
34
35 import org.w3c.dom.DOMImplementation;
36 import org.w3c.dom.Document;
37 import org.w3c.dom.DocumentType;
38 import org.w3c.dom.Element;
39
40 import ru.novosoft.uml.behavior.common_behavior.MAction;
41 import ru.novosoft.uml.behavior.common_behavior.MLink;
42 import ru.novosoft.uml.behavior.common_behavior.MObject;
43 import ru.novosoft.uml.behavior.common_behavior.MStimulus;
44 import ru.novosoft.uml.foundation.core.MClass;
45 import ru.novosoft.uml.foundation.core.MClassifier;
46 import ru.novosoft.uml.foundation.core.MNamespace;
47
48 import th.co.edge.jseq.Activation;
49 import th.co.edge.jseq.MockObject;
50 import th.co.edge.jseq.MockObjectMap;
51 import th.co.edge.jseq.argouml.pgml.Fig;
52 import th.co.edge.jseq.argouml.pgml.FigLink;
53 import th.co.edge.jseq.argouml.pgml.FigObject;
54 import th.co.edge.jseq.argouml.pgml.FigStimulus;
55
56
57
58
59
60 public class SequenceDiagram {
61 private static final String PGML_PUBLIC_ID = null;
62 private static final String PGML_SYSTEM_ID = "pgml.dtd";
63 private static final String PGML_NAMESPACE = null;
64
65 private static final String UML_SEQUENCE_DIAGRAM_CLASS =
66 "org.argouml.uml.diagram.sequence.ui.UMLSequenceDiagram";
67
68 private static final int TOP_MARGIN = 10;
69 private static final int LEFT_MARGIN = 10;
70 private static final int COLUMN_WIDTH = 135;
71
72 private MNamespace namespace;
73 private MockObjectMap mockObjectMap;
74 private DocumentBuilder builder;
75
76 private Map<MObject, FigObject> figObjectMap =
77 new HashMap<MObject, FigObject>();
78 private List<Fig> figObjects = new LinkedList<Fig>();
79 private List<Fig> figLinks = new LinkedList<Fig>();
80 private List<Fig> figStimuli = new LinkedList<Fig>();
81 private int nextFigNumber = 0;
82 private int nextPortNumber = 0;
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 public SequenceDiagram(MNamespace namespace, Activation activation)
98 throws ParserConfigurationException {
99 this.namespace = namespace;
100 this.mockObjectMap = MockObjectMap.addAll(activation);
101
102 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
103 this.builder = factory.newDocumentBuilder();
104 }
105
106
107
108
109
110
111 public Document getDocument() {
112 DOMImplementation impl = builder.getDOMImplementation();
113 DocumentType docType =
114 impl.createDocumentType("pgml", PGML_PUBLIC_ID, PGML_SYSTEM_ID);
115 Document doc = impl.createDocument(PGML_NAMESPACE, "pgml", docType);
116 Element root = doc.getDocumentElement();
117 root.setAttribute("description", getRootDescription());
118 addFigs(doc, figObjects);
119 addFigs(doc, figStimuli);
120 addFigs(doc, figLinks);
121 return doc;
122 }
123
124 private void addFigs(Document doc, List<Fig> figs) {
125 for (Fig fig : figs) {
126 doc.getDocumentElement().appendChild(fig.getXML(doc));
127 }
128 }
129
130 private String getRootDescription() {
131 return UML_SEQUENCE_DIAGRAM_CLASS + "|" + namespace.getUUID();
132 }
133
134
135
136
137
138
139
140 public void addObject(MObject object) {
141 FigObject figObject = createEmptyFigObject(object);
142 figObjects.add(figObject);
143 figObjectMap.put(object, figObject);
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 @SuppressWarnings("unchecked")
160 public void addCall(MObject sender, MObject receiver, MLink link) {
161 FigObject figSender = figObjectMap.get(sender);
162 FigObject figReceiver = figObjectMap.get(receiver);
163
164 String sourcePortFig = figSender.addPort(nextPortNumber);
165 if (!figSender.isActive()) {
166 activate(sender);
167 }
168 String destPortFig = figReceiver.addPort(nextPortNumber);
169 activate(receiver);
170 nextPortNumber++;
171 String sourceFigNode = figSender.getName();
172 String destFigNode = figReceiver.getName();
173
174 for (Iterator i = link.getStimuli().iterator(); i.hasNext();) {
175 MStimulus stimulus = (MStimulus) i.next();
176 MAction action = stimulus.getDispatchAction();
177 FigStimulus figStimulus =
178 createFigStimulus(stimulus, action.getName());
179 figStimuli.add(figStimulus);
180 }
181 FigLink figLink =
182 createFigLink(link, sourcePortFig, destPortFig, sourceFigNode,
183 destFigNode);
184 figLinks.add(figLink);
185 }
186
187
188
189
190
191
192
193
194
195 private void activate(MObject object) {
196 FigObject figObject = figObjectMap.get(object);
197 figObject.activate(nextPortNumber);
198 }
199
200
201
202
203
204
205
206
207
208 public void deactivate(MObject object) {
209 FigObject figObject = figObjectMap.get(object);
210 figObject.deactivate(nextPortNumber - 1);
211 }
212
213 private FigObject createEmptyFigObject(MObject object) {
214 int column = getColumn(object);
215 FigObject fig =
216 new FigObject(getNextFigName(), getName(object), object
217 .getUUID(), LEFT_MARGIN, TOP_MARGIN + column *
218 COLUMN_WIDTH);
219 return fig;
220 }
221
222 private FigStimulus createFigStimulus(MStimulus stimulus, String name) {
223 FigStimulus fig =
224 new FigStimulus(getNextFigName(), name, stimulus.getUUID());
225 return fig;
226 }
227
228 private FigLink createFigLink(MLink link, String sourcePortFig,
229 String destPortFig, String sourceFigNode, String destFigNode) {
230 FigLink fig =
231 new FigLink(getNextFigName(), link.getUUID(), LEFT_MARGIN,
232 TOP_MARGIN, sourcePortFig, destPortFig, sourceFigNode,
233 destFigNode);
234 return fig;
235 }
236
237 private int getColumn(MObject object) {
238 MClass cls = getClass(object);
239 MockObject mockObject = mockObjectMap.get(cls.getName());
240 if (mockObject == null) {
241 throw new IllegalArgumentException("Object not found " + object);
242 }
243 return mockObject.getColumn();
244 }
245
246 private String getName(MObject object) {
247 MClass cls = getClass(object);
248 return object.getName() + " : " + cls.getName();
249 }
250
251
252 @SuppressWarnings("unchecked")
253 private MClass getClass(MObject object) {
254 MClass cls = null;
255 for (Iterator i = object.getClassifiers().iterator(); i.hasNext();) {
256 MClassifier classifier = (MClassifier) i.next();
257 if (classifier instanceof MClass) {
258 cls = (MClass) classifier;
259 break;
260 }
261 }
262 if (cls == null) {
263 throw new IllegalArgumentException("No class found for " + object);
264 }
265 return cls;
266 }
267
268 private String getNextFigName() {
269 return "Fig" + nextFigNumber++;
270 }
271 }