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.util.ArrayList;
023: import java.util.Collection;
024: import java.util.HashMap;
025: import java.util.List;
026: import org.netbeans.modules.bpel.design.geometry.FBounds;
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.geometry.FRange;
030: import org.netbeans.modules.bpel.design.model.elements.NullBorder;
031:
032: import org.netbeans.modules.bpel.model.api.Activity;
033: import org.netbeans.modules.bpel.model.api.BpelEntity;
034: import org.netbeans.modules.bpel.model.api.Sequence;
035: import org.netbeans.modules.bpel.design.layout.LayoutManager;
036: import org.netbeans.modules.bpel.design.model.DiagramModel;
037: import org.netbeans.modules.bpel.design.model.connections.Direction;
038: import org.netbeans.modules.bpel.design.model.connections.Connection;
039: import org.netbeans.modules.bpel.design.model.connections.DefaultConnection;
040: import org.netbeans.modules.bpel.design.model.elements.BorderElement;
041: import org.netbeans.modules.bpel.design.model.elements.GroupBorder;
042: import org.netbeans.modules.bpel.design.model.elements.PlaceHolderElement;
043: import org.netbeans.modules.bpel.design.model.elements.VisualElement;
044: import org.netbeans.modules.bpel.editors.api.nodes.NodeType;
045: import org.netbeans.modules.bpel.design.selection.PlaceHolder;
046:
047: public class SequencePattern extends CompositePattern {
048:
049: private PlaceHolderElement placeHolder;
050: private List<Connection> connections = new ArrayList<Connection>();
051:
052: public SequencePattern(DiagramModel model) {
053: super (model);
054: }
055:
056: public VisualElement getFirstElement() {
057: BpelEntity[] activities = (BpelEntity[]) ((Sequence) getOMReference())
058: .getActivities();
059:
060: if (activities.length > 0) {
061: return getNestedPattern(activities[0]).getFirstElement();
062: }
063: return placeHolder;
064: }
065:
066: public VisualElement getLastElement() {
067: BpelEntity[] activities = (BpelEntity[]) ((Sequence) getOMReference())
068: .getActivities();
069:
070: if (activities.length > 0) {
071: return getNestedPattern(activities[activities.length - 1])
072: .getLastElement();
073: }
074: return placeHolder;
075:
076: }
077:
078: public boolean isSelectable() {
079: //sequence can not be selected if sequences are filtered out.
080:
081: return (getBorder() instanceof GroupBorder);
082:
083: }
084:
085: public FBounds layoutPattern(LayoutManager manager) {
086: Collection<Pattern> patterns = super .getNestedPatterns();
087:
088: FRange rangeW = new FRange(0);
089: double yPos = 0;
090:
091: if (patterns.isEmpty()) {
092: double t = placeHolder.getWidth() / 2;
093: placeHolder.setLocation(-t, 0);
094:
095: rangeW.extend(-t);
096: rangeW.extend(t);
097: yPos = placeHolder.getHeight();
098:
099: } else {
100: BpelEntity[] activities = (BpelEntity[]) ((Sequence) getOMReference())
101: .getActivities();
102:
103: for (BpelEntity a : activities) {
104: Pattern p = getNestedPattern(a);
105: assert p != null;
106: FBounds clientSize = p.getBounds();
107: FPoint origin = manager.getOriginOffset(p);
108:
109: manager.setPatternPosition(p, -origin.x, yPos);
110:
111: rangeW.extend(-origin.x);
112: rangeW.extend(clientSize.width - origin.x);
113:
114: yPos += clientSize.height + LayoutManager.VSPACING;
115:
116: }
117: yPos -= LayoutManager.VSPACING;
118: }
119:
120: getBorder().setClientRectangle(rangeW.min, 0, rangeW.getSize(),
121: yPos);
122: return getBorder().getBounds();
123: }
124:
125: protected void createElementsImpl() {
126:
127: placeHolder = new PlaceHolderElement();
128: appendElement(placeHolder);
129:
130: if (getModel().getFilters().showImplicitSequences()) {
131: setBorder(new GroupBorder());
132: registerTextElement(getBorder());
133: } else {
134: setBorder(new NullBorder());
135: }
136:
137: BpelEntity activities[] = (BpelEntity[]) ((Sequence) getOMReference())
138: .getActivities();
139:
140: for (BpelEntity a : activities) {
141: Pattern p = getModel().createPattern(a);
142: p.setParent(this );
143: }
144: }
145:
146: public String getDefaultName() {
147: return "Sequence"; // NOI18N
148: }
149:
150: protected void onAppendPattern(Pattern p) {
151: if (placeHolder.getPattern() != null) {
152: removeElement(placeHolder);
153: }
154: }
155:
156: protected void onRemovePattern(Pattern p) {
157: if (getNestedPatterns().isEmpty()) {
158: appendElement(placeHolder);
159: }
160: }
161:
162: public void createPlaceholders(Pattern draggedPattern,
163: Collection<PlaceHolder> placeHolders) {
164: if (!(draggedPattern.getOMReference() instanceof Activity))
165: return;
166:
167: BpelEntity[] activities = (BpelEntity[]) ((Sequence) getOMReference())
168: .getActivities();
169:
170: if (activities.length > 0) {
171:
172: //iterate over nested element in correct order
173:
174: Connection inbound = getInboundConnection();
175: Connection outbound = getOutboundConnection();
176:
177: Pattern firstPattern = getNestedPattern(activities[0]);
178:
179: Pattern lastPattern = getNestedPattern(activities[activities.length - 1]);
180:
181: Pattern p;
182:
183: Connection lastAdded = null;
184:
185: HashMap<Connection, Pattern> pairs = new HashMap<Connection, Pattern>();
186:
187: if (inbound != null) {
188: pairs.put(lastAdded = inbound, null);
189: }
190:
191: for (int i = 0; i < connections.size(); i++) {
192: p = getNestedPattern(activities[i]);
193:
194: if (p != draggedPattern) {
195: pairs.put(lastAdded = connections.get(i), p);
196: } else if (lastAdded != null) {
197: pairs.remove(lastAdded);
198: }
199: }
200:
201: if (lastPattern != draggedPattern) {
202: //no outbound connection if sequence is inside
203: if (outbound != null) {
204: pairs.put(outbound, lastPattern);
205: }
206: } else if (lastAdded != null) {
207: pairs.remove(lastAdded);
208: }
209:
210: for (Connection c : pairs.keySet()) {
211: // MAYBE BUG
212: FPath connectedPathes = c.getSegmentsForPattern(this );
213:
214: if (connectedPathes != null) {
215: placeHolders.add(new ConnectionPlaceHolder(
216: draggedPattern, connectedPathes, pairs
217: .get(c)));
218: // for (FPath path : connectedPathes) {
219: // placeHolders.add(new ConnectionPlaceHolder(
220: // draggedPattern, path, pairs.get(c)));
221: // }
222: }
223: }
224:
225: if ((inbound == null) && (firstPattern != draggedPattern)) {
226: BorderElement border = getBorder();
227: double cx = border.getCenterX();
228: double cy = border.getY() + border.getInsets().top / 2;
229: placeHolders.add(new FirstPlaceHolder(draggedPattern,
230: cx, cy));
231: }
232:
233: if ((outbound == null) && (lastPattern != draggedPattern)) {
234: BorderElement border = getBorder();
235: double cx = border.getCenterX();
236: double cy = border.getY() + border.getHeight()
237: - border.getInsets().bottom / 2;
238: placeHolders.add(new LastPlaceHolder(draggedPattern,
239: cx, cy));
240: }
241:
242: } else {
243: placeHolders.add(new InnerPlaceHolder(draggedPattern));
244: }
245: }
246:
247: class FirstPlaceHolder extends PlaceHolder {
248: public FirstPlaceHolder(Pattern draggedPattern, double cx,
249: double cy) {
250: super (SequencePattern.this , draggedPattern, cx, cy);
251: }
252:
253: public void drop() {
254: Pattern pattern = getDraggedPattern();
255: Sequence sequence = (Sequence) getOMReference();
256: sequence.insertActivity(
257: (Activity) pattern.getOMReference(), 0);
258: }
259: }
260:
261: class LastPlaceHolder extends PlaceHolder {
262: public LastPlaceHolder(Pattern draggedPattern, double cx,
263: double cy) {
264: super (SequencePattern.this , draggedPattern, cx, cy);
265: }
266:
267: public void drop() {
268: Pattern pattern = getDraggedPattern();
269: Sequence sequence = (Sequence) getOMReference();
270: int i = sequence.getActivities().length;
271: sequence.addActivity((Activity) pattern.getOMReference());
272: }
273: }
274:
275: // abstract class NoneConnectionPlaceHolder extends CirclePlaceHolder {
276: // public NoneConnectionPlaceHolder(Pattern dndPattern,
277: // float centerX, float centerY)
278: // {
279: // super(SequencePattern.this.getView(), SequencePattern.this,
280: // dndPattern, centerX, centerY);
281: // }
282: // }
283:
284: class ConnectionPlaceHolder extends PlaceHolder {
285:
286: private Pattern insertAfter;
287:
288: public ConnectionPlaceHolder(Pattern draggedPattern,
289: FPath cPath, Pattern insertAfter) {
290: super (SequencePattern.this , draggedPattern, cPath);
291: this .insertAfter = insertAfter;
292: }
293:
294: public void drop() {
295: Pattern pattern = getDraggedPattern();
296:
297: // first find the place to paste new pattern
298: // according to "connection" position
299: BpelEntity[] activities = (BpelEntity[]) ((Sequence) getOMReference())
300: .getActivities();
301:
302: int index = -1;
303:
304: if (insertAfter == null) {
305: index = 0;
306: } else {
307: Object refInsertAfter = insertAfter.getOMReference();
308: for (int n = 0; n < activities.length; n++) {
309:
310: if (activities[n] == refInsertAfter) {
311: index = n + 1;
312: break;
313: }
314: }
315: }
316:
317: ((Sequence) getOMReference()).insertActivity(
318: (Activity) pattern.getOMReference(), index);
319: }
320: }
321:
322: class InnerPlaceHolder extends PlaceHolder {
323: public InnerPlaceHolder(Pattern draggedPattern) {
324: super (SequencePattern.this , draggedPattern, placeHolder
325: .getCenterX(), placeHolder.getCenterY());
326: }
327:
328: public void drop() {
329: ((Sequence) getOMReference())
330: .addActivity((Activity) getDraggedPattern()
331: .getOMReference());
332: }
333: }
334:
335: public NodeType getNodeType() {
336: return NodeType.SEQUENCE;
337: }
338:
339: public void updateAccordingToViewFiltersStatus() {
340: if (getModel().getFilters().showImplicitSequences()) {
341: setBorder(new GroupBorder());
342: registerTextElement(getBorder());
343: setText(((Sequence) getOMReference()).getName());
344: } else {
345: setBorder(new NullBorder());
346: registerTextElement(null);
347: }
348: }
349:
350: public void reconnectElements() {
351: //Trying to reuse existing connections for optimisation
352: BpelEntity[] activities = (BpelEntity[]) ((Sequence) getOMReference())
353: .getActivities();
354:
355: ensureConnectionsCount(connections, activities.length - 1);
356:
357: for (int i = 0; i < activities.length - 1; i++) {
358: Pattern p1 = getNestedPattern(activities[i]);
359: Pattern p2 = getNestedPattern(activities[i + 1]);
360:
361: VisualElement v1 = p1.getLastElement();
362: VisualElement v2 = p2.getFirstElement();
363:
364: connections.get(i).connect(v1, Direction.BOTTOM, v2,
365: Direction.TOP);
366: }
367:
368: }
369:
370: private Connection getInboundConnection() {
371: List<Connection> list = getFirstElement()
372: .getIncomingConnections();
373:
374: for (Connection connection : list) {
375: Class c = connection.getClass();
376: if ((c == Connection.class)
377: || (c == DefaultConnection.class)) {
378: return connection;
379: }
380: }
381:
382: return null;
383: }
384:
385: private Connection getOutboundConnection() {
386: List<Connection> list = getLastElement()
387: .getOutcomingConnections();
388:
389: for (Connection connection : list) {
390: Class c = connection.getClass();
391: if ((c == Connection.class)
392: || (c == DefaultConnection.class)) {
393: return connection;
394: }
395: }
396:
397: return null;
398: }
399: }
|