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;
021:
022: import java.awt.Component;
023: import java.awt.Point;
024: import java.awt.datatransfer.DataFlavor;
025: import java.awt.datatransfer.Transferable;
026: import java.awt.datatransfer.UnsupportedFlavorException;
027: import java.awt.dnd.DnDConstants;
028: import java.awt.dnd.DragGestureEvent;
029: import java.awt.dnd.DragGestureListener;
030: import java.awt.dnd.DragSource;
031: import java.awt.dnd.DragSourceDragEvent;
032: import java.awt.dnd.DragSourceDropEvent;
033: import java.awt.dnd.DragSourceEvent;
034: import java.awt.dnd.DragSourceListener;
035: import java.awt.dnd.DropTarget;
036: import java.awt.dnd.DropTargetDragEvent;
037: import java.awt.dnd.DropTargetDropEvent;
038: import java.awt.dnd.DropTargetEvent;
039: import java.awt.dnd.DropTargetListener;
040: import java.awt.image.BufferedImage;
041: import java.io.IOException;
042: import java.util.ArrayList;
043: import java.util.List;
044: import java.util.concurrent.Callable;
045: import org.netbeans.modules.bpel.design.decoration.components.LinkToolButton;
046: import org.netbeans.modules.bpel.design.geometry.FPoint;
047: import org.netbeans.modules.bpel.design.selection.DnDTool;
048: import org.netbeans.modules.bpel.design.selection.FlowlinkTool;
049: import org.netbeans.modules.bpel.model.api.BPELElementsBuilder;
050:
051: import org.netbeans.modules.bpel.model.api.BpelEntity;
052: import org.netbeans.modules.bpel.design.model.patterns.Pattern;
053: import org.netbeans.modules.bpel.design.selection.GhostSelection;
054: import org.netbeans.modules.bpel.model.api.For;
055: import org.netbeans.modules.bpel.model.api.ForEach;
056: import org.netbeans.modules.bpel.model.api.PartnerLink;
057: import org.netbeans.modules.bpel.model.api.Pick;
058: import org.netbeans.modules.bpel.model.api.Receive;
059: import org.netbeans.modules.bpel.model.api.Sequence;
060: import org.netbeans.modules.bpel.model.api.Wait;
061: import org.netbeans.modules.bpel.model.api.events.VetoException;
062: import org.netbeans.modules.bpel.model.api.support.TBoolean;
063: import org.netbeans.modules.bpel.properties.ImportRegistrationHelper;
064: import org.netbeans.modules.bpel.nodes.BpelNode;
065: import org.netbeans.modules.bpel.nodes.actions.AddOnAlarmAction;
066: import org.netbeans.modules.websvc.core.WebServiceReference;
067: import org.openide.ErrorManager;
068: import org.openide.loaders.DataObject;
069: import org.openide.nodes.Node;
070: import org.openide.util.Exceptions;
071: import org.openide.util.NbBundle;
072:
073: /**
074: *
075: * @author Alexey
076: */
077:
078: public class DnDHandler implements DragSourceListener,
079: DragGestureListener, DropTargetListener {
080:
081: private DesignView designView;
082: private DragSource dragSource;
083:
084: private MessageFlowDataFlavor flowDataFlavor = new MessageFlowDataFlavor();
085: private BpelDataFlavor bpelDataFlavor = new BpelDataFlavor();
086: private List<DiagramView> views;
087:
088: public DnDHandler(DesignView designView) {
089: this .designView = designView;
090:
091: views = new ArrayList<DiagramView>(3);
092: views.add(designView.getProcessView());
093: views.add(designView.getConsumersView());
094: views.add(designView.getProvidersView());
095:
096: dragSource = DragSource.getDefaultDragSource();// new DragSource();
097:
098: for (DiagramView view : views) {
099: dragSource.createDefaultDragGestureRecognizer(view,
100: DnDConstants.ACTION_MOVE, this );
101: new DropTarget(view, DnDConstants.ACTION_MOVE,
102: (DropTargetListener) this , true);
103:
104: }
105:
106: }
107:
108: public DesignView getDesignView() {
109: return designView;
110: }
111:
112: public void dragEnter(DragSourceDragEvent dsde) {
113: // System.out.println("DragSource.dragEnter");
114: }
115:
116: public void dragOver(DragSourceDragEvent dsde) {
117:
118: dsde.getDragSourceContext().setCursor(
119: dragSource.DefaultMoveDrop);
120: }
121:
122: public void dropActionChanged(DragSourceDragEvent dsde) {
123: }
124:
125: public void dragExit(DragSourceEvent dse) {
126: dse.getDragSourceContext().setCursor(
127: dragSource.DefaultMoveNoDrop);
128: }
129:
130: public void dragDropEnd(DragSourceDropEvent dsde) {
131: getGhostSelection().clear();
132: for (DiagramView view : views) {
133: view.getPlaceholderManager().clear();
134: }
135: getFlowLinkTool().clear();
136:
137: // System.out.println("DragSource.dragDropEnd");
138: if (dsde.getDropAction() == DnDConstants.ACTION_MOVE) {
139: // BpelEntity be = getBpelEntity(dsde.getDragSourceContext().getTransferable());
140: // BpelContainer parent = (BpelContainer)be.getParent();
141: // parent.remove(be);
142: }
143: }
144:
145: public void dragGestureRecognized(DragGestureEvent dge) {
146: // System.out.println("DragSource.dragGestureRecognized");
147:
148: Object src = dge.getTriggerEvent().getSource();
149:
150: if (src instanceof LinkToolButton) {
151: dge
152: .startDrag(DragSource.DefaultLinkDrop,
153: new BufferedImage(1, 1,
154: BufferedImage.TYPE_INT_ARGB),
155: new Point(0, 0),
156: new MessageFlowTransferable(
157: (LinkToolButton) src), this );
158: } else {
159:
160: if (dge.getComponent() instanceof DiagramView) {
161:
162: DiagramView view = (DiagramView) dge.getComponent();
163: Pattern clicked = view.findPattern(dge.getDragOrigin());
164:
165: Pattern selected = designView.getSelectionModel()
166: .getSelectedPattern();
167:
168: if (clicked == null) {
169: return;
170: }
171:
172: if (!clicked.isDraggable()) {
173: return;
174: }
175:
176: if (clicked == selected || clicked.isNestedIn(selected)) {
177: //start a move tool
178: if (!getDesignView().getModel().isReadOnly()) {
179: getGhostSelection().init(selected,
180: dge.getDragOrigin());
181: }
182:
183: dge.startDrag(DragSource.DefaultMoveDrop,
184: new BufferedImage(1, 1,
185: BufferedImage.TYPE_INT_ARGB),
186: new Point(0, 0), new BpelTransferable(
187: selected), this );
188: }
189: }
190: }
191: }
192:
193: public void dragEnter(DropTargetDragEvent dtde) {
194: // System.out.println("DropTarget.DragEnter, flavor[0] = " + dtde.getTransferable().getTransferDataFlavors()[0].getDefaultRepresentationClass());
195:
196: Transferable tr = dtde.getTransferable();
197:
198: if (tr.isDataFlavorSupported(flowDataFlavor)) {
199: FPoint p;
200: try {
201: LinkToolButton btn = (LinkToolButton) tr
202: .getTransferData(flowDataFlavor);
203: getFlowLinkTool().init(btn);
204:
205: if (designView.getModel().isReadOnly()) {
206: getGhostSelection().init(
207: NbBundle.getMessage(getClass(),
208: "LBL_ReadOnly"), //NOI18N
209: dtde.getLocation());
210: dtde.rejectDrag();
211: return;
212: }
213:
214: if (!designView.getModel().getFilters()
215: .showPartnerlinks()) {
216: getGhostSelection().init(
217: NbBundle.getMessage(getClass(),
218: "LBL_CanNotCreateMessageFlow"), //NOI18N
219: dtde.getLocation());
220: dtde.rejectDrag();
221: }
222: } catch (UnsupportedFlavorException ex) {
223: ex.printStackTrace();
224: } catch (IOException ex) {
225: ex.printStackTrace();
226: }
227: } else {
228: BpelEntity entity = getBpelEntity(tr);
229:
230: if (entity == null) {
231: dtde.rejectDrag();
232: return;
233: }
234:
235: if (entity.getModel() != getDesignView().getBPELModel()) {
236: dtde.rejectDrag();
237: return;
238: }
239:
240: if (designView.getModel().isReadOnly()) {
241: getGhostSelection()
242: .init(
243: NbBundle.getMessage(getClass(),
244: "LBL_ReadOnly"), //NOI18N
245: dtde.getLocation());
246: dtde.rejectDrag();
247: return;
248: }
249:
250: if (!designView.getModel().getFilters()
251: .showImplicitSequences()
252: && (entity instanceof Sequence)) {
253: getGhostSelection().init(
254: NbBundle.getMessage(getClass(),
255: "LBL_CanNotAddSequence"),
256: dtde.getLocation()); // NOI18N
257: dtde.rejectDrag();
258: } else if (!designView.getModel().getFilters()
259: .showPartnerlinks()
260: && (entity instanceof PartnerLink)) {
261: getGhostSelection().init(
262: NbBundle.getMessage(getClass(),
263: "LBL_CanNotAddPartnerLink"),
264: dtde.getLocation()); // NOI18N
265: dtde.rejectDrag();
266: } else {
267: Pattern pattern = designView.getModel().getPattern(
268: entity);
269:
270: if (pattern == null) {
271: pattern = designView.getModel().createPattern(
272: entity);
273: //designView.getLayoutManager().layout(pattern, 0, 0);
274:
275: }
276:
277: if (getGhostSelection().isEmpty()) {
278: getGhostSelection().initCentered(pattern,
279: dtde.getLocation());
280: }
281:
282: for (DiagramView view : views) {
283: view.getPlaceholderManager().init(pattern);
284: }
285:
286: dtde.acceptDrag(DnDConstants.ACTION_MOVE);
287: }
288: }
289: }
290:
291: public void dragOver(DropTargetDragEvent dtde) {
292: // System.out.println("DropTarget.DragOver");
293: Transferable tr = dtde.getTransferable();
294:
295: DnDTool tool = null;
296:
297: if (tr.isDataFlavorSupported(flowDataFlavor)) {
298: //FIXME tool = getFlowLinkTool();
299: } else {
300: if (!getGhostSelection().isEmpty()) {
301:
302: DiagramView view = (DiagramView) dtde
303: .getDropTargetContext().getComponent();
304: if (view != null) {
305: FPoint mp = view.convertScreenToDiagram(dtde
306: .getLocation());
307:
308: tool = view.getPlaceholderManager();
309:
310: tool.move(mp);
311:
312: getGhostSelection().move(mp);
313: getGhostSelection().setEnabled(
314: tool.isValidLocation());
315: }
316:
317: }
318: }
319:
320: if (tool != null && tool.isValidLocation()) {
321: dtde.acceptDrag(DnDConstants.ACTION_MOVE);
322: } else {
323: dtde.rejectDrag();
324: }
325: }
326:
327: public void dropActionChanged(DropTargetDragEvent dtde) {
328: }
329:
330: public void dragExit(DropTargetEvent dte) {
331: // System.out.println("DropTarget.DragExit");
332: getGhostSelection().clear();
333: for (DiagramView view : views) {
334: view.getPlaceholderManager().clear();
335: }
336: getFlowLinkTool().clear();
337: }
338:
339: public void drop(final DropTargetDropEvent dtde) {
340: // System.out.println("DropTarget.drop");
341:
342: //BpelEntity be = getBpelEntity(dtde.getTransferable());
343:
344: getDesignView().getTopComponent().requestActive();
345: getDesignView().requestFocusInWindow();
346:
347: getGhostSelection().clear();
348:
349: final DiagramView view = (DiagramView) dtde
350: .getDropTargetContext().getComponent();
351:
352: if (view == null) {
353: return;
354: }
355:
356: final FPoint location = view.convertScreenToDiagram(dtde
357: .getLocation());
358:
359: Callable<Object> callable = null;
360: if (dtde.isDataFlavorSupported(flowDataFlavor)) {
361: callable = new Callable<Object>() {
362:
363: public Object call() {
364: getFlowLinkTool().drop(location);
365:
366: return null;
367: }
368: };
369: } else {
370: callable = new Callable<Object>() {
371:
372: public Object call() {
373: view.getPlaceholderManager().drop(location);
374: return null;
375: }
376: };
377:
378: }
379:
380: try {
381: if (callable != null) {
382: designView.getBPELModel().invoke(callable, this );
383: }
384: } catch (Exception ex) {
385: ErrorManager.getDefault().notify(
386: ErrorManager.INFORMATIONAL, ex);
387: }
388:
389: }
390:
391: private BpelEntity getBpelEntity(Transferable t) {
392: BpelEntity entity = null;
393: try {
394:
395: for (DataFlavor flavor : t.getTransferDataFlavors()) {
396: Class repClass = flavor.getRepresentationClass();
397: Object data = t.getTransferData(flavor);
398: if (BpelNode.class.isAssignableFrom(repClass)) {
399: //DnD from Diagram or Nav
400: Object ref = ((BpelNode) data).getReference();
401: if (ref instanceof BpelEntity) {
402: entity = (BpelEntity) ref;
403: }
404:
405: } else if (Node.class.isAssignableFrom(repClass)) {
406: //DnD from palette or ProjectTree
407: entity = getPaletteItem((Node) data);
408: } else if (WebServiceReference.class
409: .isAssignableFrom(repClass)) {
410: entity = designView.getBPELModel().getBuilder()
411: .createPartnerLink();
412: entity.setCookie(DnDHandler.class, data);
413:
414: } else if (DataObject.class.isAssignableFrom(repClass)) {
415: DataObject dataObj = (DataObject) data;
416: String ext = dataObj.getPrimaryFile().getExt();
417: if (ext.compareToIgnoreCase("wsdl") == 0) { // NOI18N
418: //for WSDl first just try to create PL based on PLTS found in that WSDL
419: entity = designView.getBPELModel().getBuilder()
420: .createPartnerLink();
421: entity.setCookie(DnDHandler.class, dataObj
422: .getPrimaryFile());
423: } else if (ext.compareToIgnoreCase("xsd") == 0) { // NOI18N
424: //For schemas just add imprt
425: entity = new ImportRegistrationHelper(
426: designView.getBPELModel())
427: .createImport(dataObj.getPrimaryFile());
428: }
429: }
430: if (entity != null) {
431: break;
432: }
433: }
434:
435: } catch (UnsupportedFlavorException ufe) {
436:
437: } catch (IOException ioe) {
438:
439: }
440: return entity;
441: }
442:
443: class MessageFlowDataFlavor extends DataFlavor {
444: private static final long serialVersionUID = 1;
445:
446: public MessageFlowDataFlavor() {
447: super (FlowlinkTool.class, "Message flow link"); // NOI18N
448: }
449: }
450:
451: class MessageFlowTransferable implements Transferable {
452:
453: private LinkToolButton button;
454:
455: public MessageFlowTransferable(LinkToolButton button) {
456: this .button = button;
457: }
458:
459: public DataFlavor[] getTransferDataFlavors() {
460: return new DataFlavor[] { flowDataFlavor };
461: }
462:
463: public boolean isDataFlavorSupported(DataFlavor flavor) {
464: return (flavor.getRepresentationClass() == FlowlinkTool.class);
465: }
466:
467: public Object getTransferData(DataFlavor flavor)
468: throws UnsupportedFlavorException, IOException {
469: if (!isDataFlavorSupported(flavor))
470: throw new UnsupportedFlavorException(flavor);
471:
472: return button;
473: }
474:
475: }
476:
477: class BpelDataFlavor extends DataFlavor {
478: private static final long serialVersionUID = 1;
479:
480: public BpelDataFlavor() {
481: super (BpelNode.class, "Bpel element"); // NOI18N
482: }
483: }
484:
485: class BpelTransferable implements Transferable {
486:
487: private BpelNode draggedNode;
488:
489: public BpelTransferable(BpelNode draggedNode) {
490: this .draggedNode = draggedNode;
491: }
492:
493: public BpelTransferable(Pattern pattern) {
494: BpelEntity omRef = pattern.getOMReference();
495: assert omRef != null;
496:
497: this .draggedNode = (BpelNode) designView
498: .getNodeForPattern(pattern);
499:
500: }
501:
502: public DataFlavor[] getTransferDataFlavors() {
503: return new DataFlavor[] { bpelDataFlavor };
504: }
505:
506: public boolean isDataFlavorSupported(DataFlavor flavor) {
507: return (flavor.getRepresentationClass() == BpelNode.class);
508: }
509:
510: public Object getTransferData(DataFlavor flavor)
511: throws UnsupportedFlavorException, IOException {
512: if (!isDataFlavorSupported(flavor))
513: throw new UnsupportedFlavorException(flavor);
514:
515: return draggedNode;
516: }
517:
518: }
519:
520: private GhostSelection getGhostSelection() {
521: return designView.getGhost();
522: }
523:
524: private BpelEntity getPaletteItem(Node data) {
525: // assuming to be item from palette
526: String item = data.getName();
527: int k = item.indexOf("_"); // NOI18N
528:
529: if (k != -1) {
530: item = item.substring(0, k);
531: }
532: BPELElementsBuilder builder = designView.getBPELModel()
533: .getBuilder();
534:
535: if (item.equals("reply")) { // NOI18N
536: return builder.createReply();
537: } else if (item.equals("invoke")) { // NOI18N
538: return builder.createInvoke();
539: } else if (item.equals("receive")) { // NOI18N
540:
541: Receive rcv = builder.createReceive();
542: //indicator that object is being DnD from pallete.
543: //Diagram may use this value to set CreateInstance attribute
544: rcv.setCookie(DnDHandler.class, DnDHandler.class);
545: return rcv;
546: } else if (item.equals("pick")) { // NOI18N
547: Pick p = builder.createPick();
548: p.addOnMessage(builder.createOnMessage());
549: return p;
550: } else if (item.equals("assign")) { // NOI18N
551: return builder.createAssign();
552: } else if (item.equals("sequence")) { // NOI18N
553: return builder.createSequence();
554: } else if (item.equals("flow")) { // NOI18N
555: return builder.createFlow();
556: } else if (item.equals("while")) { // NOI18N
557: return builder.createWhile();
558: } else if (item.equals("repeatuntil")) { // NOI18N
559: return builder.createRepeatUntil();
560: } else if (item.equals("foreach")) { // NOI18N
561: ForEach fe = builder.createForEach();
562: fe.setParallel(TBoolean.NO);
563: try {
564: fe.setCounterName(fe.getName() + "Counter"); // NOI18N
565: } catch (VetoException ex) {
566: }
567: return fe;
568: } else if (item.equals("scope")) { // NOI18N
569: return builder.createScope();
570: } else if (item.equals("if")) { // NOI18N
571: return builder.createIf();
572: } else if (item.equals("wait")) { // NOI18N
573: Wait w = builder.createWait();
574: For f = builder.createFor();
575: try {
576: f.setContent(AddOnAlarmAction.DEFAULT_FOR_VALUE); //NOI18N
577: } catch (VetoException ex) {
578: ErrorManager.getDefault().notify(
579: ErrorManager.INFORMATIONAL, ex);
580: }
581: w.setTimeEvent(f);
582: return w;
583: } else if (item.equals("exit")) { // NOI18N
584: return builder.createExit();
585: } else if (item.equals("throw")) { // NOI18N
586: return builder.createThrow();
587: } else if (item.equals("rethrow")) { // NOI18N
588: return builder.createRethrow();
589: } else if (item.equals("compensate")) { // NOI18N
590: return builder.createCompensate();
591: } else if (item.equals("compensatescope")) { // NOI18N
592: return builder.createCompensateScope();
593: } else if (item.equals("empty")) { // NOI18N
594: return builder.createEmpty();
595: } else if (item.equals("partner")) { // NOI18N
596: return builder.createPartnerLink();
597: } else if (item.equals("exit")) { // NOI18N
598: return builder.createExit();
599: } else {
600: //System.out.println("Warning: can't recognize dragged item: " + item); // NOI18N
601: }
602: return null;
603: }
604:
605: public FlowlinkTool getFlowLinkTool() {
606: return designView.getFlowLinkTool();
607: }
608: }
|