Coverage Report - org.argouml.uml.diagram.state.ui.UMLStateDiagram
 
Classes in this File Line Coverage Branch Coverage Complexity
UMLStateDiagram
48%
143/294
23%
46/200
3.373
 
 1  
 /* $Id: UMLStateDiagram.java 18729 2010-09-10 16:10:34Z bobtarling $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009-2010 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  
  *    Bob Tarling
 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.state.ui;
 40  
 
 41  
 import java.awt.Point;
 42  
 import java.awt.Rectangle;
 43  
 import java.beans.PropertyChangeEvent;
 44  
 import java.beans.PropertyVetoException;
 45  
 import java.util.Collection;
 46  
 import java.util.HashSet;
 47  
 
 48  
 import javax.swing.Action;
 49  
 
 50  
 import org.apache.log4j.Logger;
 51  
 import org.argouml.i18n.Translator;
 52  
 import org.argouml.model.DeleteInstanceEvent;
 53  
 import org.argouml.model.Model;
 54  
 import org.argouml.ui.CmdCreateNode;
 55  
 import org.argouml.uml.diagram.DiagramElement;
 56  
 import org.argouml.uml.diagram.DiagramFactory;
 57  
 import org.argouml.uml.diagram.DiagramSettings;
 58  
 import org.argouml.uml.diagram.UMLMutableGraphSupport;
 59  
 import org.argouml.uml.diagram.activity.ui.FigActionState;
 60  
 import org.argouml.uml.diagram.state.StateDiagramGraphModel;
 61  
 import org.argouml.uml.diagram.static_structure.ui.FigComment;
 62  
 import org.argouml.uml.diagram.ui.ActionSetMode;
 63  
 import org.argouml.uml.diagram.ui.FigNodeModelElement;
 64  
 import org.argouml.uml.diagram.ui.RadioAction;
 65  
 import org.argouml.uml.diagram.ui.UMLDiagram;
 66  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewActionSequence;
 67  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewCallAction;
 68  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewCreateAction;
 69  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewDestroyAction;
 70  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewReturnAction;
 71  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewSendAction;
 72  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewTerminateAction;
 73  
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewUninterpretedAction;
 74  
 import org.argouml.uml.ui.behavior.state_machines.ButtonActionNewGuard;
 75  
 import org.argouml.util.ToolBarUtility;
 76  
 import org.tigris.gef.base.LayerPerspective;
 77  
 import org.tigris.gef.base.LayerPerspectiveMutable;
 78  
 import org.tigris.gef.base.ModeCreatePolyEdge;
 79  
 import org.tigris.gef.presentation.FigNode;
 80  
 
 81  
 
 82  
 /**
 83  
  * The UML Statechart diagram. <p>
 84  
  * 
 85  
  * The correct name for this class would be 
 86  
  * "UMLStatechartDiagram". See issue 2306.
 87  
  */
 88  
 public class UMLStateDiagram extends UMLDiagram {
 89  
 
 90  
     private static final long serialVersionUID = -1541136327444703151L;
 91  
 
 92  38
     private static final Logger LOG = Logger.getLogger(UMLStateDiagram.class);
 93  
 
 94  
     /**
 95  
      * this diagram needs to be deleted when its statemachine is deleted.
 96  
      */
 97  
     private Object theStateMachine;
 98  
 
 99  
     ////////////////
 100  
     // actions for toolbar
 101  
 
 102  
     private Action actionStubState;
 103  
     private Action actionState;
 104  
     private Action actionSynchState;
 105  
     private Action actionSubmachineState;
 106  
     private Action actionCompositeState;
 107  
     private Action actionStartPseudoState;
 108  
     private Action actionFinalPseudoState;
 109  
     private Action actionBranchPseudoState;
 110  
     private Action actionForkPseudoState;
 111  
     private Action actionJoinPseudoState;
 112  
     private Action actionShallowHistoryPseudoState;
 113  
     private Action actionDeepHistoryPseudoState;
 114  
     private Action actionCallEvent;
 115  
     private Action actionChangeEvent;
 116  
     private Action actionSignalEvent;
 117  
     private Action actionTimeEvent;
 118  
     private Action actionGuard;
 119  
     private Action actionCallAction;
 120  
     private Action actionCreateAction;
 121  
     private Action actionDestroyAction;
 122  
     private Action actionReturnAction;
 123  
     private Action actionSendAction;
 124  
     private Action actionTerminateAction;
 125  
     private Action actionUninterpretedAction;
 126  
     private Action actionActionSequence;
 127  
     private Action actionTransition;
 128  
     private Action actionJunctionPseudoState;
 129  
 
 130  
     /**
 131  
      * Constructor used by PGML parser to create a new diagram.  Use of
 132  
      * this constructor by other callers is deprecated.
 133  
      * 
 134  
      * @deprecated for 0.27.3 by tfmorris.  Use 
 135  
      * {@link #UMLStateDiagram(String, Object)}
 136  
      */
 137  
     @Deprecated
 138  
     public UMLStateDiagram() {
 139  39
         super(new StateDiagramGraphModel());
 140  
         try {
 141  39
             setName(getNewDiagramName());
 142  0
         } catch (PropertyVetoException pve) {
 143  
             // nothing we can do about veto, so just ignore it
 144  39
         }
 145  39
     }
 146  
 
 147  
     /**
 148  
      * Constructor.
 149  
      * 
 150  
      * @param name the name of the diagram
 151  
      * @param machine the StateMachine for the new diagram
 152  
      */
 153  
     public UMLStateDiagram(String name, Object machine) {
 154  0
         super(name, machine, new StateDiagramGraphModel());
 155  
 
 156  0
         if (!Model.getFacade().isAStateMachine(machine)) {
 157  0
             throw new IllegalStateException(
 158  
                 "No StateMachine given to create a Statechart diagram");
 159  
         }
 160  0
         namespace = getNamespaceFromMachine(machine);
 161  0
         if (!Model.getFacade().isANamespace(namespace)) {
 162  0
             throw new IllegalArgumentException();
 163  
         }
 164  
 
 165  0
         nameDiagram(namespace);
 166  0
         setup(namespace, machine);
 167  0
     }
 168  
 
 169  
    
 170  
     /**
 171  
      * Constructor.
 172  
      * 
 173  
      * @param ns the NameSpace for the new diagram
 174  
      * @param machine the StateMachine for the new diagram
 175  
      * @deprecated for 0.27.3 by tfmorris. Use
 176  
      *             {@link #UMLStateDiagram(String, Object)}/
 177  
      */
 178  
     @Deprecated
 179  
     public UMLStateDiagram(Object ns, Object machine) {
 180  39
         this();
 181  
 
 182  39
         if (!Model.getFacade().isAStateMachine(machine)) {
 183  0
             throw new IllegalStateException(
 184  
                 "No StateMachine given to create a Statechart diagram");
 185  
         }
 186  39
         if (ns == null) {
 187  39
             ns = getNamespaceFromMachine(machine);
 188  
         }
 189  39
         if (!Model.getFacade().isANamespace(ns)) {
 190  0
             throw new IllegalArgumentException();
 191  
         }
 192  
 
 193  39
         nameDiagram(ns);
 194  39
         setup(ns, machine);
 195  39
     }
 196  
 
 197  
     /**
 198  
      * Name the diagram based on the name of its namespace and the number of
 199  
      * behaviors that it contains.
 200  
      * @param ns containing namespace
 201  
      */
 202  
     private void nameDiagram(Object ns) {
 203  39
         String nname = Model.getFacade().getName(ns);
 204  39
         if (nname != null && nname.trim().length() != 0) {
 205  39
             int number = (Model.getFacade().getBehaviors(ns)) == null ? 0
 206  
                     : Model.getFacade().getBehaviors(ns).size();
 207  39
             String name = nname + " " + (number++);
 208  39
             LOG.info("UMLStateDiagram constructor: String name = " + name);
 209  
             try {
 210  39
                 setName(name);
 211  0
             } catch (PropertyVetoException pve) {
 212  
                 // nothing we can do about veto, so just ignore it
 213  39
             }
 214  
         }
 215  
 
 216  39
     }
 217  
 
 218  
     /**
 219  
      * From a given StateMachine, find the Namespace. 
 220  
      * Guaranteed to give a non-null result.
 221  
      * 
 222  
      * @param machine the given StateMachine. 
 223  
      *          If not a StateMachine: throws exception
 224  
      * @return the best possible namespace to be deducted
 225  
      */
 226  
     private Object getNamespaceFromMachine(Object machine) {
 227  39
         if (!Model.getFacade().isAStateMachine(machine)) {
 228  0
             throw new IllegalStateException(
 229  
                 "No StateMachine given to create a Statechart diagram");
 230  
         }
 231  
         
 232  39
         Object ns = Model.getFacade().getNamespace(machine);
 233  39
         if (ns != null) {
 234  39
             return ns;
 235  
         }
 236  
         
 237  0
         Object context = Model.getFacade().getContext(machine);
 238  0
         if (Model.getFacade().isAClassifier(context)) {
 239  0
             ns = context;
 240  0
         } else if (Model.getFacade().isABehavioralFeature(context)) {
 241  0
             ns = Model.getFacade().getNamespace( // or just the owner?
 242  
                     Model.getFacade().getOwner(context));
 243  
         }
 244  0
         if (ns == null) {
 245  0
             ns = getProject().getRoots().iterator().next();
 246  
         }
 247  0
         if (ns == null || !Model.getFacade().isANamespace(ns)) {
 248  0
             throw new IllegalStateException(
 249  
                     "Can not deduce a Namespace from a StateMachine");
 250  
         }
 251  0
         return ns;
 252  
     }
 253  
 
 254  
     /**
 255  
      * Get the owner of a statechart diagram.
 256  
      * @return the statemachine which owns the diagram
 257  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getOwner()
 258  
      */
 259  
     @Override
 260  
     public Object getOwner() {
 261  324
         if (!(getGraphModel() instanceof StateDiagramGraphModel)) {
 262  0
             throw new IllegalStateException(
 263  
                     "Incorrect graph model of "
 264  
                     + getGraphModel().getClass().getName());
 265  
         }
 266  324
         StateDiagramGraphModel gm = (StateDiagramGraphModel) getGraphModel();
 267  324
         return gm.getMachine();
 268  
     }
 269  
 
 270  
     /**
 271  
      * Called by the PGML parser to initialize the statechart
 272  
      * diagram. First the parser creates a statechart diagram via the
 273  
      * default constructor. Then this method is called.
 274  
      *
 275  
      * @param o the statemachine
 276  
      * @see org.tigris.gef.base.Diagram#initialize(Object)
 277  
      */
 278  
     @Override
 279  
     public void initialize(Object o) {
 280  0
         if (Model.getFacade().isAStateMachine(o)) {
 281  0
             Object machine = o;
 282  0
             Object contextNamespace = getNamespaceFromMachine(machine);
 283  
 
 284  0
             setup(contextNamespace, machine);
 285  0
         } else {
 286  0
             throw new IllegalStateException(
 287  
                 "Cannot find namespace "
 288  
                     + "while initializing "
 289  
                     + "statechart diagram");
 290  
         }
 291  0
     }
 292  
 
 293  
     /**
 294  
      * Method to perform a number of important initializations of a
 295  
      * StateDiagram.<p>
 296  
      *
 297  
      * Each diagram type has a similar <I>UMLxxxDiagram</I> class.<p>
 298  
      *
 299  
      * Changed <I>lay</I> from <I>LayerPerspective</I> to
 300  
      * <I>LayerPerspectiveMutable</I>.  This class is a child of
 301  
      * <I>LayerPerspective</I> and was implemented to correct some
 302  
      * difficulties in changing the model. <I>lay</I> is used mainly
 303  
      * in <I>LayerManager</I>(GEF) to control the adding, changing and
 304  
      * deleting layers on the diagram...
 305  
      *
 306  
      * @param namespace Class from the UML model...connects the class to
 307  
      * the Statechart diagram.
 308  
      * @param machine StateMachine from the UML model
 309  
      * @author psager@tigris.org Jan. 24, 2oo2
 310  
      */
 311  
     public void setup(Object namespace, Object machine) {
 312  39
         setNamespace(namespace);
 313  
 
 314  39
         theStateMachine = machine;
 315  
 
 316  39
         StateDiagramGraphModel gm = createGraphModel();
 317  39
         gm.setHomeModel(namespace);
 318  39
         if (theStateMachine != null) {
 319  39
             gm.setMachine(theStateMachine);
 320  
         }
 321  39
         StateDiagramRenderer rend = new StateDiagramRenderer(); // singleton
 322  
 
 323  39
         LayerPerspective lay = new LayerPerspectiveMutable(
 324  
                 Model.getFacade().getName(namespace), gm);
 325  39
         lay.setGraphNodeRenderer(rend);
 326  39
         lay.setGraphEdgeRenderer(rend);
 327  39
         setLayer(lay);
 328  
 
 329  
         /* Listen to machine deletion, 
 330  
          * to delete the diagram. */
 331  39
         Model.getPump().addModelEventListener(this, theStateMachine, 
 332  
                 new String[] {"remove", "namespace"});
 333  39
     }
 334  
     
 335  
     
 336  
     // TODO: Needs to be tidied up after stable release. Graph model
 337  
     // should be created in constructor
 338  
     private StateDiagramGraphModel createGraphModel() {
 339  39
         if ((getGraphModel() instanceof StateDiagramGraphModel)) {
 340  39
             return (StateDiagramGraphModel) getGraphModel();
 341  
         } else {
 342  0
             return new StateDiagramGraphModel();
 343  
         }
 344  
     }
 345  
 
 346  
     /*
 347  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#propertyChange(java.beans.PropertyChangeEvent)
 348  
      */
 349  
     @Override
 350  
     public void propertyChange(PropertyChangeEvent evt) {
 351  1
         if ((evt.getSource() == theStateMachine)
 352  
                 && (evt instanceof DeleteInstanceEvent)
 353  
                 && "remove".equals(evt.getPropertyName())) {
 354  1
             Model.getPump().removeModelEventListener(this, 
 355  
                     theStateMachine, new String[] {"remove", "namespace"});
 356  1
             if (getProject() != null) {
 357  1
                 getProject().moveToTrash(this);
 358  
             } else {
 359  0
                 DiagramFactory.getInstance().removeDiagram(this);
 360  
             }
 361  
         }
 362  1
         if (evt.getSource() == theStateMachine 
 363  
                 && "namespace".equals(evt.getPropertyName())) {
 364  0
             Object newNamespace = evt.getNewValue();
 365  0
             if (newNamespace != null // this in case we are being deleted 
 366  
                     && getNamespace() != newNamespace) {
 367  
                 /* The namespace of the statemachine is changed! */
 368  0
                 setNamespace(newNamespace);
 369  0
                 ((UMLMutableGraphSupport) getGraphModel())
 370  
                                 .setHomeModel(newNamespace);
 371  
             }
 372  
         }
 373  1
     }
 374  
 
 375  
     /**
 376  
      * @return the StateMachine belonging to this diagram
 377  
      */
 378  
     public Object getStateMachine() {
 379  1
         return ((StateDiagramGraphModel) getGraphModel()).getMachine();
 380  
     }
 381  
 
 382  
     /**
 383  
      * @param sm Set the StateMachine for this diagram.
 384  
      */
 385  
     public void setStateMachine(Object sm) {
 386  
 
 387  0
         if (!Model.getFacade().isAStateMachine(sm)) {
 388  0
             throw new IllegalArgumentException("This is not a StateMachine");
 389  
         }
 390  
 
 391  0
         ((StateDiagramGraphModel) getGraphModel()).setMachine(sm);
 392  0
     }
 393  
 
 394  
     /**
 395  
      * Get the actions from which to create a toolbar or equivalent
 396  
      * graphic triggers.
 397  
      * @return the array of actions
 398  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getUmlActions()
 399  
      */
 400  
     protected Object[] getUmlActions() {
 401  39
         if (Model.getFacade().getUmlVersion().charAt(0) == '1') {
 402  39
             Object[] actions =
 403  
             {
 404  
                 getActionState(),
 405  
                 getActionCompositeState(),
 406  
                 getActionTransition(),
 407  
                 getActionSynchState(),
 408  
                 getActionSubmachineState(),
 409  
                 getActionStubState(),
 410  
                 null,
 411  
                 getActionStartPseudoState(),
 412  
                 getActionFinalPseudoState(),
 413  
                 getActionJunctionPseudoState(),
 414  
                 getActionChoicePseudoState(),
 415  
                 getActionForkPseudoState(),
 416  
                 getActionJoinPseudoState(),
 417  
                 getActionShallowHistoryPseudoState(),
 418  
                 getActionDeepHistoryPseudoState(),
 419  
                 null,
 420  
                 getTriggerActions(),
 421  
                 getActionGuard(),
 422  
                 getEffectActions(),
 423  
             };
 424  39
             return actions;
 425  
         } else {
 426  0
             Object[] actions =
 427  
             {
 428  
                 getActionState(),
 429  
                 getActionTransition(),
 430  
                 null,
 431  
                 getActionStartPseudoState(),
 432  
                 getActionFinalPseudoState(),
 433  
                 getActionJunctionPseudoState(),
 434  
                 getActionChoicePseudoState(),
 435  
                 getActionForkPseudoState(),
 436  
                 getActionJoinPseudoState(),
 437  
                 getActionShallowHistoryPseudoState(),
 438  
                 getActionDeepHistoryPseudoState(),
 439  
                 null,
 440  
                 getTriggerActions(),
 441  
                 getActionGuard(),
 442  
                 getEffectActions(),
 443  
             };
 444  0
             return actions;
 445  
         }
 446  
     }
 447  
 
 448  
     protected Object[] getTriggerActions() {
 449  39
         Object[] actions = {
 450  
             getActionCallEvent(),
 451  
             getActionChangeEvent(),
 452  
             getActionSignalEvent(),
 453  
             getActionTimeEvent(),
 454  
         };
 455  39
         ToolBarUtility.manageDefault(actions, "diagram.state.trigger");
 456  39
         return actions;
 457  
     }
 458  
 
 459  
     protected Object[] getEffectActions() {
 460  39
         Object[] actions = {
 461  
             getActionCallAction(),
 462  
             getActionCreateAction(),
 463  
             getActionDestroyAction(),
 464  
             getActionReturnAction(),
 465  
             getActionSendAction(),
 466  
             getActionTerminateAction(),
 467  
             getActionUninterpretedAction(),
 468  
             getActionActionSequence(),
 469  
         };
 470  39
         ToolBarUtility.manageDefault(actions, "diagram.state.effect");
 471  39
         return actions;
 472  
     }
 473  
 
 474  
     /*
 475  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getLabelName()
 476  
      */
 477  
     public String getLabelName() {
 478  39
         return Translator.localize("label.state-chart-diagram");
 479  
     }
 480  
 
 481  
     /**
 482  
      * @return Returns the actionChoicePseudoState.
 483  
      */
 484  
     protected Action getActionChoicePseudoState() {
 485  39
         if (actionBranchPseudoState == null) {
 486  39
             actionBranchPseudoState = new RadioAction(
 487  
                     new ActionCreatePseudostate(Model.getPseudostateKind()
 488  
                             .getChoice(), "button.new-choice"));
 489  
         }
 490  39
         return actionBranchPseudoState;
 491  
     }
 492  
 
 493  
     /**
 494  
      * @return Returns the actionCompositeState.
 495  
      */
 496  
     protected Action getActionCompositeState() {
 497  39
         if (actionCompositeState == null) {
 498  39
             actionCompositeState =
 499  
                 new RadioAction(new CmdCreateNode(
 500  
                         Model.getMetaTypes().getCompositeState(),
 501  
                         "button.new-compositestate"));
 502  
         }
 503  39
         return actionCompositeState;
 504  
     }
 505  
     /**
 506  
      * @return Returns the actionDeepHistoryPseudoState.
 507  
      */
 508  
     protected Action getActionDeepHistoryPseudoState() {
 509  39
         if (actionDeepHistoryPseudoState == null) {
 510  39
             actionDeepHistoryPseudoState = new RadioAction(
 511  
                     new ActionCreatePseudostate(
 512  
                         Model.getPseudostateKind().getDeepHistory(),
 513  
                         "button.new-deephistory"));
 514  
         }
 515  39
         return actionDeepHistoryPseudoState;
 516  
     }
 517  
     /**
 518  
      * @return Returns the actionFinalPseudoState.
 519  
      */
 520  
     protected Action getActionFinalPseudoState() {
 521  39
         if (actionFinalPseudoState == null) {
 522  39
             actionFinalPseudoState =
 523  
                 new RadioAction(
 524  
                         new CmdCreateNode(
 525  
                                 Model.getMetaTypes().getFinalState(),
 526  
                                 "button.new-finalstate"));
 527  
         }
 528  39
         return actionFinalPseudoState;
 529  
     }
 530  
     /**
 531  
      * @return Returns the actionForkPseudoState.
 532  
      */
 533  
     protected Action getActionForkPseudoState() {
 534  39
         if (actionForkPseudoState == null) {
 535  39
             actionForkPseudoState = new RadioAction(
 536  
                     new ActionCreatePseudostate(
 537  
                             Model.getPseudostateKind()
 538  
                             .getFork(), "button.new-fork"));
 539  
         }
 540  39
         return actionForkPseudoState;
 541  
     }
 542  
     /**
 543  
      * @return Returns the actionJoinPseudoState.
 544  
      */
 545  
     protected Action getActionJoinPseudoState() {
 546  39
         if (actionJoinPseudoState == null) {
 547  39
             actionJoinPseudoState = new RadioAction(new ActionCreatePseudostate(
 548  
                     Model.getPseudostateKind().getJoin(), "button.new-join"));
 549  
         }
 550  39
         return actionJoinPseudoState;
 551  
     }
 552  
     /**
 553  
      * @return Returns the actionJunctionPseudoState.
 554  
      */
 555  
     protected Action getActionJunctionPseudoState() {
 556  39
         if (actionJunctionPseudoState == null) {
 557  39
             actionJunctionPseudoState = new RadioAction(
 558  
                     new ActionCreatePseudostate(
 559  
                         Model.getPseudostateKind().getJunction(),
 560  
                         "button.new-junction"));
 561  
         }
 562  39
         return actionJunctionPseudoState;
 563  
     }
 564  
     /**
 565  
      * @return Returns the actionShallowHistoryPseudoState.
 566  
      */
 567  
     protected Action getActionShallowHistoryPseudoState() {
 568  39
         if (actionShallowHistoryPseudoState == null) {
 569  39
             actionShallowHistoryPseudoState = new RadioAction(
 570  
                     new ActionCreatePseudostate(
 571  
                         Model.getPseudostateKind().getShallowHistory(),
 572  
                         "button.new-shallowhistory"));
 573  
         }
 574  39
         return actionShallowHistoryPseudoState;
 575  
     }
 576  
     /**
 577  
      * @return Returns the actionStartPseudoState.
 578  
      */
 579  
     protected Action getActionStartPseudoState() {
 580  39
         if (actionStartPseudoState == null) {
 581  39
             actionStartPseudoState = new RadioAction(
 582  
                     new ActionCreatePseudostate(
 583  
                         Model.getPseudostateKind().getInitial(),
 584  
                         "button.new-initial"));
 585  
         }
 586  39
         return actionStartPseudoState;
 587  
     }
 588  
     /**
 589  
      * @return Returns the actionState.
 590  
      */
 591  
     protected Action getActionState() {
 592  39
         if (actionState == null) {
 593  39
             if (Model.getFacade().getUmlVersion().charAt(0) == '1') {
 594  39
                 actionState =
 595  
                     new RadioAction(
 596  
                             new CmdCreateNode(Model.getMetaTypes().getSimpleState(),
 597  
                                               "button.new-simplestate"));
 598  
             } else {
 599  0
                 actionState =
 600  
                     new RadioAction(
 601  
                             new CmdCreateNode(Model.getMetaTypes().getState(),
 602  
                                               "button.new-simplestate"));
 603  
             }
 604  
         }
 605  39
         return actionState;
 606  
     }
 607  
 
 608  
     /**
 609  
      * @return Returns the actionSynchState.
 610  
      */
 611  
     protected Action getActionSynchState() {
 612  39
         if (actionSynchState == null) {
 613  39
             actionSynchState =
 614  
                 new RadioAction(
 615  
                         new CmdCreateNode(
 616  
                                 Model.getMetaTypes().getSynchState(),
 617  
                                 "button.new-synchstate"));
 618  
         }
 619  39
         return actionSynchState;
 620  
     }
 621  
 
 622  
     /**
 623  
      * @return Returns the actionSubmachineState.
 624  
      */
 625  
     protected Action getActionSubmachineState() {
 626  39
         if (actionSubmachineState == null) {
 627  39
             actionSubmachineState =
 628  
                     new RadioAction(
 629  
                             new CmdCreateNode(
 630  
                                     Model.getMetaTypes().getSubmachineState(),
 631  
                                     "button.new-submachinestate"));
 632  
         }
 633  39
         return actionSubmachineState;
 634  
     }
 635  
 
 636  
     /**
 637  
      * @return Returns the actionSubmachineState.
 638  
      */
 639  
     protected Action getActionStubState() {
 640  39
         if (actionStubState == null) {
 641  39
             actionStubState =
 642  
                     new RadioAction(
 643  
                             new CmdCreateNode(
 644  
                                     Model.getMetaTypes().getStubState(),
 645  
                                     "button.new-stubstate"));
 646  
         }
 647  39
         return actionStubState;
 648  
     }
 649  
 
 650  
     /**
 651  
      * @return Returns the actionTransition.
 652  
      */
 653  
     protected Action getActionTransition() {
 654  39
         if (actionTransition == null) {
 655  39
             actionTransition = new RadioAction(
 656  
                     new ActionSetMode(
 657  
                         ModeCreatePolyEdge.class,
 658  
                         "edgeClass",
 659  
                         Model.getMetaTypes().getTransition(),
 660  
                         "button.new-transition"));
 661  
         }
 662  39
         return actionTransition;
 663  
     }
 664  
 
 665  
     /**
 666  
      * @return Returns the actionCallEvent.
 667  
      */
 668  
     protected Action getActionCallEvent() {
 669  39
         if (actionCallEvent == null) {
 670  39
             actionCallEvent = new ButtonActionNewCallEvent();
 671  
         }
 672  39
         return actionCallEvent;
 673  
     }
 674  
 
 675  
     /**
 676  
      * @return Returns the actionCallEvent.
 677  
      */
 678  
     protected Action getActionChangeEvent() {
 679  39
         if (actionChangeEvent == null) {
 680  39
             actionChangeEvent = new ButtonActionNewChangeEvent();
 681  
         }
 682  39
         return actionChangeEvent;
 683  
     }
 684  
 
 685  
     /**
 686  
      * @return Returns the actionCallEvent.
 687  
      */
 688  
     protected Action getActionSignalEvent() {
 689  39
         if (actionSignalEvent == null) {
 690  39
             actionSignalEvent = new ButtonActionNewSignalEvent();
 691  
         }
 692  39
         return actionSignalEvent;
 693  
     }
 694  
 
 695  
     /**
 696  
      * @return Returns the actionCallEvent.
 697  
      */
 698  
     protected Action getActionTimeEvent() {
 699  39
         if (actionTimeEvent == null) {
 700  39
             actionTimeEvent = new ButtonActionNewTimeEvent();
 701  
         }
 702  39
         return actionTimeEvent;
 703  
     }
 704  
 
 705  
     protected Action getActionGuard() {
 706  39
         if (actionGuard == null) {
 707  39
             actionGuard = new ButtonActionNewGuard();
 708  
         }
 709  39
         return actionGuard;
 710  
     }
 711  
     
 712  
     protected Action getActionCallAction() {
 713  39
         if (actionCallAction == null) {
 714  39
             actionCallAction = ActionNewCallAction.getButtonInstance();
 715  
         }
 716  39
         return actionCallAction;
 717  
     }
 718  
     
 719  
     protected Action getActionCreateAction() {
 720  39
         if (actionCreateAction == null) {
 721  39
             actionCreateAction = ActionNewCreateAction.getButtonInstance();
 722  
         }
 723  39
         return actionCreateAction;
 724  
     }
 725  
 
 726  
     protected Action getActionDestroyAction() {
 727  39
         if (actionDestroyAction == null) {
 728  39
             actionDestroyAction = ActionNewDestroyAction.getButtonInstance();
 729  
         }
 730  39
         return actionDestroyAction;
 731  
     }
 732  
 
 733  
     protected Action getActionReturnAction() {
 734  39
         if (actionReturnAction == null) {
 735  39
             actionReturnAction = ActionNewReturnAction.getButtonInstance();
 736  
         }
 737  39
         return actionReturnAction;
 738  
     }
 739  
     
 740  
     protected Action getActionSendAction() {
 741  39
         if (actionSendAction == null) {
 742  39
             actionSendAction = ActionNewSendAction.getButtonInstance();
 743  
         }
 744  39
         return actionSendAction;
 745  
     }
 746  
     
 747  
     protected Action getActionTerminateAction() {
 748  39
         if (actionTerminateAction == null) {
 749  39
             actionTerminateAction = 
 750  
                 ActionNewTerminateAction.getButtonInstance();
 751  
         }
 752  39
         return actionTerminateAction;
 753  
     }
 754  
 
 755  
     protected Action getActionUninterpretedAction() {
 756  39
         if (actionUninterpretedAction == null) {
 757  39
             actionUninterpretedAction = 
 758  
                 ActionNewUninterpretedAction.getButtonInstance();
 759  
         }
 760  39
         return actionUninterpretedAction;
 761  
     }
 762  
 
 763  
 
 764  
     protected Action getActionActionSequence() {
 765  39
         if (actionActionSequence == null) {
 766  39
             actionActionSequence = 
 767  
                 ActionNewActionSequence.getButtonInstance();
 768  
         }
 769  39
         return actionActionSequence;
 770  
     }
 771  
 
 772  
     /*
 773  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getDependentElement()
 774  
      */
 775  
     @Override
 776  
     public Object getDependentElement() {
 777  1
         return getStateMachine();
 778  
     }
 779  
 
 780  
     /*
 781  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#isRelocationAllowed(java.lang.Object)
 782  
      */
 783  
     public boolean isRelocationAllowed(Object base)  {
 784  0
             return false;
 785  
             /* TODO: We may return the following when the
 786  
              * relocate() has been implemented. */
 787  
 //            Model.getStateMachinesHelper()
 788  
 //                .isAddingStatemachineAllowed(base);
 789  
     }
 790  
 
 791  
     @SuppressWarnings("unchecked")
 792  
     public Collection getRelocationCandidates(Object root) {
 793  
         /* TODO: We may return something useful when the
 794  
          * relocate() has been implemented, like 
 795  
          * all StateMachines that are not ActivityGraphs. */
 796  0
         Collection c =  new HashSet();
 797  0
         c.add(getOwner());
 798  0
         return c;
 799  
     }
 800  
 
 801  
     /*
 802  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#relocate(java.lang.Object)
 803  
      */
 804  
     public boolean relocate(Object base) {
 805  0
         return false;
 806  
     }
 807  
 
 808  
     public void encloserChanged(FigNode enclosed, 
 809  
             FigNode oldEncloser, FigNode newEncloser) {
 810  
         // Do nothing.        
 811  0
     }
 812  
 
 813  
     @Override
 814  
     public boolean doesAccept(Object objectToAccept) {
 815  0
         if (Model.getFacade().isAState(objectToAccept)) {
 816  0
             return true;
 817  0
         } else if (Model.getFacade().isASynchState(objectToAccept)) {
 818  0
             return true;
 819  0
         } else if (Model.getFacade().isAStubState(objectToAccept)) {
 820  0
             return true;
 821  0
         } else if (Model.getFacade().isAPseudostate(objectToAccept)) {
 822  0
             return true;
 823  0
         } else if (Model.getFacade().isAComment(objectToAccept)) {
 824  0
             return true;
 825  
         } 
 826  0
         return false;
 827  
     }
 828  
     
 829  
     @Override
 830  
     public DiagramElement drop(Object droppedObject, Point location) {
 831  0
         FigNodeModelElement figNode = null;
 832  
 
 833  
         // If location is non-null, convert to a rectangle that we can use
 834  0
         Rectangle bounds = null;
 835  0
         if (location != null) {
 836  0
             bounds = new Rectangle(location.x, location.y, 0, 0);
 837  
         }
 838  0
         DiagramSettings settings = getDiagramSettings();
 839  
 
 840  0
         if (Model.getFacade().isAActionState(droppedObject)) {
 841  0
             figNode = new FigActionState(droppedObject, bounds, settings);
 842  0
         } else if (Model.getFacade().isAFinalState(droppedObject)) {
 843  0
             figNode = new FigFinalState(droppedObject, bounds, settings);
 844  0
         } else if (Model.getFacade().isAStubState(droppedObject)) {
 845  0
             figNode = new FigStubState(droppedObject, bounds, settings);
 846  0
         } else if (Model.getFacade().isASubmachineState(droppedObject)) {
 847  0
             figNode = new FigSubmachineState(droppedObject, bounds, settings);
 848  0
         } else if (Model.getFacade().isACompositeState(droppedObject)) {
 849  0
             figNode = new FigCompositeState(droppedObject, bounds, settings);
 850  0
         } else if (Model.getFacade().isASynchState(droppedObject)) {
 851  0
             figNode = new FigSynchState(droppedObject, bounds, settings);
 852  0
         } else if (Model.getFacade().isAState(droppedObject)) {
 853  0
             figNode = new FigSimpleState(droppedObject, bounds, settings);
 854  0
         } else if (Model.getFacade().isAComment(droppedObject)) {
 855  0
             figNode = new FigComment(droppedObject, bounds, settings);
 856  0
         } else if (Model.getFacade().isAPseudostate(droppedObject)) {
 857  0
             Object kind = Model.getFacade().getKind(droppedObject);
 858  0
             if (kind == null) {
 859  0
                 LOG.warn("found a null type pseudostate");
 860  0
                 return null;
 861  
             }
 862  0
             if (kind.equals(Model.getPseudostateKind().getInitial())) {
 863  0
                 figNode = new FigInitialState(droppedObject, bounds, settings);
 864  0
             } else if (kind.equals(
 865  
                     Model.getPseudostateKind().getChoice())) {
 866  0
                 figNode = new FigBranchState(droppedObject, bounds, settings);
 867  0
             } else if (kind.equals(
 868  
                     Model.getPseudostateKind().getJunction())) {
 869  0
                 figNode = new FigJunctionState(droppedObject, bounds, settings);
 870  0
             } else if (kind.equals(
 871  
                     Model.getPseudostateKind().getFork())) {
 872  0
                 figNode = new FigForkState(droppedObject, bounds, settings);
 873  0
             } else if (kind.equals(
 874  
                     Model.getPseudostateKind().getJoin())) {
 875  0
                 figNode = new FigJoinState(droppedObject, bounds, settings);
 876  0
             } else if (kind.equals(
 877  
                     Model.getPseudostateKind().getShallowHistory())) {
 878  0
                 figNode = new FigShallowHistoryState(droppedObject, bounds, 
 879  
                         settings);
 880  0
             } else if (kind.equals(
 881  
                     Model.getPseudostateKind().getDeepHistory())) {
 882  0
                 figNode = new FigDeepHistoryState(droppedObject, bounds, 
 883  
                         settings);
 884  
             } else {
 885  0
                 LOG.warn("found a type not known");
 886  
             }
 887  
         }
 888  
         
 889  0
         if (figNode != null) {
 890  
             // if location is null here the position of the new figNode is set
 891  
             // after in org.tigris.gef.base.ModePlace.mousePressed(MouseEvent e)
 892  0
             if (location != null) {
 893  0
                 figNode.setLocation(location.x, location.y);
 894  
             }
 895  0
             LOG.debug("Dropped object " + droppedObject + " converted to " 
 896  
                     + figNode);
 897  
         } else {
 898  0
             LOG.debug("Dropped object NOT added " + figNode);
 899  
         }
 900  
         
 901  0
         return figNode;
 902  
     }
 903  
     
 904  
 
 905  
     public DiagramElement createDiagramElement(
 906  
             final Object modelElement,
 907  
             final Rectangle bounds) {
 908  
         
 909  0
         FigNodeModelElement figNode = null;
 910  
         
 911  0
         DiagramSettings settings = getDiagramSettings();
 912  
         
 913  0
         if (Model.getFacade().isAActionState(modelElement)) {
 914  0
             figNode = new FigActionState(modelElement, bounds, settings);
 915  0
         } else if (Model.getFacade().isAFinalState(modelElement)) {
 916  0
             figNode = new FigFinalState(modelElement, bounds, settings);
 917  0
         } else if (Model.getFacade().isAStubState(modelElement)) {
 918  0
             figNode = new FigStubState(modelElement, bounds, settings);
 919  0
         } else if (Model.getFacade().isASubmachineState(modelElement)) {
 920  0
             figNode = new FigSubmachineState(modelElement, bounds, settings);
 921  0
         } else if (Model.getFacade().isACompositeState(modelElement)) {
 922  0
             figNode = new FigCompositeState(modelElement, bounds, settings);
 923  0
         } else if (Model.getFacade().isASynchState(modelElement)) {
 924  0
             figNode = new FigSynchState(modelElement, bounds, settings);
 925  0
         } else if (Model.getFacade().isAState(modelElement)) {
 926  0
             figNode = new FigSimpleState(modelElement, bounds, settings);
 927  0
         } else if (Model.getFacade().isAComment(modelElement)) {
 928  0
             figNode = new FigComment(modelElement, bounds, settings);
 929  0
         } else if (Model.getFacade().isAPseudostate(modelElement)) {
 930  0
             Object kind = Model.getFacade().getKind(modelElement);
 931  0
             if (kind == null) {
 932  0
                 LOG.warn("found a null type pseudostate");
 933  0
                 return null;
 934  
             }
 935  0
             if (kind.equals(Model.getPseudostateKind().getInitial())) {
 936  0
                 figNode = new FigInitialState(modelElement, bounds, settings);
 937  0
             } else if (kind.equals(
 938  
                     Model.getPseudostateKind().getChoice())) {
 939  0
                 figNode = new FigBranchState(modelElement, bounds, settings);
 940  0
             } else if (kind.equals(
 941  
                     Model.getPseudostateKind().getJunction())) {
 942  0
                 figNode = new FigJunctionState(modelElement, bounds, settings);
 943  0
             } else if (kind.equals(
 944  
                     Model.getPseudostateKind().getFork())) {
 945  0
                 figNode = new FigForkState(modelElement, bounds, settings);
 946  0
             } else if (kind.equals(
 947  
                     Model.getPseudostateKind().getJoin())) {
 948  0
                 figNode = new FigJoinState(modelElement, bounds, settings);
 949  0
             } else if (kind.equals(
 950  
                     Model.getPseudostateKind().getShallowHistory())) {
 951  0
                 figNode = new FigShallowHistoryState(modelElement, bounds, 
 952  
                         settings);
 953  0
             } else if (kind.equals(
 954  
                     Model.getPseudostateKind().getDeepHistory())) {
 955  0
                 figNode = new FigDeepHistoryState(modelElement, bounds, 
 956  
                         settings);
 957  
             } else {
 958  0
                 LOG.warn("found a type not known");
 959  
             }
 960  
         }
 961  
         
 962  0
         if (figNode != null) {
 963  0
             LOG.debug("Model element " + modelElement + " converted to " 
 964  
                     + figNode);
 965  
         } else {
 966  0
             LOG.debug("Dropped object NOT added " + figNode);
 967  
         }
 968  0
         return figNode;
 969  
     }
 970  
     
 971  
 }