001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.bpel.design.selection;
021:
022: import java.awt.Color;
023: import java.awt.Graphics2D;
024: import java.awt.Point;
025: import java.awt.Shape;
026: import java.awt.geom.Ellipse2D;
027: import org.netbeans.modules.bpel.design.geometry.FPath;
028: import org.netbeans.modules.bpel.design.geometry.FPoint;
029: import org.netbeans.modules.bpel.design.model.connections.Connection;
030: import org.netbeans.modules.bpel.design.model.elements.InvokeOperationElement;
031: import org.netbeans.modules.bpel.design.model.elements.OperationElement;
032: import org.netbeans.modules.bpel.design.model.elements.ReceiveOperationElement;
033:
034: import org.netbeans.modules.bpel.model.api.BpelEntity;
035: import org.netbeans.modules.bpel.model.api.Invoke;
036: import org.netbeans.modules.bpel.model.api.OperationReference;
037: import org.netbeans.modules.bpel.model.api.PartnerLink;
038: import org.netbeans.modules.bpel.model.api.PartnerLinkReference;
039: import org.netbeans.modules.bpel.model.api.PortTypeReference;
040: import org.netbeans.modules.bpel.model.api.Reply;
041: import org.netbeans.modules.bpel.design.DesignView;
042: import org.netbeans.modules.bpel.design.GUtils;
043: import org.netbeans.modules.bpel.design.decoration.components.LinkToolButton;
044: import org.netbeans.modules.bpel.design.model.connections.Direction;
045: import org.netbeans.modules.bpel.design.model.elements.VisualElement;
046: import org.netbeans.modules.bpel.design.model.patterns.PartnerlinkPattern;
047: import org.netbeans.modules.bpel.model.api.OnEvent;
048: import org.netbeans.modules.bpel.model.api.OnMessage;
049: import org.netbeans.modules.bpel.model.api.Receive;
050: import org.netbeans.modules.bpel.model.api.references.BpelReference;
051: import org.netbeans.modules.bpel.model.api.references.ReferenceCollection;
052: import org.netbeans.modules.bpel.model.api.references.WSDLReference;
053: import org.netbeans.modules.xml.wsdl.model.Operation;
054: import org.netbeans.modules.xml.wsdl.model.PortType;
055:
056: public class FlowlinkTool implements DnDTool {
057:
058: private VisualElement startElement;
059: private VisualElement endElement;
060:
061: private static final int INPUT = 1;
062: private static final int OUTPUT = 2;
063: private static final int INPUT_OUTOUT = INPUT | OUTPUT;
064:
065: private DesignView designView;
066:
067: private double startX;
068: private double startY;
069:
070: private double currentX;
071: private double currentY;
072:
073: private LinkToolButton button;
074:
075: public FlowlinkTool(DesignView designView) {
076: this .designView = designView;
077: }
078:
079: public DesignView getDesignView() {
080: return designView;
081: }
082:
083: public void init(LinkToolButton btn) {
084: this .button = btn;
085: VisualElement e = btn.getPattern().getFirstElement();
086:
087: // DND can start only from operation element
088: // or fromdiagram element involved into messageflow
089: if ((e == null) || (!isOperation(e) && !isTask(e)))
090: return;
091:
092: startElement = e;
093:
094: if (isTask(e)) {
095:
096: startX = e.getX();
097: startY = e.getCenterY();
098:
099: } else {
100: startX = e.getX() + e.getWidth();
101: startY = e.getCenterY();
102: }
103:
104: getDesignView().getDecorationManager().decorationChanged();
105: }
106:
107: private void move() {
108: Point p = getDesignView().getOverlayView().getMousePosition();
109: if (p != null) {
110: FPoint fp = getDesignView().convertScreenToDiagram(p);
111: moveImpl(fp.x, fp.y);
112: }
113: }
114:
115: public boolean isValidLocation() {
116: return endElement != null;
117: }
118:
119: public void move(FPoint p) {
120: moveImpl(p.x, p.y);
121:
122: //button.setPosition(getDesignView().convertDiagramToScreen(p));
123:
124: getDesignView().repaint();
125: }
126:
127: private void moveImpl(double x, double y) {
128: if (!isActive())
129: return;
130: currentX = x;
131: currentY = y;
132:
133: VisualElement e = null;//getDesignView().findElement(x, y);
134:
135: endElement = (e != null && isValidLinkTo(e)) ? e : null;
136:
137: }
138:
139: public void drop(FPoint p) {
140: drop(p.x, p.y);
141: }
142:
143: public void drop(double x, double y) {
144: if (!isActive())
145: return;
146:
147: moveImpl(x, y);
148:
149: if (endElement != null && (isValidLinkTo(endElement))) {
150: VisualElement operation = isOperation(startElement) ? startElement
151: : endElement;
152: if (operation != null) {
153: VisualElement task = isOperation(startElement) ? endElement
154: : startElement;
155:
156: PartnerlinkPattern pattern = (PartnerlinkPattern) operation
157: .getPattern();
158:
159: BpelEntity activity = (BpelEntity) task.getPattern()
160: .getOMReference();
161:
162: BpelReference<PartnerLink> pl_ref = ((ReferenceCollection) activity)
163: .createReference((PartnerLink) pattern
164: .getOMReference(), PartnerLink.class);
165:
166: if (pl_ref != null) {
167: ((PartnerLinkReference) activity)
168: .setPartnerLink(pl_ref);
169: }
170:
171: Operation op = pattern.getOperation(operation);
172:
173: if (op != null) {
174: WSDLReference<Operation> op_ref = ((ReferenceCollection) activity)
175: .createWSDLReference(op, Operation.class);
176:
177: if (op_ref != null) {
178: ((OperationReference) activity)
179: .setOperation(op_ref);
180: }
181: PortType pt = (PortType) op.getParent();
182: if (pt != null) {
183: WSDLReference<PortType> pt_ref = ((ReferenceCollection) activity)
184: .createWSDLReference(pt, PortType.class);
185:
186: if (pt_ref != null) {
187: ((PortTypeReference) activity)
188: .setPortType(pt_ref);
189: } else {
190: ((PortTypeReference) activity)
191: .removePortType();
192: }
193:
194: }
195: }
196: }
197: }
198: clear();
199: }
200:
201: public void clear() {
202: startElement = null;
203: endElement = null;
204:
205: if (button != null) {
206: BpelEntity be = button.getPattern().getOMReference();
207: if (be != null) {
208: getDesignView().getDecorationManager()
209: .decorationChanged();
210: }
211: }
212:
213: //FIXME designView.getDecorationManager().repositionComponentsRecursive();
214: getDesignView().repaint();
215: }
216:
217: public boolean isActive() {
218: return (startElement != null);
219: }
220:
221: private boolean isValidLinkTo(VisualElement to) {
222: if (to == null) {
223: return false;
224: } else if (to == startElement) {
225: return false;
226: }
227: if ((isOperation(to) && isTask(startElement))
228: || (isOperation(startElement) && isTask(to))) {
229: return ((getDirections(to) | getDirections(startElement)) == (INPUT | OUTPUT));
230: }
231: return false;
232: }
233:
234: private int getDirections(VisualElement e) {
235: BpelEntity ref = (BpelEntity) e.getPattern().getOMReference();
236: if (e instanceof ReceiveOperationElement) {
237: return INPUT;
238: } else if (e instanceof InvokeOperationElement) {
239: return INPUT | OUTPUT;
240: } else if (isTask(ref)) {
241: if (ref instanceof Reply) {
242: return OUTPUT;
243: } else if (ref instanceof Invoke) {
244: return OUTPUT;
245: } else {
246: return INPUT;
247: }
248: }
249:
250: return 0;
251: }
252:
253: private boolean isOperation(VisualElement e) {
254: return e instanceof OperationElement;
255: }
256:
257: private boolean isSendTask(VisualElement e) {
258: Object o = e.getPattern().getOMReference();
259: return (o instanceof Invoke) || (o instanceof Reply);
260: }
261:
262: private boolean isTask(VisualElement e) {
263: return isTask((BpelEntity) e.getPattern().getOMReference());
264: }
265:
266: private boolean isTask(BpelEntity o) {
267: return (o instanceof OperationReference)
268: && (o instanceof PartnerLinkReference)
269: && (o instanceof PortTypeReference);
270: }
271:
272: public void paint(Graphics2D g2) {
273: if (!isActive())
274: return;
275: // if (getDesignView().getModel().isReadOnly()) return; //127263
276:
277: move();
278:
279: double x1, y1, x2, y2;
280:
281: if (isValidLocation()) {
282: x1 = startElement.getCenterX();
283: y1 = startElement.getCenterY();
284:
285: x2 = endElement.getCenterX();
286: y2 = endElement.getCenterY();
287:
288: double w1 = startElement.getWidth() / 2;
289: double w2 = endElement.getWidth() / 2;
290:
291: if (x1 <= x2) {
292: x1 += w1;
293: x2 -= w2;
294: } else {
295: x1 -= w1;
296: x2 += w2;
297: }
298: } else {
299: x1 = startX;
300: y1 = startY;
301:
302: x2 = currentX;
303: y2 = currentY;
304: }
305:
306: FPath path = createPath(x1, y1, x2, y2, !isForwardDirection());
307:
308: if (path != null) {
309: // GUtils.setSolidStroke(g2, 8);
310: // GUtils.setPaint(g2, new Color(0x88FFFFFF, true));
311: // GUtils.draw(g2, GUtils.convert(path), true);
312: Connection.paintConnection(g2, path, true, true, false,
313: true, (isValidLocation()) ? null : Color.RED);
314: }
315:
316: Graphics2D buttonGraphics = (Graphics2D) g2.create();
317:
318: double scale = GUtils.getScale(buttonGraphics.getTransform());
319:
320: buttonGraphics.translate(currentX, currentY);
321: buttonGraphics.scale(1 / scale, 1 / scale);
322: buttonGraphics.translate(-button.getWidth() / 2, -button
323: .getHeight() / 2);
324: button.paint(buttonGraphics);
325: buttonGraphics.dispose();
326: }
327:
328: private boolean isForwardDirection() {
329: BpelEntity omRef = startElement.getPattern().getOMReference();
330:
331: if (omRef == null)
332: return true;
333:
334: if (omRef instanceof OnMessage || omRef instanceof OnEvent
335: || omRef instanceof Receive) {
336:
337: return false;
338: } else if (omRef instanceof Invoke || omRef instanceof Reply) {
339: return true;
340: }
341:
342: return true;
343: }
344:
345: private FPath createPath(double x1, double y1, double x2,
346: double y2, boolean invert) {
347:
348: if (invert) {
349: double t = x1;
350: x1 = x2;
351: x2 = t;
352:
353: t = y1;
354: y1 = y2;
355: y2 = t;
356: }
357:
358: boolean nonZeroDX = x1 != x2;
359: boolean nonZeroDY = y1 != y2;
360:
361: if (nonZeroDX && nonZeroDY) {
362: double cx = (x1 + x2) / 2;
363: return new FPath(x1, y1, cx, y1, cx, y2, x2, y2).round(2);
364: } else if (nonZeroDX || nonZeroDY) {
365: return new FPath(x1, y1, x2, y2);
366: }
367:
368: return null;
369: }
370:
371: public Point getPosition() {
372: return designView.convertDiagramToScreen(new FPoint(currentX,
373: currentY));
374: }
375:
376: // Rendering constants
377: private static final Shape END_MARKER_SHAPE = new Ellipse2D.Float(
378: -2, -2, 4, 4);
379:
380: private static final Color ACCEPT_FILL_COLOR = new Color(0x00A000);
381: private static final Color ACCEPT_STROKE_COLOR = new Color(0x20A020);
382: private static final Color DECLINE_FILL_COLOR = new Color(0xA00000);
383: private static final Color DECLINE_STROKE_COLOR = new Color(
384: 0xA02020);
385: private static final Color COLOR = new Color(0xE68B2C);
386: }
|