1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 /***
19 * <p>Title: WSMO Studio</p>
20 * <p>Description: Semantic Web Service Editor</p>
21 * <p>Copyright: Copyright (c) 2004-2007</p>
22 * <p>Company: Ontotext Lab. / SIRMA </p>
23 */
24
25 package org.wsmostudio.bpmo.model.connectors;
26
27 import java.beans.PropertyChangeListener;
28 import java.beans.PropertyChangeSupport;
29 import java.util.*;
30
31 import org.eclipse.draw2d.Bendpoint;
32 import org.eclipse.draw2d.Graphics;
33 import org.eclipse.jface.dialogs.InputDialog;
34 import org.eclipse.jface.resource.JFaceResources;
35 import org.eclipse.jface.window.Window;
36 import org.eclipse.swt.widgets.Display;
37 import org.wsmo.common.IRI;
38 import org.wsmostudio.bpmo.model.*;
39 import org.wsmostudio.runtime.WSMORuntime;
40 import org.wsmostudio.runtime.WsmoImageRegistry;
41 import org.wsmostudio.ui.IdentifierInputDialog;
42
43 public abstract class GraphConnector {
44
45 public static final Integer SOLID_CONNECTION = new Integer(Graphics.LINE_SOLID);
46 public static final Integer DASHED_CONNECTION = new Integer(Graphics.LINE_DASHDOT);
47 public static final Integer DOT_CONNECTION = new Integer(Graphics.LINE_DOT);
48
49
50 /*** Property ID to use when the line style of this connection is modified. */
51 public static final String LINESTYLE_PROP = "LineStyle";
52 private static final long serialVersionUID = 1;
53
54 private transient PropertyChangeSupport pcsDelegate = new PropertyChangeSupport(this);
55
56 /*** True, if the connection is attached to its endpoints. */
57 private boolean isConnected;
58 /*** Line drawing style for this connection. */
59 private int lineStyle = Graphics.LINE_SOLID;
60
61 private WorkflowEntityNode source;
62 private WorkflowEntityNode target;
63
64 protected WorkflowProperty nameProp =
65 new WorkflowProperty(Consts.PROP_CONDITION,
66 JFaceResources.getImage(WsmoImageRegistry.DATA_VALUE_ICON),
67 new String[] {Consts.ACTION_SET_LABEL}, false,
68 WorkflowProperty.defaultValueEditOrRemovePolicies);
69
70 protected WorkflowProperty identifierProp = new WorkflowProperty(Consts.PROP_ID,
71 JFaceResources.getImage(WsmoImageRegistry.IRI_ICON),
72 new String[] {Consts.ACTION_CHANGE_ID}, false,
73 new String[] {Consts.ACTION_CHANGE_ID});
74
75 public String getLabel() {
76 return (String)this.nameProp.getSingleValue();
77 }
78
79 public void setLabel(String lab) {
80
81 String oldLab = getLabel();
82 this.nameProp.addValue(lab);
83 firePropertyChange("name", oldLab, lab);
84 }
85
86 public IRI getIdentifier() {
87 return (IRI)this.identifierProp.getSingleValue();
88 }
89
90 public void setIdentifier(IRI id) {
91 this.identifierProp.addValue(id);
92 }
93
94
95 protected String m_sourceTerminal = "";
96 protected String m_targetTerminal = "";
97
98 public void setSourceTerminal(String s){
99 m_sourceTerminal = s;
100 }
101 public void setTargetTerminal(String s){
102 m_targetTerminal = s;
103 }
104 public String getSourceTerminal() {
105 return m_sourceTerminal;
106 }
107 public String getTargetTerminal() {
108 return m_targetTerminal;
109 }
110
111
112 /***
113 * Create a (solid) connection between two distinct shapes.
114 * @param source a source endpoint for this connection (non null)
115 * @param target a target endpoint for this connection (non null)
116 * @throws IllegalArgumentException if any of the parameters are null or source == target
117 * @see #setLineStyle(int)
118 */
119 public GraphConnector(WorkflowEntityNode source,
120 String sourceTerminal,
121 WorkflowEntityNode target,
122 String targetTerminal) {
123 super();
124 if (sourceTerminal != null) {
125 setSourceTerminal(sourceTerminal);
126 }
127 if (targetTerminal != null) {
128 setTargetTerminal(targetTerminal);
129 }
130 reconnect(source, target);
131 }
132
133 /***
134 * Disconnect this connection from the shapes it is attached to.
135 */
136 public void disconnect() {
137 if (isConnected) {
138 source.removeOutConnection(this);
139 target.removeInConnection(this);
140 isConnected = false;
141 firePropertyChange("", null, null);
142 }
143 }
144
145
146 /***
147 * Attach a non-null PropertyChangeListener to this object.
148 * @param l a non-null PropertyChangeListener instance
149 * @throws IllegalArgumentException if the parameter is null
150 */
151 public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
152 if (l == null) {
153 throw new IllegalArgumentException();
154 }
155 pcsDelegate.addPropertyChangeListener(l);
156 }
157
158 /***
159 * Report a property change to registered listeners (for example edit parts).
160 * @param property the programmatic name of the property that changed
161 * @param oldValue the old value of this property
162 * @param newValue the new value of this property
163 */
164 protected void firePropertyChange(String property, Object oldValue, Object newValue) {
165 if (pcsDelegate.hasListeners(property)) {
166 pcsDelegate.firePropertyChange(property, oldValue, newValue);
167 }
168 }
169
170 /***
171 * Remove a PropertyChangeListener from this component.
172 * @param l a PropertyChangeListener instance
173 */
174 public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
175 if (l != null) {
176 pcsDelegate.removePropertyChangeListener(l);
177 }
178 }
179
180 public void notifyContentChanged() {
181 if (this.source != null) {
182 this.source.notifyContentChanged();
183 }
184 else if (this.target != null) {
185 this.target.notifyContentChanged();
186 }
187 }
188
189 public int getLineStyle() {
190 return lineStyle;
191 }
192
193 public List<WorkflowProperty> listSupportedProperties() {
194 return new LinkedList<WorkflowProperty>();
195 }
196
197
198 public boolean handleAction(String actionID, WorkflowProperty prop, Object value) {
199 if (actionID.equals(Consts.ACTION_CHANGE_ID)) {
200 IdentifierInputDialog idDialog = new IdentifierInputDialog(
201 Display.getCurrent().getActiveShell(),
202 "Edit Identifier",
203 "IRI",
204 (getIdentifier() == null) ? "" : getIdentifier().toString(),
205 getSource().getTopContainer().getNSHolder(),
206 WSMORuntime.getRuntime().getWsmoFactory(),
207 false);
208 if (idDialog.open() != Window.OK) {
209 return false;
210 }
211 IRI newID = (IRI)idDialog.getIdentifier();
212 if (false == newID.equals(getIdentifier())) {
213 setIdentifier(newID);
214 return true;
215 }
216 }
217 if (actionID.equals(Consts.ACTION_SET_LABEL)) {
218 InputDialog dialog = new InputDialog(
219 Display.getCurrent().getActiveShell(),
220 "New Connection Condition",
221 "Expression : ",
222 this.getLabel(),
223 null);
224 if (dialog.open() != Window.OK) {
225 return false;
226 }
227 String newName = dialog.getValue();
228 if (newName == null
229 || newName.trim().length() == 0) {
230 if (this.getLabel() != null) {
231 prop.removeValue(this.getLabel());
232 firePropertyChange("name", null, newName);
233 return true;
234 }
235 }
236 else {
237 prop.addValue(newName);
238 firePropertyChange("name", null, newName);
239 return true;
240 }
241 }
242 if (actionID.equals("Edit")) {
243 InputDialog dialog = new InputDialog(
244 Display.getCurrent().getActiveShell(),
245 "New Connection Condition",
246 prop.toString() + " : ",
247 (String)value,
248 null);
249 if (dialog.open() != Window.OK) {
250 return false;
251 }
252 String newValue = dialog.getValue();
253 if (newValue == null
254 || newValue.trim().length() == 0) {
255 prop.removeValue(this.getLabel());
256 firePropertyChange("name", null, newValue);
257 return true;
258 }
259 else {
260 prop.addValue(newValue);
261 firePropertyChange("name", null, newValue);
262 return true;
263 }
264 }
265 if (actionID.equals("Remove")) {
266 prop.removeValue(value);
267 firePropertyChange("name", value, null);
268 return true;
269 }
270
271
272 return false;
273 }
274
275 /***
276 * Returns the source endpoint of this connection.
277 * @return a non-null Shape instance
278 */
279 public WorkflowEntityNode getSource() {
280 return source;
281 }
282
283 /***
284 * Returns the target endpoint of this connection.
285 * @return a non-null Shape instance
286 */
287 public WorkflowEntityNode getTarget() {
288 return target;
289 }
290
291 /***
292 * Reconnect this connection.
293 * The connection will reconnect with the shapes it was previously attached to.
294 */
295 public void reconnect() {
296 if (!isConnected) {
297 target.addInConnection(this);
298 source.addOutConnection(this);
299 isConnected = true;
300 firePropertyChange("", null, null);
301 }
302 }
303
304 /***
305 * Reconnect to a different source and/or target shape.
306 * The connection will disconnect from its current attachments and reconnect to
307 * the new source and target.
308 * @param newSource a new source endpoint for this connection (non null)
309 * @param newTarget a new target endpoint for this connection (non null)
310 * @throws IllegalArgumentException if any of the paramers are null or newSource == newTarget
311 */
312 public void reconnect(WorkflowEntityNode newSource, WorkflowEntityNode newTarget) {
313 if (newSource == null || newTarget == null || newSource == newTarget) {
314 throw new IllegalArgumentException();
315 }
316 WorkflowEntityNode oldSource = this.source;
317 disconnect();
318 this.source = newSource;
319 this.target = newTarget;
320 if (this instanceof ControlflowArc
321 && false == newSource.equals(oldSource)
322 && ((ControlflowArc)this).isDefaultBranch()) {
323 ((ControlflowArc)this).setDefaultBranch(false);
324 }
325 reconnect();
326 }
327
328 /***
329 * Set the line drawing style of this connection.
330 * @param lineStyle one of following values: Graphics.LINE_DASH or Graphics.LINE_SOLID
331 * @see Graphics#LINE_DASH
332 * @see Graphics#LINE_SOLID
333 * @throws IllegalArgumentException if lineStyle does not have one of the above values
334 */
335 public void setLineStyle(int lineStyle) {
336 this.lineStyle = lineStyle;
337 firePropertyChange(LINESTYLE_PROP, null, new Integer(this.lineStyle));
338 }
339
340
341 /*** List of bendpoint model object associated with current connection model object. */
342 protected List<Bendpoint> bendpoints = new ArrayList<Bendpoint>();
343
344 /*** Returns the list of bendpoints model objects. */
345 public List<Bendpoint> getBendpoints() {
346 return bendpoints;
347 }
348
349 public void insertBendpoint(int index, Bendpoint point) {
350 getBendpoints().add(index, point);
351 firePropertyChange("bendpoint", null, null);
352 }
353
354 /***
355 * Removes a bendpoint.
356 **/
357 public void removeBendpoint(int index) {
358 getBendpoints().remove(index);
359 firePropertyChange("bendpoint", null, null);
360 }
361
362 /***
363 * Sets another location for an existing bendpoint.
364 **/
365 public void setBendpoint(int index, Bendpoint point)
366 {
367 getBendpoints().set(index, point);
368 firePropertyChange("bendpoint", null, null);
369 }
370
371 public void cloneProperties(GraphConnector conn) {
372 conn.setSourceTerminal(getSourceTerminal());
373 conn.setTargetTerminal(getTargetTerminal());
374 conn.setLineStyle(getLineStyle());
375 if (getLabel() != null) {
376 conn.setLabel(getLabel());
377 }
378 }
379
380 public String toString() {
381 return source + " => " + target;
382 }
383
384 }
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418