Coverage Report - org.argouml.uml.diagram.activity.ui.UMLActivityDiagram
 
Classes in this File Line Coverage Branch Coverage Complexity
UMLActivityDiagram
47%
121/255
21%
36/166
3.128
 
 1  
 /* $Id: UMLActivityDiagram.java 17853 2010-01-12 19:55:46Z linus $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009 Contributors - see below
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    bobtarling
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 1996-2008 The Regents of the University of California. All
 17  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 18  
 // software and its documentation without fee, and without a written
 19  
 // agreement is hereby granted, provided that the above copyright notice
 20  
 // and this paragraph appear in all copies.  This software program and
 21  
 // documentation are copyrighted by The Regents of the University of
 22  
 // California. The software program and documentation are supplied "AS
 23  
 // IS", without any accompanying services from The Regents. The Regents
 24  
 // does not warrant that the operation of the program will be
 25  
 // uninterrupted or error-free. The end-user understands that the program
 26  
 // was developed for research purposes and is advised not to rely
 27  
 // exclusively on the program for any reason.  IN NO EVENT SHALL THE
 28  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 29  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 30  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 31  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 32  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 33  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 34  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 35  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 36  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 37  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 38  
 
 39  
 package org.argouml.uml.diagram.activity.ui;
 40  
 
 41  
 import java.awt.Rectangle;
 42  
 import java.beans.PropertyChangeEvent;
 43  
 import java.beans.PropertyVetoException;
 44  
 import java.util.ArrayList;
 45  
 import java.util.Collection;
 46  
 import java.util.Collections;
 47  
 import java.util.HashMap;
 48  
 import java.util.HashSet;
 49  
 import java.util.Iterator;
 50  
 import java.util.List;
 51  
 
 52  
 import javax.swing.Action;
 53  
 
 54  
 import org.apache.log4j.Logger;
 55  
 import org.argouml.i18n.Translator;
 56  
 import org.argouml.model.ActivityGraphsHelper;
 57  
 import org.argouml.model.DeleteInstanceEvent;
 58  
 import org.argouml.model.Model;
 59  
 import org.argouml.ui.CmdCreateNode;
 60  
 import org.argouml.uml.diagram.DiagramElement;
 61  
 import org.argouml.uml.diagram.DiagramSettings;
 62  
 import org.argouml.uml.diagram.UMLMutableGraphSupport;
 63  
 import org.argouml.uml.diagram.activity.ActivityDiagramGraphModel;
 64  
 import org.argouml.uml.diagram.state.StateDiagramGraphModel;
 65  
 import org.argouml.uml.diagram.state.ui.ActionCreatePseudostate;
 66  
 import org.argouml.uml.diagram.state.ui.ButtonActionNewCallEvent;
 67  
 import org.argouml.uml.diagram.state.ui.ButtonActionNewChangeEvent;
 68  
 import org.argouml.uml.diagram.state.ui.ButtonActionNewSignalEvent;
 69  
 import org.argouml.uml.diagram.state.ui.ButtonActionNewTimeEvent;
 70  
 import org.argouml.uml.diagram.state.ui.FigBranchState;
 71  
 import org.argouml.uml.diagram.state.ui.FigFinalState;
 72  
 import org.argouml.uml.diagram.state.ui.FigForkState;
 73  
 import org.argouml.uml.diagram.state.ui.FigInitialState;
 74  
 import org.argouml.uml.diagram.state.ui.FigJoinState;
 75  
 import org.argouml.uml.diagram.state.ui.FigJunctionState;
 76  
 import org.argouml.uml.diagram.state.ui.FigStateVertex;
 77  
 import org.argouml.uml.diagram.static_structure.ui.FigComment;
 78  
 import org.argouml.uml.diagram.ui.ActionSetMode;
 79  
 import org.argouml.uml.diagram.ui.FigNodeModelElement;
 80  
 import org.argouml.uml.diagram.ui.RadioAction;
 81  
 import org.argouml.uml.diagram.ui.UMLDiagram;
 82  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewActionSequence;
 83  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewCallAction;
 84  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewCreateAction;
 85  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewDestroyAction;
 86  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewReturnAction;
 87  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewSendAction;
 88  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewTerminateAction;
 89  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewUninterpretedAction;
 90  
 import org.argouml.uml.ui.behavior.state_machines.ButtonActionNewGuard;
 91  
 import org.argouml.util.ToolBarUtility;
 92  
 import org.tigris.gef.base.LayerPerspective;
 93  
 import org.tigris.gef.base.LayerPerspectiveMutable;
 94  
 import org.tigris.gef.base.ModeCreatePolyEdge;
 95  
 import org.tigris.gef.graph.GraphModel;
 96  
 import org.tigris.gef.presentation.Fig;
 97  
 import org.tigris.gef.presentation.FigNode;
 98  
 
 99  
 /**
 100  
  * The Activity diagram.<p>
 101  
  *
 102  
  * TODO: Finish the work on subactivity states.
 103  
  */
 104  19
 public class UMLActivityDiagram extends UMLDiagram {
 105  
     
 106  
     /**
 107  
      * Logger.
 108  
      */
 109  19
     private static final Logger LOG =
 110  
         Logger.getLogger(UMLActivityDiagram.class);
 111  
     
 112  
     /**
 113  
      * The UID.
 114  
      */
 115  
     private static final long serialVersionUID = 6223128918989919230L;
 116  
     
 117  
     /**
 118  
      * this diagram needs to be deleted when its statemachine is deleted.
 119  
      */
 120  
     private Object theActivityGraph;
 121  
 
 122  
     private Action actionState;
 123  
     private Action actionStartPseudoState;
 124  
     private Action actionFinalPseudoState;
 125  
     private Action actionJunctionPseudoState;
 126  
     private Action actionForkPseudoState;
 127  
     private Action actionJoinPseudoState;
 128  
     private Action actionTransition;
 129  
     private Action actionObjectFlowState;
 130  
     private Action actionSwimlane;
 131  
     private Action actionCallState;
 132  
     private Action actionSubactivityState;
 133  
     private Action actionCallEvent;
 134  
     private Action actionChangeEvent;
 135  
     private Action actionSignalEvent;
 136  
     private Action actionTimeEvent;
 137  
     private Action actionGuard;
 138  
     private Action actionCallAction;
 139  
     private Action actionCreateAction;
 140  
     private Action actionDestroyAction;
 141  
     private Action actionReturnAction;
 142  
     private Action actionSendAction;
 143  
     private Action actionTerminateAction;
 144  
     private Action actionUninterpretedAction;
 145  
     private Action actionActionSequence;
 146  
 
 147  
     /**
 148  
      * Constructor.
 149  
      * 
 150  
      * @deprecated for 0.28 by tfmorris.  Use 
 151  
      * {@link #UMLActivityDiagram(String, Object, GraphModel)}.
 152  
      */
 153  
     @Deprecated
 154  
     public UMLActivityDiagram() {
 155  19
         super();
 156  
         try {
 157  19
             setName(getNewDiagramName());
 158  0
         } catch (PropertyVetoException pve) {
 159  
             // no action required in case of veto on setName
 160  19
         }
 161  
         // TODO: All super constructors should take a GraphModel
 162  19
         setGraphModel(createGraphModel());
 163  19
     }
 164  
 
 165  
     /**
 166  
      * Constructor.
 167  
      *
 168  
      * @param namespace the namespace for the diagram
 169  
      * @param agraph the ActivityGraph for the diagram
 170  
      * @deprecated for 0.28 by tfmorris.  Use 
 171  
      * {@link #UMLActivityDiagram(String, Object, GraphModel)}.
 172  
      */
 173  
     @Deprecated
 174  
     public UMLActivityDiagram(Object namespace, Object agraph) {
 175  
 
 176  19
         this();
 177  
 
 178  19
         if (namespace == null) {
 179  19
             namespace = Model.getFacade().getNamespace(agraph);
 180  
         }
 181  
         
 182  19
         if (!Model.getFacade().isANamespace(namespace)
 183  
             || !Model.getFacade().isAActivityGraph(agraph)) {
 184  0
             throw new IllegalArgumentException();
 185  
         }
 186  
 
 187  19
         if (Model.getFacade().getName(namespace) != null) {
 188  19
             if (!Model.getFacade().getName(namespace).trim().equals("")) {
 189  19
                 String name =
 190  
                     Model.getFacade().getName(namespace)
 191  
                     + " activity "
 192  
                     + (Model.getFacade().getBehaviors(namespace).size());
 193  
                 try {
 194  19
                     setName(name);
 195  0
                 } catch (PropertyVetoException pve) {
 196  
                     // no action required
 197  19
                 }
 198  
             }
 199  
         }
 200  19
         setup(namespace, agraph);
 201  19
     }
 202  
 
 203  
     /*
 204  
      * @see org.tigris.gef.base.Diagram#initialize(java.lang.Object)
 205  
      */
 206  
     public void initialize(Object o) {
 207  0
         if (!(Model.getFacade().isAActivityGraph(o))) {
 208  0
             return;
 209  
         }
 210  0
         Object context = Model.getFacade().getContext(o);
 211  0
         if (context != null) {
 212  0
             if (Model.getFacade().isABehavioralFeature(context)) {
 213  0
                 setup(Model.getFacade().getNamespace(
 214  
                                 Model.getFacade().getOwner(context)), o);
 215  
             } else {
 216  0
                 setup(context, o);
 217  
             }
 218  
         } else {
 219  0
             Object namespace4Diagram = Model.getFacade().getNamespace(o);
 220  0
             if (namespace4Diagram != null) {
 221  0
                 setup(namespace4Diagram, o);
 222  
             } else {
 223  0
                 throw new IllegalStateException("Cannot find context "
 224  
                         + "nor namespace while initializing activity diagram");
 225  
             }
 226  
         }
 227  0
     }
 228  
 
 229  
     /**
 230  
      * Method to perform a number of important initializations of an
 231  
      * <em>Activity Diagram</em>.<p>
 232  
      *
 233  
      * Each diagram type has a similar <em>UMLxxxDiagram</em> class.<p>
 234  
      *
 235  
      * Changed <em>lay</em> from <em>LayerPerspective</em> to
 236  
      * <em>LayerPerspectiveMutable</em>.  This class is a child of
 237  
      * <em>LayerPerspective</em> and was implemented to correct some
 238  
      * difficulties in changing the model. <em>lay</em> is used mainly
 239  
      * in <em>LayerManager</em>(GEF) to control the adding, changing and
 240  
      * deleting layers on the diagram...  psager@tigris.org Jan. 24,
 241  
      * 2002
 242  
 
 243  
      * @param namespace  Namespace from the model
 244  
      * @param agraph ActivityGraph from the model
 245  
      */
 246  
     public void setup(Object namespace, Object agraph) {
 247  19
         if (!Model.getFacade().isANamespace(namespace)
 248  
             || !Model.getFacade().isAActivityGraph(agraph)) {
 249  0
             throw new IllegalArgumentException();
 250  
         }
 251  
 
 252  19
         setNamespace(namespace);
 253  
 
 254  19
         theActivityGraph = agraph;
 255  
         
 256  
         
 257  19
         ActivityDiagramGraphModel gm = createGraphModel();
 258  
         
 259  19
         gm.setHomeModel(namespace);
 260  19
         if (theActivityGraph != null) {
 261  19
             gm.setMachine(theActivityGraph);
 262  
         }
 263  19
         ActivityDiagramRenderer rend = new ActivityDiagramRenderer();
 264  
 
 265  19
         LayerPerspective lay = new LayerPerspectiveMutable(
 266  
                 Model.getFacade().getName(namespace), gm);
 267  19
         lay.setGraphNodeRenderer(rend);
 268  19
         lay.setGraphEdgeRenderer(rend);
 269  19
         setLayer(lay);
 270  
 
 271  
         /* Listen to activitygraph deletion, 
 272  
          * delete this diagram. */
 273  19
         Model.getPump().addModelEventListener(this, theActivityGraph, 
 274  
                 new String[] {"remove", "namespace"});
 275  19
     }
 276  
     
 277  
     // TODO: Needs to be tidied up after stable release. Graph model
 278  
     // should be created in constructor
 279  
     private ActivityDiagramGraphModel createGraphModel() {
 280  38
         if ((getGraphModel() instanceof ActivityDiagramGraphModel)) {
 281  19
             return (ActivityDiagramGraphModel) getGraphModel();
 282  
         } else {
 283  19
             return new ActivityDiagramGraphModel();
 284  
         }
 285  
     }
 286  
     
 287  
     /*
 288  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#propertyChange(java.beans.PropertyChangeEvent)
 289  
      */
 290  
     public void propertyChange(PropertyChangeEvent evt) {
 291  0
         if ((evt.getSource() == theActivityGraph)
 292  
                 && (evt instanceof DeleteInstanceEvent)
 293  
                 && "remove".equals(evt.getPropertyName())) {
 294  0
             Model.getPump().removeModelEventListener(this, 
 295  
                     theActivityGraph, new String[] {"remove", "namespace"});
 296  0
             getProject().moveToTrash(this);
 297  
         }
 298  0
         if (evt.getSource() == getStateMachine()) {
 299  0
             Object newNamespace = 
 300  
                 Model.getFacade().getNamespace(getStateMachine());
 301  0
             if (getNamespace() != newNamespace) {
 302  
                 /* The namespace of the activitygraph is changed! */
 303  0
                 setNamespace(newNamespace);
 304  0
                 ((UMLMutableGraphSupport) getGraphModel())
 305  
                                 .setHomeModel(newNamespace);
 306  
             }
 307  
         }
 308  0
     }
 309  
 
 310  
     /*
 311  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getOwner()
 312  
      */
 313  
     public Object getOwner() {
 314  164
         if (!(getGraphModel() instanceof ActivityDiagramGraphModel)) {
 315  0
             throw new IllegalStateException(
 316  
                     "Incorrect graph model of "
 317  
                     + getGraphModel().getClass().getName());
 318  
         }
 319  164
         ActivityDiagramGraphModel gm =
 320  
             (ActivityDiagramGraphModel) getGraphModel();
 321  164
         return gm.getMachine();
 322  
     }
 323  
 
 324  
     /**
 325  
      * @return the statemachine
 326  
      * 
 327  
      * TODO: If this method is called by any of the Figs, it will introduce
 328  
      * a dependency cycle.  It would be much better if they could just
 329  
      * use {@link org.argouml.uml.diagram.ArgoDiagram#getOwner()} which does
 330  
      * the same thing.
 331  
      */
 332  
     public Object getStateMachine() {
 333  19
         GraphModel gm = getGraphModel();
 334  19
         if (gm instanceof StateDiagramGraphModel) {
 335  19
             Object machine = ((StateDiagramGraphModel) gm).getMachine();
 336  19
             if (!Model.getUmlFactory().isRemoved(machine)) {
 337  19
                 return machine;
 338  
             }
 339  
         }
 340  0
         return null;
 341  
     }
 342  
 
 343  
     /**
 344  
      * @param sm set the statemachine for this diagram
 345  
      */
 346  
     public void setStateMachine(Object sm) {
 347  
 
 348  0
         if (!Model.getFacade().isAStateMachine(sm)) {
 349  0
             throw new IllegalArgumentException();
 350  
         }
 351  
 
 352  0
         ((ActivityDiagramGraphModel) getGraphModel()).setMachine(sm);
 353  0
     }
 354  
 
 355  
     /**
 356  
      * Get the actions from which to create a toolbar or equivalent
 357  
      * graphic triggers.
 358  
      *
 359  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getUmlActions()
 360  
      * @return the array of actions
 361  
      */
 362  
     protected Object[] getUmlActions() {
 363  19
         Object[] actions =
 364  
         {
 365  
             getActionState(),
 366  
             getActionTransition(),
 367  
             null,
 368  
             getActionStartPseudoState(),
 369  
             getActionFinalPseudoState(),
 370  
             getActionJunctionPseudoState(),
 371  
             getActionForkPseudoState(),
 372  
             getActionJoinPseudoState(),
 373  
             getActionSwimlane(),
 374  
             null,
 375  
             getActionCallState(),
 376  
             getActionObjectFlowState(),
 377  
             /*getActionSubactivityState()*/
 378  
             null,
 379  
             getTriggerActions(),
 380  
             getActionGuard(),
 381  
             getEffectActions(),
 382  
         };
 383  19
         return actions;
 384  
     }
 385  
 
 386  
     protected Object[] getTriggerActions() {
 387  19
         Object[] actions = {
 388  
             getActionCallEvent(),
 389  
             getActionChangeEvent(),
 390  
             getActionSignalEvent(),
 391  
             getActionTimeEvent(),
 392  
         };
 393  19
         ToolBarUtility.manageDefault(actions, "diagram.activity.trigger");
 394  19
         return actions;
 395  
     }
 396  
 
 397  
     protected Object[] getEffectActions() {
 398  19
         Object[] actions = {
 399  
             getActionCallAction(),
 400  
             getActionCreateAction(),
 401  
             getActionDestroyAction(),
 402  
             getActionReturnAction(),
 403  
             getActionSendAction(),
 404  
             getActionTerminateAction(),
 405  
             getActionUninterpretedAction(),
 406  
             getActionActionSequence(),
 407  
         };
 408  19
         ToolBarUtility.manageDefault(actions, "diagram.activity.effect");
 409  19
         return actions;
 410  
     }
 411  
 
 412  
     /*
 413  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getLabelName()
 414  
      */
 415  
     public String getLabelName() {
 416  19
         return Translator.localize("label.activity-diagram");
 417  
     }
 418  
 
 419  
     /**
 420  
      * @return Returns the actionCallState.
 421  
      */
 422  
     protected Action getActionCallState() {
 423  19
         if (actionCallState == null) {
 424  19
             actionCallState =
 425  
                 new RadioAction(
 426  
                         new CmdCreateNode(
 427  
                                 Model.getMetaTypes().getCallState(),
 428  
                                 "button.new-callstate"));
 429  
         }
 430  19
         return actionCallState;
 431  
     }
 432  
     /**
 433  
      * @return Returns the actionFinalPseudoState.
 434  
      */
 435  
     protected Action getActionFinalPseudoState() {
 436  19
         if (actionFinalPseudoState == null) {
 437  19
             actionFinalPseudoState =
 438  
                 new RadioAction(
 439  
                         new CmdCreateNode(
 440  
                                 Model.getMetaTypes().getFinalState(),
 441  
                                 "button.new-finalstate"));
 442  
         }
 443  19
         return actionFinalPseudoState;
 444  
     }
 445  
     /**
 446  
      * @return Returns the actionForkPseudoState.
 447  
      */
 448  
     protected Action getActionForkPseudoState() {
 449  19
         if (actionForkPseudoState == null) {
 450  19
             actionForkPseudoState =
 451  
                 new RadioAction(
 452  
                         new ActionCreatePseudostate(
 453  
                                 Model.getPseudostateKind().getFork(),
 454  
                                 "button.new-fork"));
 455  
         }
 456  19
         return actionForkPseudoState;
 457  
     }
 458  
     /**
 459  
      * @return Returns the actionJoinPseudoState.
 460  
      */
 461  
     protected Action getActionJoinPseudoState() {
 462  19
         if (actionJoinPseudoState == null) {
 463  19
             actionJoinPseudoState =
 464  
                 new RadioAction(
 465  
                         new ActionCreatePseudostate(
 466  
                                 Model.getPseudostateKind().getJoin(),
 467  
                                 "button.new-join"));
 468  
         }
 469  19
         return actionJoinPseudoState;
 470  
     }
 471  
     /**
 472  
      * @return Returns the actionJunctionPseudoState.
 473  
      */
 474  
     protected Action getActionJunctionPseudoState() {
 475  19
         if (actionJunctionPseudoState == null) {
 476  19
             actionJunctionPseudoState =
 477  
                 new RadioAction(
 478  
                         new ActionCreatePseudostate(
 479  
                                 Model.getPseudostateKind().getJunction(),
 480  
                                 "button.new-junction"));
 481  
         }
 482  19
         return actionJunctionPseudoState;
 483  
     }
 484  
     /**
 485  
      * @return Returns the actionSwimlane.
 486  
      */
 487  
     protected Action getActionSwimlane() {
 488  19
         if (actionSwimlane == null) {
 489  19
             actionSwimlane =
 490  
                 new ActionCreatePartition(getStateMachine());
 491  
         }
 492  19
         return actionSwimlane;
 493  
     }
 494  
     /**
 495  
      * @return Returns the actionObjectFlowState.
 496  
      */
 497  
     protected Action getActionObjectFlowState() {
 498  19
         if (actionObjectFlowState == null) {
 499  19
             actionObjectFlowState =
 500  
                 new RadioAction(
 501  
                         new CmdCreateNode(
 502  
                                 Model.getMetaTypes().getObjectFlowState(),
 503  
                                 "button.new-objectflowstate"));
 504  
         }
 505  19
         return actionObjectFlowState;
 506  
     }
 507  
     /**
 508  
      * @return Returns the actionStartPseudoState.
 509  
      */
 510  
     protected Action getActionStartPseudoState() {
 511  19
         if (actionStartPseudoState == null) {
 512  19
             actionStartPseudoState =
 513  
                 new RadioAction(
 514  
                         new ActionCreatePseudostate(
 515  
                                 Model.getPseudostateKind().getInitial(),
 516  
                                 "button.new-initial"));
 517  
         }
 518  19
         return actionStartPseudoState;
 519  
     }
 520  
     /**
 521  
      * @return Returns the actionState.
 522  
      */
 523  
     protected Action getActionState() {
 524  19
         if (actionState == null) {
 525  19
             actionState =
 526  
                 new RadioAction(
 527  
                         new CmdCreateNode(
 528  
                                 Model.getMetaTypes().getActionState(),
 529  
                                 "button.new-actionstate"));
 530  
         }
 531  19
         return actionState;
 532  
     }
 533  
     /**
 534  
      * @return Returns the actionSubactivityState.
 535  
      */
 536  
     protected Action getActionSubactivityState() {
 537  0
         if (actionSubactivityState == null) {
 538  0
             actionSubactivityState =
 539  
                 new RadioAction(
 540  
                         new CmdCreateNode(
 541  
                                 Model.getMetaTypes().getSubactivityState(),
 542  
                         "button.new-subactivitystate"));
 543  
         }
 544  0
         return actionSubactivityState;
 545  
     }
 546  
     /**
 547  
      * @return Returns the actionTransition.
 548  
      */
 549  
     protected Action getActionTransition() {
 550  19
         if (actionTransition == null) {
 551  19
             actionTransition =
 552  
                 new RadioAction(
 553  
                         new ActionSetMode(
 554  
                                 ModeCreatePolyEdge.class,
 555  
                                 "edgeClass",
 556  
                                 Model.getMetaTypes().getTransition(),
 557  
                         "button.new-transition"));
 558  
         }
 559  19
         return actionTransition;
 560  
     }
 561  
 
 562  
     /**
 563  
      * @return Returns the actionCallEvent.
 564  
      */
 565  
     protected Action getActionCallEvent() {
 566  19
         if (actionCallEvent == null) {
 567  19
             actionCallEvent = new ButtonActionNewCallEvent();
 568  
         }
 569  19
         return actionCallEvent;
 570  
     }
 571  
 
 572  
     /**
 573  
      * @return Returns the actionCallEvent.
 574  
      */
 575  
     protected Action getActionChangeEvent() {
 576  19
         if (actionChangeEvent == null) {
 577  19
             actionChangeEvent = new ButtonActionNewChangeEvent();
 578  
         }
 579  19
         return actionChangeEvent;
 580  
     }
 581  
 
 582  
     /**
 583  
      * @return Returns the actionCallEvent.
 584  
      */
 585  
     protected Action getActionSignalEvent() {
 586  19
         if (actionSignalEvent == null) {
 587  19
             actionSignalEvent = new ButtonActionNewSignalEvent();
 588  
         }
 589  19
         return actionSignalEvent;
 590  
     }
 591  
 
 592  
     /**
 593  
      * @return Returns the actionCallEvent.
 594  
      */
 595  
     protected Action getActionTimeEvent() {
 596  19
         if (actionTimeEvent == null) {
 597  19
             actionTimeEvent = new ButtonActionNewTimeEvent();
 598  
         }
 599  19
         return actionTimeEvent;
 600  
     }
 601  
 
 602  
     protected Action getActionGuard() {
 603  19
         if (actionGuard == null) {
 604  19
             actionGuard = new ButtonActionNewGuard();
 605  
         }
 606  19
         return actionGuard;
 607  
     }
 608  
     
 609  
     protected Action getActionCallAction() {
 610  19
         if (actionCallAction == null) {
 611  19
             actionCallAction = ActionNewCallAction.getButtonInstance();
 612  
         }
 613  19
         return actionCallAction;
 614  
     }
 615  
     
 616  
     protected Action getActionCreateAction() {
 617  19
         if (actionCreateAction == null) {
 618  19
             actionCreateAction = ActionNewCreateAction.getButtonInstance();
 619  
         }
 620  19
         return actionCreateAction;
 621  
     }
 622  
 
 623  
     protected Action getActionDestroyAction() {
 624  19
         if (actionDestroyAction == null) {
 625  19
             actionDestroyAction = ActionNewDestroyAction.getButtonInstance();
 626  
         }
 627  19
         return actionDestroyAction;
 628  
     }
 629  
 
 630  
     protected Action getActionReturnAction() {
 631  19
         if (actionReturnAction == null) {
 632  19
             actionReturnAction = ActionNewReturnAction.getButtonInstance();
 633  
         }
 634  19
         return actionReturnAction;
 635  
     }
 636  
     
 637  
     protected Action getActionSendAction() {
 638  19
         if (actionSendAction == null) {
 639  19
             actionSendAction = ActionNewSendAction.getButtonInstance();
 640  
         }
 641  19
         return actionSendAction;
 642  
     }
 643  
     
 644  
     protected Action getActionTerminateAction() {
 645  19
         if (actionTerminateAction == null) {
 646  19
             actionTerminateAction = 
 647  
                 ActionNewTerminateAction.getButtonInstance();
 648  
         }
 649  19
         return actionTerminateAction;
 650  
     }
 651  
 
 652  
     protected Action getActionUninterpretedAction() {
 653  19
         if (actionUninterpretedAction == null) {
 654  19
             actionUninterpretedAction = 
 655  
                 ActionNewUninterpretedAction.getButtonInstance();
 656  
         }
 657  19
         return actionUninterpretedAction;
 658  
     }
 659  
 
 660  
     protected Action getActionActionSequence() {
 661  19
         if (actionActionSequence == null) {
 662  19
             actionActionSequence = 
 663  
                 ActionNewActionSequence.getButtonInstance();
 664  
         }
 665  19
         return actionActionSequence;
 666  
     }
 667  
 
 668  
     /*
 669  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getDependentElement()
 670  
      */
 671  
     public Object getDependentElement() {
 672  0
         return getStateMachine(); /* The ActivityGraph. */
 673  
     }
 674  
 
 675  
     /*
 676  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#isRelocationAllowed(java.lang.Object)
 677  
      */
 678  
     public boolean isRelocationAllowed(Object base) {
 679  0
         return false;
 680  
         /* TODO: We may return the following when the
 681  
          * relocate() has been implemented.
 682  
          */
 683  
 //      Model.getActivityGraphsHelper()
 684  
 //      .isAddingActivityGraphAllowed(base);
 685  
     }
 686  
 
 687  
     @SuppressWarnings("unchecked")
 688  
     public Collection getRelocationCandidates(Object root) {
 689  
         /* TODO: We may return something useful when the
 690  
          * relocate() has been implemented. */
 691  0
         Collection c =  new HashSet();
 692  0
         c.add(getOwner());
 693  0
         return c;
 694  
     }
 695  
 
 696  
     /*
 697  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#relocate(java.lang.Object)
 698  
      */
 699  
     public boolean relocate(Object base) {
 700  0
         return false;
 701  
     }
 702  
     
 703  
     /**
 704  
      * Once the diagram has loaded we build the previous/next links between
 705  
      * any swimlanes.
 706  
      */
 707  
     @Override
 708  
     public void postLoad() {
 709  0
         FigPartition previous = null;
 710  
 
 711  
         // Create a map of partitions keyed by x coordinate
 712  0
         HashMap map = new HashMap();
 713  
         
 714  0
         Iterator it = new ArrayList(getLayer().getContents()).iterator();
 715  0
         while (it.hasNext()) {
 716  0
             Fig f = (Fig) it.next();
 717  0
             if (f instanceof FigPartition) {
 718  0
                 map.put(Integer.valueOf(f.getX()), f);
 719  
             }
 720  0
         }
 721  
         
 722  
         // Sort the x coordinates into order
 723  0
         List xList = new ArrayList(map.keySet());
 724  0
         Collections.sort(xList);
 725  
         
 726  
         // Link the previous/next reference of the swimlanes
 727  
         // according to the x order.
 728  0
         it = xList.iterator();
 729  0
         while (it.hasNext()) {
 730  0
             Fig f = (Fig) map.get(it.next());
 731  0
             if (f instanceof FigPartition) {
 732  0
                 FigPartition fp = (FigPartition) f;
 733  0
                 if (previous != null) {
 734  0
                     previous.setNextPartition(fp);
 735  
                 }
 736  0
                 fp.setPreviousPartition(previous);
 737  0
                 fp.setNextPartition(null);
 738  0
                 previous = fp; 
 739  
             }
 740  0
         }
 741  0
     }
 742  
 
 743  
     /**
 744  
      * Extends basic functionality to handle logic for enclosement of states
 745  
      * within a swimlane.
 746  
      * @param enclosed The FigNode enclosed.
 747  
      * @param oldEncloser The previous encloser (null if none)
 748  
      * @param newEncloser The encloser (null if none)
 749  
      */
 750  
     public void encloserChanged(
 751  
             FigNode enclosed, FigNode oldEncloser, FigNode newEncloser) {
 752  
         
 753  0
         if (oldEncloser == null && newEncloser == null) {
 754  0
             return;
 755  
         }
 756  
         
 757  0
         if (enclosed instanceof FigStateVertex
 758  
                 || enclosed instanceof FigObjectFlowState) {
 759  0
             changePartition(enclosed);
 760  
         }
 761  0
     }
 762  
     
 763  
     /**
 764  
      * Extends basic functionality to handle logic for enclosement of states
 765  
      * within a swimlane.
 766  
      * @param enclosed The FigNode enclosed.
 767  
      */
 768  
     private void changePartition(FigNode enclosed) {
 769  
         
 770  0
         assert enclosed != null;
 771  
         
 772  0
         Object state = enclosed.getOwner();
 773  0
         ActivityGraphsHelper activityGraph = Model.getActivityGraphsHelper();
 774  
         
 775  0
         for (Object f : getLayer().getContentsNoEdges()) {
 776  0
             if (f instanceof FigPartition) {
 777  0
                 FigPartition fig = (FigPartition) f;
 778  0
                 Object partition = fig.getOwner();
 779  0
                 if (fig.getBounds().intersects(enclosed.getBounds())) {
 780  0
                     activityGraph.addContent(partition, state);
 781  0
                 } else if (isStateInPartition(state, partition)) {
 782  0
                     activityGraph.removeContent(partition, state);
 783  
                 }
 784  0
             }
 785  
         }
 786  0
     }
 787  
 
 788  
     private boolean isStateInPartition(Object state, Object partition) {
 789  0
         return Model.getFacade().getContents(partition).contains(state);
 790  
     }
 791  
     
 792  
     @Override
 793  
     public boolean doesAccept(Object objectToAccept) {
 794  0
         if (Model.getFacade().isAPartition(objectToAccept)) {
 795  0
             return true;
 796  0
         } else if (Model.getFacade().isAState(objectToAccept)) {
 797  0
             return true;
 798  0
         } else if (Model.getFacade().isAPseudostate(objectToAccept)) {
 799  0
             Object kind = Model.getFacade().getKind(objectToAccept);
 800  0
             if (kind == null) {
 801  0
                 LOG.warn("found a null type pseudostate");
 802  0
                 return false;
 803  
             }
 804  0
             if (kind.equals(
 805  
                     Model.getPseudostateKind().getShallowHistory())) {
 806  0
                 return false;
 807  0
             } else if (kind.equals(
 808  
                     Model.getPseudostateKind().getDeepHistory())) {
 809  0
                 return false;
 810  
             }
 811  0
             return true;
 812  0
         } else if (Model.getFacade().isAComment(objectToAccept)) {
 813  0
             return true;
 814  
         }
 815  0
         return false;
 816  
     }
 817  
     
 818  
     public DiagramElement createDiagramElement(
 819  
             final Object modelElement,
 820  
             final Rectangle bounds) {
 821  
         
 822  0
         FigNodeModelElement figNode = null;
 823  
         
 824  0
         DiagramSettings settings = getDiagramSettings();
 825  
         
 826  0
         if (Model.getFacade().isAPartition(modelElement)) {
 827  0
             figNode = new FigPartition(modelElement, bounds, settings);
 828  0
         } else if (Model.getFacade().isAActionState(modelElement)) {
 829  0
             figNode = new FigActionState(modelElement, bounds, settings);
 830  0
         } else if (Model.getFacade().isACallState(modelElement)) {
 831  0
             figNode = new FigCallState(modelElement, bounds, settings);
 832  0
         } else if (Model.getFacade().isAObjectFlowState(modelElement)) {
 833  0
             figNode = new FigObjectFlowState(modelElement, bounds, settings);
 834  0
         } else if (Model.getFacade().isASubactivityState(modelElement)) {
 835  0
             figNode = new FigSubactivityState(modelElement, bounds, settings);
 836  0
         } else if (Model.getFacade().isAFinalState(modelElement)) {
 837  0
             figNode = new FigFinalState(modelElement, bounds, settings);
 838  0
         } else if (Model.getFacade().isAPseudostate(modelElement)) {
 839  0
             Object kind = Model.getFacade().getKind(modelElement);
 840  0
             if (kind == null) {
 841  0
                 LOG.warn("found a null type pseudostate");
 842  0
                 return null;
 843  
             }
 844  0
             if (kind.equals(Model.getPseudostateKind().getInitial())) {
 845  0
                 figNode = new FigInitialState(modelElement, bounds, settings);
 846  0
             } else if (kind.equals(
 847  
                     Model.getPseudostateKind().getChoice())) {
 848  0
                 figNode = new FigBranchState(modelElement, bounds, settings);
 849  0
             } else if (kind.equals(
 850  
                     Model.getPseudostateKind().getJunction())) {
 851  0
                 figNode = new FigJunctionState(modelElement, bounds, settings);
 852  0
             } else if (kind.equals(
 853  
                     Model.getPseudostateKind().getFork())) {
 854  0
                 figNode = new FigForkState(modelElement, bounds, settings);
 855  0
             } else if (kind.equals(
 856  
                     Model.getPseudostateKind().getJoin())) {
 857  0
                 figNode = new FigJoinState(modelElement, bounds, settings);
 858  
             } else {
 859  0
                 LOG.warn("found a type not known");
 860  
             }
 861  0
         } else if (Model.getFacade().isAComment(modelElement)) {
 862  0
             figNode = new FigComment(modelElement, bounds, settings);
 863  
         }
 864  
         
 865  0
         if (figNode != null) {
 866  0
             LOG.debug("Model element " + modelElement + " converted to " 
 867  
                     + figNode);
 868  
         } else {
 869  0
             LOG.debug("Dropped object NOT added " + figNode);
 870  
         }
 871  0
         return figNode;
 872  
     }
 873  
     
 874  
 
 875  
 }