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.Graphics2D;
023: import java.awt.geom.Area;
024: import java.util.ArrayList;
025: import java.util.Collection;
026: import java.util.List;
027: import org.netbeans.modules.bpel.model.api.Activity;
028: import org.netbeans.modules.bpel.model.api.BpelEntity;
029: import org.netbeans.modules.bpel.model.api.ExtendableActivity;
030: import org.netbeans.modules.bpel.model.api.Flow;
031: import org.netbeans.modules.bpel.design.geometry.FBounds;
032: import org.netbeans.modules.bpel.design.geometry.FDimension;
033: import org.netbeans.modules.bpel.design.geometry.FPath;
034: import org.netbeans.modules.bpel.design.geometry.FPoint;
035: import org.netbeans.modules.bpel.design.geometry.FShape;
036: import org.netbeans.modules.bpel.design.layout.LayoutManager;
037: import org.netbeans.modules.bpel.design.model.DiagramModel;
038: import org.netbeans.modules.bpel.design.model.connections.Connection;
039: import org.netbeans.modules.bpel.design.model.connections.ConnectionManager;
040: import org.netbeans.modules.bpel.design.model.connections.Direction;
041: import org.netbeans.modules.bpel.design.model.elements.ContentElement;
042: import org.netbeans.modules.bpel.design.model.elements.BorderElement;
043: import org.netbeans.modules.bpel.design.model.elements.GroupBorder;
044: import org.netbeans.modules.bpel.design.model.elements.PlaceHolderElement;
045: import org.netbeans.modules.bpel.design.model.elements.VisualElement;
046: import org.netbeans.modules.bpel.editors.api.nodes.NodeType;
047: import org.netbeans.modules.bpel.design.selection.PlaceHolder;
048: import org.netbeans.modules.bpel.model.api.Sequence;
049:
050: public class FlowPattern extends CompositePattern {
051:
052: private VisualElement startGateway;
053: private VisualElement endGateway;
054:
055: private PlaceHolderElement placeHolder;
056:
057: private List<Connection> connectionsStart = new ArrayList<Connection>();
058: private List<Connection> connectionsEnd = new ArrayList<Connection>();
059:
060: private Connection startPlaceHolderConnection;
061: private Connection endPlaceHolderConnection;
062:
063: public FlowPattern(DiagramModel model) {
064: super (model);
065: }
066:
067: public VisualElement getFirstElement() {
068: return startGateway;
069: }
070:
071: public VisualElement getLastElement() {
072: return endGateway;
073: }
074:
075: protected void createElementsImpl() {
076: setBorder(new GroupBorder());
077: getBorder().setLabelText(getDefaultName());
078: registerTextElement(getBorder());
079:
080: startGateway = ContentElement.createFlowGateway();
081: appendElement(startGateway);
082: startGateway.setLabelText(""); // NOI18N
083:
084: endGateway = ContentElement.createFlowGateway();
085: appendElement(endGateway);
086: endGateway.setLabelText(""); // NOI18N
087:
088: placeHolder = new PlaceHolderElement();
089: appendElement(placeHolder);
090:
091: Flow flow = (Flow) getOMReference();
092:
093: BpelEntity[] activities = flow.getActivities();
094:
095: for (BpelEntity a : activities) {
096: Pattern p = getModel().createPattern(a);
097: p.setParent(this );
098: }
099: }
100:
101: public FBounds layoutPattern(LayoutManager manager) {
102:
103: Collection<Pattern> patterns = getNestedPatterns();
104:
105: boolean empty = patterns.isEmpty();
106:
107: double height = 0;
108: double width = 0;
109:
110: if (empty) {
111: width = placeHolder.getWidth();
112: height = placeHolder.getHeight();
113:
114: placeHolder.setLocation(-width / 2, -height / 2);
115: } else {
116: Flow flow = (Flow) getOMReference();
117: ExtendableActivity[] activities = flow.getActivities();
118:
119: for (ExtendableActivity a : activities) {
120: Pattern p = getNestedPattern(a);
121: FDimension pSize = p.getBounds().getSize();
122: height = Math.max(height, pSize.height);
123: width += pSize.width;
124: }
125:
126: width += (patterns.size() - 1) * LayoutManager.HSPACING;
127:
128: double x = -width / 2;
129:
130: for (ExtendableActivity a : activities) {
131: Pattern p = getNestedPattern(a);
132: FBounds pBounds = p.getBounds();
133: float y = -pBounds.height / 2;
134: manager.setPatternPosition(p, x, y);
135: x += pBounds.width + LayoutManager.HSPACING;
136: }
137: }
138:
139: double y1 = -(height / 2 + startGateway.getHeight() / 2 + LayoutManager.VSPACING);
140: double y2 = height / 2 + endGateway.getHeight() / 2
141: + LayoutManager.VSPACING;
142:
143: startGateway.setCenter(0, y1);
144: endGateway.setCenter(0, y2);
145:
146: width = Math.max(width, startGateway.getWidth());
147:
148: double x0 = -width / 2;
149: double y0 = -height / 2 - startGateway.getHeight()
150: - LayoutManager.VSPACING;
151:
152: height += startGateway.getHeight() + endGateway.getHeight() + 2
153: * LayoutManager.VSPACING;
154:
155: getBorder().setClientRectangle(x0, y0, width, height);
156: return getBorder().getBounds();
157: }
158:
159: protected void onAppendPattern(Pattern p) {
160: if (placeHolder.getPattern() == this ) {
161: removeElement(placeHolder);
162: }
163: }
164:
165: protected void onRemovePattern(Pattern p) {
166: Flow flow = (Flow) getOMReference();
167: if (flow.sizeOfActivities() == 0) {
168: appendElement(placeHolder);
169: }
170: }
171:
172: public String getDefaultName() {
173: return "Flow"; // NOI18N
174: }
175:
176: public void createPlaceholders(Pattern draggedPattern,
177: Collection<PlaceHolder> placeHolders) {
178: if (draggedPattern == this )
179: return;
180: if (isNestedIn(draggedPattern))
181: return;
182: if (!(draggedPattern.getOMReference() instanceof Activity))
183: return;
184:
185: if (placeHolder.getPattern() != null) {
186: placeHolders.add(new FirstPlaceHolder(draggedPattern));
187: } else {
188: placeHolders.add(new NextPlaceHolder(draggedPattern));
189:
190: Flow flow = (Flow) getOMReference();
191:
192: ExtendableActivity[] activities = flow.getActivities();
193:
194: for (int i = 0; i < activities.length; i++) {
195: ExtendableActivity activity = activities[i];
196:
197: if (activity instanceof Sequence)
198: continue;
199:
200: Pattern p = getNestedPattern(activity);
201:
202: if (p == draggedPattern)
203: continue;
204:
205: FPath start = connectionsStart.get(i).getPath();
206: FPath end = connectionsEnd.get(i).getPath();
207:
208: if (p instanceof CompositePattern) {
209: BorderElement border = ((CompositePattern) p)
210: .getBorder();
211:
212: if (border != null) {
213: FShape borderShape = border.getShape();
214:
215: start = start.subtract(borderShape);
216: end = end.subtract(borderShape);
217: }
218: }
219:
220: placeHolders
221: .add(new BeforeImpliciteSequencePlaceHolder(i,
222: draggedPattern, start));
223: placeHolders.add(new AfterImpliciteSequencePlaceHolder(
224: i, draggedPattern, end));
225: }
226: }
227: }
228:
229: public void reconnectElements() {
230: BpelEntity[] activities = ((Flow) getOMReference())
231: .getActivities();
232:
233: ensureConnectionsCount(connectionsStart, activities.length);
234: ensureConnectionsCount(connectionsEnd, activities.length);
235:
236: for (int i = 0; i < activities.length; i++) {
237: Pattern p = getNestedPattern(activities[i]);
238:
239: Connection cs = connectionsStart.get(i);
240: Connection ce = connectionsEnd.get(i);
241:
242: ConnectionManager.connectVerticaly(startGateway, cs, p, ce,
243: endGateway);
244: }
245:
246: if (placeHolder.getPattern() != null) {
247: if (startPlaceHolderConnection == null) {
248: startPlaceHolderConnection = new Connection(this );
249: }
250:
251: if (endPlaceHolderConnection == null) {
252: endPlaceHolderConnection = new Connection(this );
253: }
254:
255: ConnectionManager.connectVerticaly(startGateway,
256: startPlaceHolderConnection, placeHolder,
257: endPlaceHolderConnection, endGateway);
258: } else {
259: if (startPlaceHolderConnection != null) {
260: startPlaceHolderConnection.remove();
261: startPlaceHolderConnection = null;
262: }
263:
264: if (endPlaceHolderConnection != null) {
265: endPlaceHolderConnection.remove();
266: endPlaceHolderConnection = null;
267: }
268: }
269: }
270:
271: public NodeType getNodeType() {
272: return NodeType.FLOW;
273: }
274:
275: public Area createSelection() {
276: Area a = new Area(getBorder().getShape());
277: a.subtract(new Area(startGateway.getShape()));
278: a.subtract(new Area(endGateway.getShape()));
279: return a;
280: }
281:
282: private double getNextPlaceHolderX() {
283: BorderElement border = getBorder();
284: return border.getX() + border.getWidth()
285: - border.getInsets().right / 2;
286: }
287:
288: class FirstPlaceHolder extends PlaceHolder {
289: public FirstPlaceHolder(Pattern draggedPattern) {
290: super (FlowPattern.this , draggedPattern, placeHolder
291: .getCenterX(), placeHolder.getCenterY());
292: }
293:
294: public void drop() {
295: Pattern p = getDraggedPattern();
296: ((Flow) getOMReference()).addActivity((Activity) p
297: .getOMReference());
298:
299: }
300: }
301:
302: class NextPlaceHolder extends PlaceHolder {
303:
304: private FPath tempPath;
305:
306: public NextPlaceHolder(Pattern draggedPattern) {
307: super (FlowPattern.this , draggedPattern,
308: getNextPlaceHolderX(), getBorder().getCenterY());
309:
310: tempPath = createTempPath();
311: }
312:
313: public void drop() {
314: Pattern p = getDraggedPattern();
315: ((Flow) getOMReference()).addActivity((Activity) p
316: .getOMReference());
317: }
318:
319: public void paint(Graphics2D g2) {
320: Connection.paintConnection(g2, tempPath, false, true,
321: false, false, null);
322: super .paint(g2);
323: }
324:
325: private FPath createTempPath() {
326: double x1 = startGateway.getX() + startGateway.getWidth();
327: double y1 = startGateway.getY() + startGateway.getHeight();
328: for (Connection c : startGateway.getOutcomingConnections()) {
329: if (c.getSourceDirection() == Direction.RIGHT) {
330: y1 = Math.min(c.getPath().point(0).y, y1);
331: }
332: }
333: y1 = (y1 + startGateway.getY()) / 2;
334:
335: double x2 = endGateway.getX() + endGateway.getWidth();
336: double y2 = endGateway.getY();
337: for (Connection c : endGateway.getIncomingConnections()) {
338: if (c.getTargetDirection() == Direction.RIGHT) {
339: y2 = Math.max(c.getPath().point(1).y, y2);
340: }
341: }
342: y2 = (y2 + endGateway.getY() + endGateway.getHeight()) / 2;
343:
344: double xp = getNextPlaceHolderX();
345:
346: FPath p = new FPath(x1, y1, xp, y1, xp, y2, x2, y2);
347:
348: return p.round(2);
349: }
350: }
351:
352: private class BeforeImpliciteSequencePlaceHolder extends
353: PlaceHolder {
354:
355: private int index;
356:
357: public BeforeImpliciteSequencePlaceHolder(int index,
358: Pattern draggedPattern, FPath path) {
359: super (FlowPattern.this , draggedPattern, path.point(Math
360: .max(0, 1f - 10f / path.length())));
361:
362: Flow flow = (Flow) FlowPattern.this .getOMReference();
363: ExtendableActivity dragged = (ExtendableActivity) draggedPattern
364: .getOMReference();
365:
366: this .index = index;
367:
368: if (dragged.getParent() == flow) {
369: int oldIndex = flow.indexOf(ExtendableActivity.class,
370: dragged);
371: if (oldIndex < index) {
372: this .index--;
373: }
374: }
375: }
376:
377: public void drop() {
378: Flow flow = (Flow) getOwnerPattern().getOMReference();
379:
380: ExtendableActivity dragged = (ExtendableActivity) getDraggedPattern()
381: .getOMReference();
382: ExtendableActivity activity = (ExtendableActivity) flow
383: .getActivity(index).cut();
384:
385: Sequence sequence = flow.getBpelModel().getBuilder()
386: .createSequence();
387:
388: sequence.addActivity(dragged);
389: sequence.addActivity(activity);
390:
391: flow.insertActivity(sequence, index);
392: }
393: }
394:
395: private class AfterImpliciteSequencePlaceHolder extends PlaceHolder {
396:
397: private int index;
398:
399: public AfterImpliciteSequencePlaceHolder(int index,
400: Pattern draggedPattern, FPath path) {
401: super (FlowPattern.this , draggedPattern, path.point(Math
402: .min(1, 10f / path.length())));
403:
404: Flow flow = (Flow) FlowPattern.this .getOMReference();
405: ExtendableActivity dragged = (ExtendableActivity) draggedPattern
406: .getOMReference();
407:
408: this .index = index;
409:
410: if (dragged.getParent() == flow) {
411: int oldIndex = flow.indexOf(ExtendableActivity.class,
412: dragged);
413: if (oldIndex < index) {
414: this .index--;
415: }
416: }
417: }
418:
419: public void drop() {
420: Flow flow = (Flow) getOwnerPattern().getOMReference();
421:
422: ExtendableActivity dragged = (ExtendableActivity) getDraggedPattern()
423: .getOMReference();
424: ExtendableActivity activity = (ExtendableActivity) flow
425: .getActivity(index).cut();
426:
427: Sequence sequence = flow.getBpelModel().getBuilder()
428: .createSequence();
429:
430: sequence.addActivity(activity);
431: sequence.addActivity(dragged);
432:
433: flow.insertActivity(sequence, index);
434: }
435: }
436:
437: }
|