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.model.patterns;
021:
022: import java.awt.geom.Area;
023: import java.util.ArrayList;
024: import java.util.Collection;
025: import java.util.List;
026: import org.netbeans.modules.bpel.design.geometry.FBounds;
027: import org.netbeans.modules.bpel.design.model.elements.BorderElement;
028: import org.netbeans.modules.bpel.editors.api.nodes.NodeType;
029: import org.netbeans.modules.bpel.design.selection.PlaceHolder;
030: import org.netbeans.modules.bpel.model.api.Activity;
031: import org.netbeans.modules.bpel.model.api.BpelEntity;
032: import org.netbeans.modules.bpel.model.api.Else;
033: import org.netbeans.modules.bpel.model.api.ElseIf;
034: import org.netbeans.modules.bpel.model.api.ExtendableActivity;
035: import org.netbeans.modules.bpel.model.api.If;
036: import org.netbeans.modules.bpel.design.geometry.FDimension;
037: import org.netbeans.modules.bpel.design.geometry.FPath;
038: import org.netbeans.modules.bpel.design.geometry.FPoint;
039: import org.netbeans.modules.bpel.design.geometry.FRectangle;
040: import org.netbeans.modules.bpel.design.layout.LayoutManager;
041: import org.netbeans.modules.bpel.design.model.DiagramModel;
042: import org.netbeans.modules.bpel.design.model.connections.Connection;
043: import org.netbeans.modules.bpel.design.model.connections.ConnectionManager;
044: import org.netbeans.modules.bpel.design.model.connections.Direction;
045: import org.netbeans.modules.bpel.design.model.elements.ContentElement;
046: import org.netbeans.modules.bpel.design.model.elements.GroupBorder;
047: import org.netbeans.modules.bpel.design.model.elements.PlaceHolderElement;
048: import org.netbeans.modules.bpel.design.model.elements.StubElement;
049: import org.netbeans.modules.bpel.design.model.elements.VisualElement;
050: import org.netbeans.modules.bpel.model.api.BooleanExpr;
051:
052: public class IfPattern extends CompositePattern {
053:
054: private VisualElement forkGateway;
055: private VisualElement mergeGateway;
056: private PlaceHolderElement thenPlaceHolder;
057: private StubElement elseStub;
058:
059: private List<Connection> connectionsFork = new ArrayList<Connection>();
060: private List<Connection> connectionsMerge = new ArrayList<Connection>();
061:
062: public IfPattern(DiagramModel model) {
063: super (model);
064: }
065:
066: protected void onAppendPattern(Pattern nestedPattern) {
067: BpelEntity entity = nestedPattern.getOMReference();
068:
069: if (entity instanceof Else) {
070: removeElement(elseStub);
071: } else if (!(entity instanceof ElseIf)) {
072: removeElement(thenPlaceHolder);
073: }
074: }
075:
076: protected void onRemovePattern(Pattern nestedPattern) {
077: If ifOM = (If) getOMReference();
078:
079: if (!elseStub.hasPattern() && (ifOM.getElse() == null)) {
080: appendElement(elseStub);
081: } else if (!thenPlaceHolder.hasPattern()
082: && (ifOM.getActivity() == null)) {
083: appendElement(thenPlaceHolder);
084: }
085: }
086:
087: public VisualElement getFirstElement() {
088: return forkGateway;
089: }
090:
091: public VisualElement getLastElement() {
092: return mergeGateway;
093: }
094:
095: public FBounds layoutPattern(LayoutManager manager) {
096: If ifActivity = (If) getOMReference();
097: BpelEntity thenBranch = ifActivity.getActivity();
098: Else elseBranch = ifActivity.getElse();
099: ElseIf[] elseIfBranches = ifActivity.getElseIfs();
100: int elseIfCount = (elseIfBranches == null) ? 0
101: : elseIfBranches.length;
102:
103: forkGateway.setCenter(0, 0);
104:
105: double y0 = -forkGateway.getHeight() / 2; // - (elseIfCount > 0) ? 8 : 0; //TODO: Replace with constant
106: double y1 = forkGateway.getHeight() / 2
107: + LayoutManager.VSPACING;
108: //+ ((elseIfCount > 0) ? 8 : 0);
109: double x0, x1, x2, y2;
110:
111: if (thenBranch != null) {
112: Pattern p = getNestedPattern(thenBranch);
113: FBounds size = p.getBounds();
114: FPoint offset = manager.getOriginOffset(p);
115: x1 = -offset.x;
116: x2 = x1 + size.width;
117: y2 = y1 + size.height;
118: manager.setPatternPosition(p, x1, y1);
119: } else {
120: double width = thenPlaceHolder.getWidth();
121: double height = thenPlaceHolder.getHeight();
122: x1 = -width / 2;
123: x2 = x1 + width;
124: y2 = y1 + height;
125: thenPlaceHolder.setLocation(x1, y1);
126: }
127: x0 = Math.min(-forkGateway.getWidth() / 2, x1);
128: x2 = Math.max(x2, forkGateway.getWidth() / 2)
129: + LayoutManager.HSPACING;
130:
131: for (int i = 0; i < elseIfCount; i++) {
132: Pattern p = getNestedPattern(elseIfBranches[i]);
133: FBounds size = p.getBounds();
134: manager.setPatternPosition(p, x2, y0);
135:
136: y2 = Math.max(y2, y0 + size.height);
137: x2 += size.width;
138: x2 += LayoutManager.HSPACING;
139: }
140:
141: if (elseBranch != null) {
142: Pattern p = getNestedPattern(elseBranch);
143: FBounds size = p.getBounds();
144: manager.setPatternPosition(p, x2, y1);
145: y2 = Math.max(y2, y1 + size.height);
146: x2 += size.width;
147: } else {
148: double width = elseStub.getWidth();
149: double height = elseStub.getHeight();
150: elseStub.setLocation(x2, y1 + thenPlaceHolder.getHeight()
151: / 2);
152: y2 = Math.max(y2, y1 + height + thenPlaceHolder.getHeight()
153: / 2);
154: x2 += width;
155: }
156:
157: y2 += LayoutManager.VSPACING;
158:
159: mergeGateway.setCenter(0, y2 + mergeGateway.getHeight() / 2);
160:
161: y2 += mergeGateway.getHeight();
162: getBorder().setClientRectangle(x0, y0, x2 - x0, y2 - y0);
163:
164: return getBorder().getBounds();
165: }
166:
167: protected void createElementsImpl() {
168: setBorder(new GroupBorder());
169: registerTextElement(getBorder());
170:
171: mergeGateway = ContentElement.createIfGateway();
172: forkGateway = ContentElement.createIfGateway();
173:
174: appendElement(mergeGateway);
175: appendElement(forkGateway);
176:
177: thenPlaceHolder = new PlaceHolderElement();
178: elseStub = new StubElement();
179:
180: appendElement(thenPlaceHolder);
181: appendElement(elseStub);
182:
183: If ifActivity = (If) getOMReference();
184: BpelEntity thenBranch = ifActivity.getActivity();
185: Else elseBranch = ifActivity.getElse();
186: ElseIf[] elseIfBranches = ifActivity.getElseIfs();
187: int elseIfCount = (elseIfBranches == null) ? 0
188: : elseIfBranches.length;
189:
190: if (thenBranch != null) {
191: getModel().createPattern(thenBranch).setParent(this );
192: }
193:
194: for (int i = 0; i < elseIfCount; i++) {
195: getModel().createPattern(elseIfBranches[i]).setParent(this );
196: }
197:
198: if (elseBranch != null) {
199: getModel().createPattern(elseBranch).setParent(this );
200: }
201: }
202:
203: public void reconnectElements() {
204: If ifActivity = (If) getOMReference();
205: BpelEntity thenBranch = ifActivity.getActivity();
206: Else elseBranch = ifActivity.getElse();
207: ElseIf[] elseIfBranches = ifActivity.getElseIfs();
208:
209: ensureConnectionsCount(connectionsFork, 0);
210: ensureConnectionsCount(connectionsMerge, 0);
211:
212: VisualElement thenFirst;
213: VisualElement thenLast;
214: if (thenBranch != null) {
215: Pattern p = getNestedPattern(thenBranch);
216: thenFirst = p.getFirstElement();
217: thenLast = p.getLastElement();
218: } else {
219: thenFirst = thenPlaceHolder;
220: thenLast = thenPlaceHolder;
221: }
222:
223: VisualElement elseFirst;
224: VisualElement elseLast;
225: if (elseBranch != null) {
226: Pattern p = getNestedPattern(elseBranch);
227: elseFirst = p.getFirstElement();
228: elseLast = p.getLastElement();
229: } else {
230: elseFirst = elseStub;
231: elseLast = elseStub;
232: }
233:
234: int elseIfCount = (elseIfBranches == null) ? 0
235: : elseIfBranches.length;
236: VisualElement[] elseIfFirst = new VisualElement[elseIfCount];
237: VisualElement[] elseIfLast = new VisualElement[elseIfCount];
238: for (int i = 0; i < elseIfCount; i++) {
239: Pattern p = getNestedPattern(elseIfBranches[i]);
240: elseIfFirst[i] = p.getFirstElement();
241: elseIfLast[i] = p.getLastElement();
242: }
243:
244: Connection c1;
245: Connection c2;
246:
247: c1 = new Connection(this );
248: c2 = new Connection(this );
249: ConnectionManager.connectVerticaly(forkGateway, c1, thenFirst,
250: thenLast, c2, mergeGateway);
251: connectionsFork.add(c1);
252: connectionsMerge.add(c2);
253:
254: VisualElement prevFork = forkGateway;
255:
256: for (int i = 0; i < elseIfCount; i++) {
257: c1 = new Connection(this );
258: c2 = new Connection(this );
259: ConnectionManager.connectVerticaly(prevFork, c1,
260: elseIfFirst[i], elseIfLast[i], c2, mergeGateway);
261: c1.setTarget(c1.getTarget(), Direction.LEFT);
262: connectionsFork.add(c1);
263: connectionsMerge.add(c2);
264: c1.setPaintSlash(true);
265: prevFork = elseIfFirst[i];
266: }
267:
268: c1 = new Connection(this );
269: c2 = new Connection(this );
270: c1.setPaintSlash(true);
271: c1.setPaintArrow(elseFirst != elseStub);
272: ConnectionManager.connectVerticaly(prevFork, c1, elseFirst,
273: elseLast, c2, mergeGateway);
274: connectionsFork.add(c1);
275: connectionsMerge.add(c2);
276: }
277:
278: public String getDefaultName() {
279: return "If"; // NOI18N
280: }
281:
282: public NodeType getNodeType() {
283: return NodeType.IF;
284: }
285:
286: public Area createSelection() {
287: Area res = new Area(getBorder().getShape());
288: res.subtract(new Area(forkGateway.getShape()));
289: res.subtract(new Area(mergeGateway.getShape()));
290: return res;
291: }
292:
293: public void createPlaceholders(Pattern draggedPattern,
294: Collection<PlaceHolder> placeHolders) {
295: if (draggedPattern.getOMReference() instanceof Activity) {
296: If ifOM = (If) getOMReference();
297:
298: if (ifOM.getActivity() == null) {
299: placeHolders.add(new ThenActivityPlaceHolder(
300: draggedPattern));
301: }
302:
303: if (ifOM.getElse() == null) {
304: placeHolders.add(new ElsePlaceHolder(draggedPattern));
305: }
306: } else if (draggedPattern.getOMReference() instanceof ElseIf) {
307: ElseIf elseIf = (ElseIf) draggedPattern.getOMReference();
308:
309: if (elseIf.getParent() != getOMReference())
310: return;
311:
312: int elseIfIndex = ((If) getOMReference()).indexOf(
313: ElseIf.class, elseIf);
314:
315: int connectionsCount = connectionsFork.size();
316:
317: FPoint center;
318:
319: if (!forkGateway.getIncomingConnections().isEmpty()) {
320: FPath inp = forkGateway.getIncomingConnections().get(0)
321: .getPath();
322: double inpLength = inp.length();
323: center = inp.point(Math.max(0.5f, (inpLength - 4)
324: / inpLength));
325: } else {
326: center = new FPoint(forkGateway.getCenterX(),
327: forkGateway.getY() - 4);
328: }
329:
330: placeHolders.add(new ElseIfReorderingPlaceHolder(
331: draggedPattern, center.x, center.y, 0));
332:
333: if ((connectionsCount > 2) && (elseIfIndex != 0)) {
334: Connection c = connectionsFork.get(1);
335: FPath path = c.getPath();
336:
337: path = path.subtract(((ElseIfPattern) c.getTarget()
338: .getPattern()).getBorder().getShape());
339:
340: placeHolders.add(new ElseIfReorderingPlaceHolder(
341: draggedPattern, path, 1));
342: }
343:
344: for (int i = 2; i < connectionsCount - 1; i++) {
345: if ((elseIfIndex + 1 == i) || (elseIfIndex + 2 == i)) {
346: continue;
347: }
348:
349: Connection c = connectionsFork.get(i);
350:
351: FPath path = c.getPath();
352:
353: path = path.subtract(((ElseIfPattern) c.getSource()
354: .getPattern()).getBorder().getShape());
355: path = path.subtract(((ElseIfPattern) c.getTarget()
356: .getPattern()).getBorder().getShape());
357:
358: placeHolders.add(new ElseIfReorderingPlaceHolder(
359: draggedPattern, path, i));
360: }
361:
362: if ((connectionsCount > 1)
363: && (elseIfIndex + 1 != connectionsCount - 1)
364: && (elseIfIndex + 2 != connectionsCount - 1)) {
365: Connection c = connectionsFork
366: .get(connectionsCount - 1);
367:
368: FPath path = c.getPath();
369:
370: for (Pattern p = c.getTarget().getPattern(); p != this ; p = p
371: .getParent()) {
372: if (!(p instanceof CompositePattern)) {
373: continue;
374: }
375:
376: BorderElement border = ((CompositePattern) p)
377: .getBorder();
378:
379: if (border == null) {
380: continue;
381: }
382:
383: path = path.subtract(border.getShape());
384: }
385:
386: Pattern sourcePattern = c.getSource().getPattern();
387:
388: if (sourcePattern instanceof ElseIfPattern) {
389: path = path
390: .subtract(((ElseIfPattern) sourcePattern)
391: .getBorder().getShape());
392: }
393:
394: FPoint p = path.point(0.5f * Math.min(1,
395: LayoutManager.HSPACING / path.length()));
396:
397: placeHolders
398: .add(new ElseIfReorderingPlaceHolder(
399: draggedPattern, p.x, p.y,
400: connectionsCount - 1));
401: }
402: }
403: }
404:
405: class ThenActivityPlaceHolder extends PlaceHolder {
406: public ThenActivityPlaceHolder(Pattern draggedPattern) {
407: super (IfPattern.this , draggedPattern, thenPlaceHolder
408: .getCenterX(), thenPlaceHolder.getCenterY());
409: }
410:
411: public void drop() {
412:
413: ((If) getOMReference())
414: .setActivity((Activity) getDraggedPattern()
415: .getOMReference());
416:
417: }
418: }
419:
420: class ElsePlaceHolder extends PlaceHolder {
421: public ElsePlaceHolder(Pattern draggedPattern) {
422: super (IfPattern.this , draggedPattern,
423: elseStub.getCenterX(), elseStub.getCenterY());
424: }
425:
426: public void drop() {
427: Else elseOM = getOMReference().getBpelModel().getBuilder()
428: .createElse();
429:
430: elseOM.setActivity((Activity) getDraggedPattern()
431: .getOMReference());
432: ((If) getOMReference()).setElse(elseOM);
433: }
434: }
435:
436: class ElseIfReorderingPlaceHolder extends PlaceHolder {
437:
438: private int placeHolderPosition;
439: private int elseIfIndex;
440:
441: public ElseIfReorderingPlaceHolder(Pattern draggedPattern,
442: FPath cPath, int placeHolderPosition) {
443: super (IfPattern.this , draggedPattern, cPath);
444: init(placeHolderPosition);
445: }
446:
447: public ElseIfReorderingPlaceHolder(Pattern draggedPattern,
448: float cx, float cy, int placeHolderPosition) {
449: super (IfPattern.this , draggedPattern, cx, cy);
450: init(placeHolderPosition);
451: }
452:
453: private void init(int placeHolderPosition) {
454: this .placeHolderPosition = placeHolderPosition;
455:
456: If ifOM = (If) getOwnerPattern().getOMReference();
457: ElseIf elseIfOM = (ElseIf) getDraggedPattern()
458: .getOMReference();
459:
460: this .elseIfIndex = ifOM.indexOf(ElseIf.class, elseIfOM);
461: }
462:
463: public void drop() {
464: If ifOM = (If) getOwnerPattern().getOMReference();
465: ElseIf elseIfOM = (ElseIf) getDraggedPattern()
466: .getOMReference();
467:
468: if (placeHolderPosition == 0) {
469: ifOM.insertElseIf(elseIfOM, 0);
470:
471: ElseIf newElseIf = ifOM.getElseIf(0);
472:
473: BooleanExpr expr1 = ifOM.getCondition();
474: ExtendableActivity activity1 = ifOM.getActivity();
475:
476: if (expr1 != null) {
477: expr1 = (BooleanExpr) expr1.cut();
478: }
479:
480: if (activity1 != null) {
481: activity1 = (ExtendableActivity) activity1.cut();
482: }
483:
484: BooleanExpr expr2 = newElseIf.getCondition();
485: ExtendableActivity activity2 = newElseIf.getActivity();
486:
487: if (expr2 != null) {
488: expr2 = (BooleanExpr) expr2.cut();
489: }
490:
491: if (activity2 != null) {
492: activity2 = (ExtendableActivity) activity2.cut();
493: }
494:
495: if (expr2 != null) {
496: ifOM.setCondition(expr2);
497: }
498:
499: if (activity2 != null) {
500: ifOM.setActivity(activity2);
501: }
502:
503: if (expr1 != null) {
504: newElseIf.setCondition(expr1);
505: }
506:
507: if (activity1 != null) {
508: newElseIf.setActivity(activity1);
509: }
510: } else if (placeHolderPosition < elseIfIndex + 2) {
511: //elseIfOM = (ElseIf) elseIfOM.cut();
512: ifOM.insertElseIf(elseIfOM, placeHolderPosition - 1);
513: } else {
514: //elseIfOM = (ElseIf) elseIfOM.cut();
515: ifOM.insertElseIf(elseIfOM, placeHolderPosition - 2);
516: }
517: }
518: }
519: }
|