001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.uml.project.ui.nodes;
043:
044: import org.netbeans.modules.uml.core.eventframework.IEventPayload;
045: import org.netbeans.modules.uml.core.support.umlsupport.Log;
046: import java.awt.dnd.DnDConstants;
047:
048: import java.util.List;
049: import org.openide.filesystems.FileSystem;
050: import org.openide.filesystems.Repository;
051: import org.openide.loaders.DataObject;
052: import org.openide.cookies.InstanceCookie;
053: import org.openide.filesystems.FileObject;
054: import java.awt.datatransfer.Transferable;
055: import java.awt.EventQueue;
056: import java.util.ArrayList;
057: import java.util.LinkedList;
058: import javax.swing.Action;
059: import javax.swing.JSeparator;
060: import java.io.IOException;
061:
062: import org.openide.nodes.AbstractNode;
063: import org.openide.nodes.Children;
064: import org.openide.nodes.Node;
065: import org.openide.util.Lookup;
066: import org.openide.util.actions.SystemAction;
067: import org.netbeans.modules.uml.ui.controls.projecttree.IProjectTreeDragVerify;
068: import org.netbeans.modules.uml.ui.controls.projecttree.IProjectTreeEventDispatcher;
069: import org.netbeans.modules.uml.ui.controls.projecttree.IProjectTreeItem;
070: import org.netbeans.modules.uml.ui.controls.projecttree.ProjectTreeDragVerifyImpl;
071: import org.netbeans.modules.uml.ui.support.DispatchHelper;
072: import org.netbeans.modules.uml.ui.support.projecttreesupport.ITreeItem;
073: import org.netbeans.modules.uml.ui.support.ADTransferable;
074: import org.netbeans.modules.uml.ui.support.diagramsupport.IProxyDiagramManager;
075: import org.netbeans.modules.uml.ui.support.diagramsupport.ProxyDiagramManager;
076: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
077: import org.netbeans.modules.uml.core.metamodel.core.foundation.INamespace;
078: import org.netbeans.modules.uml.core.support.umlutils.ETList;
079: import org.netbeans.modules.uml.core.support.umlutils.ETArrayList;
080: import org.netbeans.modules.uml.project.ui.nodes.actions.NewDiagramType;
081: import org.netbeans.modules.uml.project.ui.nodes.actions.NewPackageType;
082: import org.netbeans.modules.uml.project.ui.nodes.actions.NewElementType;
083: import org.netbeans.modules.uml.project.ui.nodes.actions.NewOperationType;
084: import org.netbeans.modules.uml.project.ui.nodes.actions.NewAttributeType;
085:
086: import org.netbeans.modules.uml.propertysupport.DefinitionPropertyBuilder;
087: import org.openide.actions.*;
088: import org.openide.loaders.DataFolder;
089: import org.openide.nodes.Node.PropertySet;
090: import org.openide.util.datatransfer.ExTransferable;
091: import org.openide.util.datatransfer.NewType;
092: import org.openide.util.datatransfer.PasteType;
093:
094: /**
095: * AbstractModelElementNode model element node is a base node for all nodes that
096: * model represent model elements. AbstractModelElementNode provides the basic
097: * NetBeans node functionality.
098: * <p>
099: * The properties and children will be dynamically discovered by using the
100: * model element to determine the properties and children.
101: * <p>
102: * The DnD operations will be supported in this class as well.
103: *
104: * @author Trey Spiva
105: * @author Craig Conover, craig.conover@sun.com
106: */
107: public abstract class AbstractModelElementNode extends AbstractNode {
108: public final static String ELEMENT_TYPE_PROJECT = "Project"; // NOI18N
109: public final static String ELEMENT_TYPE_PACKAGE = "Package"; // NOI18N
110: public final static String ELEMENT_TYPE_CLASS = "Class"; // NOI18N
111: public final static String ELEMENT_TYPE_DIAGRAM = "Diagram"; // NOI18N
112: public final static String ELEMENT_TYPE_PROXY_DIAGRAM = "ProxyDiagram"; // NOI18N
113: public final static String ELEMENT_TYPE_ACTIVITY = "Activity"; // NOI18N
114: public final static String ELEMENT_TYPE_STATE_MACHINE = "StateMachine"; // NOI18N
115: public final static String ELEMENT_TYPE_INTERACTION = "Interaction"; // NOI18N
116: public final static String ELEMENT_TYPE_INTERFACE = "Interface"; // NOI18N
117: public final static String ELEMENT_TYPE_DATA_TYPE = "DataType"; // NOI18N
118: public final static String ELEMENT_TYPE_ALIASED_TYPE = "AliasedType"; // NOI18N
119: public final static String ELEMENT_TYPE_ATTRIBUTE = "Attribute"; // NOI18N
120: public final static String ELEMENT_TYPE_OPERATION = "Operation"; // NOI18N
121: public final static String ELEMENT_TYPE_PART_FACADE = "PartFacade"; // NOI18N
122: public final static String ELEMENT_TYPE_ARTIFACT = "Artifact"; // NOI18N
123: public final static String ELEMENT_TYPE_NODE = "Node"; // NOI18N
124: public final static String ELEMENT_TYPE_ACTOR = "Actor"; // NOI18N
125: public final static String ELEMENT_TYPE_ENUMERATION = "Enumeration"; // NOI18N
126: public final static String ELEMENT_TYPE_DERIVATION_CLASSIFIER = "DerivationClassifier"; // NOI18N
127: public final static String ELEMENT_TYPE_ASSOCIATION_CLASS = "AssociationClass"; // NOI18N
128: public final static String ELEMENT_TYPE_COLLABORATION = "Collaboration"; // NOI18N
129: public final static String ELEMENT_TYPE_USECASE = "UseCase"; // NOI18N
130: public final static String ELEMENT_TYPE_ACTIVITYGROUP = "ActivityGroup"; // NOI18N
131: public final static String ELEMENT_TYPE_FINALNODE = "FinalNode"; // NOI18N
132: public final static String ELEMENT_TYPE_FINALSTATE = "FinalState"; // NOI18N
133: public final static String ELEMENT_TYPE_FORKNODE = "ForkNode"; // NOI18N
134: public final static String ELEMENT_TYPE_INITIALNODE = "InitialNode"; // NOI18N
135: public final static String ELEMENT_TYPE_INVOCATIONNODE = "InvocationNode"; // NOI18N
136: public final static String ELEMENT_TYPE_LIFELINE = "Lifeline"; // NOI18N
137: public final static String ELEMENT_TYPE_STEREOTYPE = "Stereotype"; // NOI18N
138: public final static String ELEMENT_TYPE_COMMENT = "Comment"; // NOI18N
139: public final static String ELEMENT_TYPE_DEPLOYMENTSPECIFICATION = "DeploymentSpecification"; // NOI18N
140: public final static String ELEMENT_TYPE_COMPONENT = "Component"; // NOI18N
141:
142: public final static String ELEMENT_TYPE_SOURCE_FILE_ARTIFACT = "SourcFileArtifact"; // NOI18N
143: public static final String ELEMENT_TYPE_DEPENDENCY = "Dependency"; // NOI18N
144: public static final String ELEMENT_TYPE_REALIZATION = "Realization"; // NOI18N
145: public static final String ELEMENT_TYPE_USAGE = "Usage"; // NOI18N
146: public static final String ELEMENT_TYPE_PERMISSION = "Permission"; // NOI18N
147: public static final String ELEMENT_TYPE_ABSTRACTION = "Abstraction"; // NOI18N
148: public static final String ELEMENT_TYPE_GENERALIZATION = "Generalization"; // NOI18N
149: public static final String ELEMENT_TYPE_ASSOCIATION = "Association"; // NOI18N
150: public static final String ELEMENT_TYPE_AGGREGATION = "Aggregation"; // NOI18N
151:
152: public final static int NEW_TYPE_DIAGRAM = 0;
153: public final static int NEW_TYPE_PACKAGE = 1;
154: public final static int NEW_TYPE_ELEMENT = 2;
155: public final static int NEW_TYPE_ATTRIBUTE = 3;
156: public final static int NEW_TYPE_OPERATION = 4;
157:
158: public final static Integer[] AVAILABLE_NEW_TYPES = new Integer[] {
159: NEW_TYPE_DIAGRAM, NEW_TYPE_PACKAGE, NEW_TYPE_ELEMENT,
160: NEW_TYPE_ATTRIBUTE, NEW_TYPE_OPERATION };
161:
162: public final static int TOTAL_NEW_TYPES = AVAILABLE_NEW_TYPES.length;
163:
164: public final static String ADDIN_ID_ASSOCIATE_WITH = "AssociateWith"; // NOI18N
165: public final static String ADDIN_ID_DEPENDENCY_DIAGRAM = "DependencyDiagram"; // NOI18N
166: public final static String ADDIN_ID_DIAGRAM_CREATOR = "DiagramCreator"; // NOI18N
167: public final static String ADDIN_ID_GENERATOR_CODE = "GenerateCode"; // NOI18N
168: public final static String ADDIN_ID_REDEFINE_OPERATIONS = "RedefineOperations"; // NOI18N
169: public final static String ADDIN_ID_RE_OPERATION = "REOperation"; // NOI18N
170: public final static String ADDIN_ID_SHOW_AS_XML = "ShowAsXML"; // NOI18N
171:
172: //Cache to improve performance
173: Action newAction = null;
174:
175: /**
176: * Create a new abstract model element node.
177: */
178: public AbstractModelElementNode() {
179: this (new UMLChildren());
180: }
181:
182: public AbstractModelElementNode(Children ch) {
183: this (ch, null);
184: }
185:
186: /**
187: * Create a new abstract model element node and associated lookup.
188: *
189: * @param lookup The lookup to provide content of Node.getLookup() and also
190: * getCookie(java.lang.Class).
191: */
192: //public AbstractModelElementNode(Node node, Lookup lookup)
193: public AbstractModelElementNode(Lookup lookup) {
194: this (new UMLChildren(), lookup);
195: }
196:
197: public AbstractModelElementNode(Children ch, Lookup lookup) {
198: super (ch, lookup);
199: }
200:
201: /**
202: * Retrieve the model element associated with the node.
203: *
204: * @return The associated model element.
205: * @see IElement
206: */
207: public abstract IElement getModelElement();
208:
209: /**
210: * Retrieve the meta-data name for the model element.
211: *
212: * @param The meta data name.
213: */
214: public String getElementType() {
215: String retVal = ""; // NOI18N
216:
217: IElement element = getModelElement();
218: if (element != null) {
219: retVal = element.getElementType();
220: }
221:
222: return retVal;
223: }
224:
225: public void setDisplayName(String s) {
226: setDisplayName(s, true);
227: }
228:
229: // conover
230: public void setDisplayName(String s, boolean notify) {
231: super .setDisplayName(s);
232:
233: if (notify)
234: notifyPropertySetsChange();
235: }
236:
237: //**************************************************
238: // Node Overrides
239: //**************************************************
240:
241: /**
242: * Get the new types that can be created in this node. For example, a node
243: * representing a class will permit attributes, operations, classes,
244: * interfaces, and enumerations to be added.
245: *
246: * @return An array of new type operations that are allowed.
247: */
248: public NewType[] getNewTypes() {
249: String elType = getElementType();
250: NewType[] retVal = null;
251:
252: if (getModelElement() instanceof INamespace) {
253: // Diagram types: Use Case Diagram, Deployment Diagram
254: if (elType.equals(ELEMENT_TYPE_PROXY_DIAGRAM)
255: || elType.equals(ELEMENT_TYPE_DIAGRAM)) {
256: return new NewType[] { new NewPackageType(this ),
257: new NewElementType(this ) };
258: }
259:
260: else if (elType.equals(ELEMENT_TYPE_PROJECT)) {
261: return new NewType[] { new NewDiagramType(this ),
262: new NewPackageType(this ),
263: new NewElementType(this ) };
264: }
265:
266: // Interaction types: Sequence Diagram, Collaboration Diagram
267: // StateMachine types: State Diagram
268: // Activity types: Activity Diagram
269: else if (elType.equals(ELEMENT_TYPE_INTERACTION)
270: || elType.equals(ELEMENT_TYPE_STATE_MACHINE)
271: || elType.equals(ELEMENT_TYPE_ACTIVITY)) {
272: return new NewType[] { new NewDiagramType(this ),
273: new NewPackageType(this ),
274: new NewElementType(this ),
275: new NewAttributeType(this ),
276: new NewOperationType(this ) };
277: }
278: } // if getModelElement() instanceof INamespace
279:
280: // The NewAction code does not check for null. Therefore, we have
281: // to create a new object just to keep them from throwing.
282: if (retVal == null) {
283: retVal = new NewType[0];
284: }
285:
286: return retVal;
287: }
288:
289: /**
290: * Retrieves the actions for the node. This method only returns
291: * the context sensitive actions.
292: *
293: * @param context Whether to find actions for context meaning or for the
294: * node itself
295: * @return A list of actions (you may include nulls for separators)
296: */
297: public Action[] getActions(boolean context) {
298: ArrayList<Action> actions = new ArrayList<Action>();
299:
300: actions.add(SystemAction.get(OpenAction.class));
301:
302: // cvc - CR 6287660 & 6276911
303: //commented out - moved to getNewAction() to improve performance
304: /*if (!(getParentNode() instanceof UMLDiagramsRootNode) &&
305: !elemType.equals(ELEMENT_TYPE_ABSTRACTION) &&
306: !elemType.equals(ELEMENT_TYPE_AGGREGATION) &&
307: !elemType.equals(ELEMENT_TYPE_ASSOCIATION) &&
308: !elemType.equals(ELEMENT_TYPE_DEPENDENCY) &&
309: !elemType.equals(ELEMENT_TYPE_GENERALIZATION) &&
310: !elemType.equals(ELEMENT_TYPE_PERMISSION) &&
311: !elemType.equals(ELEMENT_TYPE_REALIZATION) &&
312: !elemType.equals(ELEMENT_TYPE_USAGE))*/
313: Action action = getNewAction();
314: if (action != null) {
315: actions.add(action);
316: }
317:
318: actions.add(null);
319:
320: actions.add(SystemAction.get(DeleteAction.class));
321: actions.add(SystemAction.get(RenameAction.class));
322:
323: actions.add(null);
324:
325: addContextMenus(actions);
326:
327: actions.add(null);
328:
329: // actions.add(SystemAction.get(SourceControlSubMenuAction.class));
330: //To improve performance, cache this action
331:
332: // Source control Sub menu Actions are created based on the SCM status of the nodes so every time we need
333: //to get the actions freshly so they can't be checked for null
334: /* if(scSubMenuAction==null)
335: scSubMenuAction=new SourceControlSubMenuAction();
336: actions.add(scSubMenuAction);
337: */
338: actions.add(null);
339:
340: actions.add(SystemAction.get(PropertiesAction.class));
341:
342: Action[] retVal = new Action[actions.size()];
343: actions.toArray(retVal);
344: return retVal;
345: }
346:
347: private Action getNewAction() {
348: // TODO: this needs to be reviewed as to what node should have new type action
349:
350: if (newAction == null) {
351: String elemType = getElementType();
352: if (!(getParentNode() instanceof UMLDiagramsRootNode)
353: && getModelElement() != null
354: && !elemType.equals(ELEMENT_TYPE_ABSTRACTION)
355: && !elemType.equals(ELEMENT_TYPE_AGGREGATION)
356: && !elemType.equals(ELEMENT_TYPE_ASSOCIATION)
357: && !elemType.equals(ELEMENT_TYPE_DEPENDENCY)
358: && !elemType.equals(ELEMENT_TYPE_GENERALIZATION)
359: && !elemType.equals(ELEMENT_TYPE_PERMISSION)
360: && !elemType.equals(ELEMENT_TYPE_REALIZATION)
361: && !elemType.equals(ELEMENT_TYPE_USAGE)
362: && !elemType.equals(ELEMENT_TYPE_ACTOR)
363: && !elemType.equals(ELEMENT_TYPE_DIAGRAM)
364: && !elemType.equals(ELEMENT_TYPE_PROXY_DIAGRAM)
365: && !elemType.equals("")) {
366: //newAction=SystemAction.get(NewAction.class);
367: Action[] newActions = getNewMenuAction();
368: if (newActions != null && newActions.length > 0) {
369: newAction = newActions[0];
370: }
371: }
372: }
373: return newAction;
374: }
375:
376: /**
377: * Retrievse the for the model element using property elements and property
378: * definitions. The property elements allow us to use a configuration file
379: * to specify the properties that should be displayed.
380: *
381: * @see org.netbeans.modules.uml.core.support.umlutils.IPropertyDefinition
382: * @see org.netbeans.modules.uml.core.support.umlutils.IPropertyElement
383: * @see org.netbeans.modules.uml.core.support.umlutils.IPropertyDefinitionFactory
384: * @see org.openide.nodes.Node#getPropertySets()
385: */
386: public Node.PropertySet[] getPropertySets() {
387: Node.PropertySet[] retVal = null;
388:
389: Node.PropertySet[] parentSet = super .getPropertySets();
390:
391: // The model element my not be set yet. If the model element is not set
392: // then we do not want only want to return the parents property set.
393: String elementType = getElementType();
394:
395: if (elementType.length() > 0) {
396: PropertySet[] elementProperties = retreiveProperties();
397: if (elementProperties != null) {
398: retVal = new PropertySet[parentSet.length
399: + elementProperties.length];
400: System.arraycopy(elementProperties, 0, retVal, 0,
401: elementProperties.length);
402: System.arraycopy(parentSet, 0, retVal,
403: elementProperties.length, parentSet.length);
404: }
405:
406: else {
407: retVal = parentSet;
408: }
409: }
410:
411: else {
412: retVal = parentSet;
413: }
414:
415: return retVal;
416: }
417:
418: @Override
419: public Transferable clipboardCopy() throws IOException {
420: ADTransferable retVal = new ADTransferable("DRAGGEDITEMS"); // NOI18N
421: retVal.addModelElement(getModelElement());
422:
423: DispatchHelper heleper = new DispatchHelper();
424: IProjectTreeEventDispatcher disp = heleper
425: .getProjectTreeDispatcher();
426:
427: if (disp != null) {
428: IEventPayload payload = disp
429: .createPayload("ProjectTreeBeginDrag"); // NOI18N
430: IProjectTreeDragVerify context = new ProjectTreeDragVerifyImpl();
431:
432: if (this instanceof ITreeItem) {
433: IProjectTreeItem[] items = { ((ITreeItem) this )
434: .getData() };
435: disp.fireBeginDrag(null, items, context, payload);
436: }
437:
438: }
439: return retVal;
440: }
441:
442: public Transferable clipboardCut() throws IOException {
443: return clipboardCopy();
444: }
445:
446: public boolean canDestroy() {
447: Lookup lkp = getLookup();
448: boolean canDestroy = lkp.lookup(IProjectTreeItem.class) != null;
449: return canDestroy;
450: }
451:
452: public void destroy() throws IOException {
453: // Gather up all the diagrams and model elements
454: // in preparation for deleting.
455: final ETList<IElement> modelElements = new ETArrayList<IElement>();
456: final List<String> diagrams = new LinkedList<String>();
457:
458: IProjectTreeItem treeItem = this .getLookup().lookup(
459: IProjectTreeItem.class);
460:
461: if (treeItem == null)
462: return;
463:
464: // If this item is a model element then add to the list of model
465: // elements, if it's a diagram then add it to the list of names
466: // associated with the diagrams.
467: if (treeItem.isImportedPackage()) {
468: if (treeItem.getImportedPackage() != null)
469: modelElements.add(treeItem.getImportedPackage());
470: }
471:
472: else if (treeItem.isImportedModelElement()) {
473: if (treeItem.getImportedModelElement() != null)
474: modelElements.add(treeItem.getImportedModelElement());
475: } else if (treeItem.isDiagram()) {
476: if (treeItem.getDescription() != null
477: && treeItem.getDescription().length() > 0) {
478: diagrams.add(treeItem.getDescription());
479: }
480: } else if (treeItem.getModelElement() != null) {
481: IElement elem = treeItem.getModelElement();
482: modelElements.add(elem);
483: }
484:
485: Runnable runnable = new Runnable() {
486: public void run() {
487: synchronized (deleteLock) {
488: if (inDelete) {
489: EventQueue.invokeLater(this );
490: return;
491: } else {
492: inDelete = true;
493: }
494: }
495:
496: try {
497: // Now actually do the delete of the model elements
498: for (final IElement curModelElement : modelElements) {
499: curModelElement.delete();
500: }
501:
502: // Now whack the diagrams
503: final IProxyDiagramManager proxyDiagramManager = ProxyDiagramManager
504: .instance();
505:
506: for (final String curDiagramName : diagrams) {
507: proxyDiagramManager
508: .removeDiagram(curDiagramName);
509: }
510: } finally {
511: inDelete = false;
512: }
513: }
514: };
515:
516: EventQueue.invokeLater(runnable);
517: }
518:
519: private static boolean inDelete = false;
520: private static Object deleteLock = new Object();
521:
522: public boolean canCut() {
523: return true;
524: }
525:
526: protected void createPasteTypes(Transferable t, List s) {
527: super .createPasteTypes(t, s);
528: PasteType type = getDropType(t, DnDConstants.ACTION_COPY, -1);
529: if (type != null) {
530: s.add(type);
531: }
532: }
533:
534: public PasteType getDropType(Transferable trans, int action,
535: int index) {
536: PasteType retVal = null;
537:
538: // cvc - CR 6363187 - can't DnD more than one model element in tree
539: // This method has been overhauled to fix the bug.
540:
541: try {
542: if (trans instanceof ADTransferable) {
543: if (trans
544: .isDataFlavorSupported(ADTransferable.ADDataFlavor)) {
545: Object obj = trans
546: .getTransferData(ADTransferable.ADDataFlavor);
547: ADTransferable adTrans = (ADTransferable) trans;
548:
549: if (obj != null) {
550: if (this instanceof ITreeItem) {
551: ITreeItem item = (ITreeItem) this ;
552: IProjectTreeItem data = item.getData();
553: retVal = new ModelPasteType(trans, data,
554: action);
555: }
556: }
557: } // if - isDataFlavorSupported
558: } // if - ADTransferable
559:
560: else if (trans instanceof ExTransferable) {
561: ExTransferable exTrans = (ExTransferable) trans;
562:
563: if (this instanceof ITreeItem) {
564: ITreeItem item = (ITreeItem) this ;
565: IProjectTreeItem data = item.getData();
566: retVal = new ModelPasteType(exTrans, data, action);
567: }
568: }
569:
570: else {
571: Log
572: .write("Unexpected Transferrable subtype parameter, " // NOI18N
573: + trans.getClass().getName()
574: + ". Should not be " // NOI18N
575: + "an issue but proactively logging ocurrence."); // NOI18N
576: }
577: } // try
578:
579: catch (Exception e) {
580: Log.stackTrace(e);
581: }
582:
583: return retVal;
584: }
585:
586: protected Action[] getNewMenuAction() {
587: return getActionsFromRegistry("contextmenu/uml/newtypes"); // NOI18N
588: }
589:
590: protected void getNewMenuAction(List actions) {
591: Action[] nodeActions = getActionsFromRegistry("contextmenu/uml/newtypes"); // NOI18N
592: if (nodeActions != null) {
593: for (Action curAction : nodeActions) {
594: if (curAction == null) {
595: // Make Sure the Seperators are kept.
596: actions.add(null);
597: } else if (curAction != null && curAction.isEnabled()) {
598: actions.add(curAction);
599: }
600: }
601: actions.add(null); // add a Separator
602: }
603: }
604:
605: /**
606: * Retrieve the context actions added by other modules.
607: *
608: * @param actions The action collection to add the actions to.
609: */
610: protected void addContextMenus(ArrayList<Action> actions) {
611: Action[] nodeActions = getActionsFromRegistry("contextmenu/uml/element"); // NOI18N
612:
613: for (Action curAction : nodeActions) {
614: if (curAction == null)
615: // Make Sure the Seperators are kept.
616: actions.add(null);
617:
618: else if (curAction.isEnabled())
619: actions.add(curAction);
620: }
621: }
622:
623: /**
624: * The registry information that is retrieved from layer files to build
625: * the list of actions supported by this node.
626: *
627: * @param path The registry path that is used for the lookup.
628: * @return The list of actions in the path. null will be used if when
629: * seperators can be placed.
630: */
631: protected Action[] getActionsFromRegistry(String path) {
632: ArrayList<Action> actions = new ArrayList<Action>();
633: FileSystem system = Repository.getDefault()
634: .getDefaultFileSystem();
635:
636: if (system != null) {
637: FileObject fo = system.findResource(path);
638: DataFolder df = fo != null ? DataFolder.findFolder(fo)
639: : null;
640: if (df != null) {
641: DataObject actionObjects[] = df.getChildren();
642: for (int i = 0; i < actionObjects.length; i++) {
643: InstanceCookie ic = actionObjects[i]
644: .getCookie(InstanceCookie.class);
645: if (ic == null)
646: continue;
647: Object instance;
648: try {
649: instance = ic.instanceCreate();
650: } catch (IOException e) {
651: // ignore
652: e.printStackTrace();
653: continue;
654: } catch (ClassNotFoundException e) {
655: // ignore
656: e.printStackTrace();
657: continue;
658: }
659: if (instance instanceof Action)
660: actions.add((Action) instance);
661: else if (instance instanceof JSeparator)
662: actions.add(null);
663: }
664: }
665: }
666:
667: Action[] retVal = new Action[actions.size()];
668: actions.toArray(retVal);
669: return retVal;
670: }
671:
672: protected Node.PropertySet[] retreiveProperties() {
673: Node.PropertySet[] retVal = null;
674:
675: retVal = buildProperties();
676:
677: return retVal;
678: }
679:
680: // Jyothi: Fix for Bug#6258627-Naming a component doesn't update the property sheet Name to the new value.
681: // This method is a hack.. and is NOT supposed to be used in any other scenario
682: public void notifyPropertySetsChange() {
683: firePropertySetsChange(null, retreiveProperties());
684: }
685:
686: /**
687: * Builds the proerty set structure for all model elements.
688: */
689: protected Node.PropertySet[] buildProperties() {
690: Node.PropertySet[] retVal = null;
691:
692: IElement element = getModelElement();
693:
694: if (element != null) {
695: DefinitionPropertyBuilder builder = DefinitionPropertyBuilder
696: .instance();
697: retVal = builder.retreiveProperties(element
698: .getElementType(), element);
699: }
700:
701: return retVal;
702: }
703:
704: public class ModelPasteType extends PasteType {
705: // cvc - CR 6363187 - can't DnD more than one model element in tree
706: // This inner class has been overhauled to fix the bug.
707:
708: private IProjectTreeItem mTreeItem = null;
709: private Transferable mTransferable = null;
710: private int mAction = DnDConstants.ACTION_NONE;
711:
712: public ModelPasteType(Transferable transferable,
713: IProjectTreeItem data, int action) {
714: mTreeItem = data;
715: mTransferable = transferable;
716: mAction = action;
717: }
718:
719: public Transferable paste() throws IOException {
720: fireEndDrag();
721: return null;
722: }
723:
724: /**
725: * Notifies listeners that the drag process has been completed. This event
726: * is only fired if project tree is the drop target.
727: */
728: public boolean fireEndDrag() {
729: boolean retVal = true;
730:
731: if (mAction != DnDConstants.ACTION_NONE) {
732: DispatchHelper dispatcherHelper = new DispatchHelper();
733: IProjectTreeEventDispatcher disp = dispatcherHelper
734: .getProjectTreeDispatcher();
735:
736: if (disp != null) {
737: IEventPayload payload = disp
738: .createPayload("ProjectTreeEndDrag"); // NOI18N
739: IProjectTreeDragVerify context = new ProjectTreeDragVerifyImpl();
740: context.setTargetNode(mTreeItem);
741:
742: disp.fireEndDrag(null, mTransferable, mAction,
743: context, payload);
744:
745: retVal = !context.isCancel();
746: }
747: }
748: return retVal;
749: }
750: }
751: }
|