Coverage Report - org.argouml.uml.diagram.use_case.ui.UMLUseCaseDiagram
 
Classes in this File Line Coverage Branch Coverage Complexity
UMLUseCaseDiagram
56%
65/116
23%
15/64
2.556
 
 1  
 /* $Id: UMLUseCaseDiagram.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  
  *    Michiel van der Wulp
 11  
  *    Bob Tarling
 12  
  *****************************************************************************
 13  
  *
 14  
  * Some portions of this file was previously release using the BSD License:
 15  
  */
 16  
 
 17  
 // Copyright (c) 1996-2009 The Regents of the University of California. All
 18  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 19  
 // software and its documentation without fee, and without a written
 20  
 // agreement is hereby granted, provided that the above copyright notice
 21  
 // and this paragraph appear in all copies.  This software program and
 22  
 // documentation are copyrighted by The Regents of the University of
 23  
 // California. The software program and documentation are supplied "AS
 24  
 // IS", without any accompanying services from The Regents. The Regents
 25  
 // does not warrant that the operation of the program will be
 26  
 // uninterrupted or error-free. The end-user understands that the program
 27  
 // was developed for research purposes and is advised not to rely
 28  
 // exclusively on the program for any reason.  IN NO EVENT SHALL THE
 29  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 30  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 31  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 32  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 33  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 34  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 35  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 36  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 37  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 38  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 39  
 
 40  
 package org.argouml.uml.diagram.use_case.ui;
 41  
 
 42  
 import java.awt.Point;
 43  
 import java.awt.Rectangle;
 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.Model;
 53  
 import org.argouml.ui.CmdCreateNode;
 54  
 import org.argouml.uml.diagram.DiagramElement;
 55  
 import org.argouml.uml.diagram.DiagramSettings;
 56  
 import org.argouml.uml.diagram.static_structure.ui.FigComment;
 57  
 import org.argouml.uml.diagram.static_structure.ui.FigPackage;
 58  
 import org.argouml.uml.diagram.ui.ActionAddExtensionPoint;
 59  
 import org.argouml.uml.diagram.ui.ActionSetAddAssociationMode;
 60  
 import org.argouml.uml.diagram.ui.ActionSetMode;
 61  
 import org.argouml.uml.diagram.ui.FigNodeModelElement;
 62  
 import org.argouml.uml.diagram.ui.RadioAction;
 63  
 import org.argouml.uml.diagram.ui.UMLDiagram;
 64  
 import org.argouml.uml.diagram.use_case.UseCaseDiagramGraphModel;
 65  
 import org.argouml.util.ToolBarUtility;
 66  
 import org.tigris.gef.base.LayerPerspective;
 67  
 import org.tigris.gef.base.LayerPerspectiveMutable;
 68  
 import org.tigris.gef.base.ModeCreatePolyEdge;
 69  
 import org.tigris.gef.presentation.FigNode;
 70  
 
 71  
 /**
 72  
  * The base class of the use case diagram.<p>
 73  
  *
 74  
  * Defines the toolbar, provides for its initialization and provides
 75  
  * constructors for a top level diagram and one within a defined
 76  
  * namespace.<p>
 77  
  * 
 78  
  * A use case diagram has as owner either a package or a classifier.
 79  
  */
 80  
 public class UMLUseCaseDiagram extends UMLDiagram {
 81  
 
 82  900
     private static final Logger LOG = Logger.getLogger(UMLUseCaseDiagram.class);
 83  
 
 84  
     // Actions specific to the use case diagram toolbar
 85  
 
 86  
     /**
 87  
      * Tool to add an actor node.<p>
 88  
      */
 89  
     private Action actionActor;
 90  
 
 91  
     /**
 92  
      * Tool to add a use case node.<p>
 93  
      */
 94  
     private Action actionUseCase;
 95  
 
 96  
     /**
 97  
      * Tool to create an association between UML artifacts using a
 98  
      * polyedge.<p>
 99  
      */
 100  
     private Action actionAssociation;
 101  
     private Action actionAggregation;
 102  
     private Action actionComposition;
 103  
     private Action actionUniAssociation;
 104  
     private Action actionUniAggregation;
 105  
     private Action actionUniComposition;
 106  
 
 107  
     /**
 108  
      * Tool to create a generalization between UML artifacts using a
 109  
      * polyedge.<p>
 110  
      */
 111  
     private Action actionGeneralize;
 112  
 
 113  
     /**
 114  
      * Tool to create an extend relationship between UML use cases
 115  
      * using a polyedge.<p>
 116  
      */
 117  
     private Action actionExtend;
 118  
 
 119  
     /**
 120  
      * Tool to create an include relationship between UML use cases
 121  
      * using a polyedge.<p>
 122  
      */
 123  
     private Action actionInclude;
 124  
 
 125  
     /**
 126  
      * Tool to create a dependency between UML artifacts using a
 127  
      * polyedge.<p>
 128  
      */
 129  
     private Action actionDependency;
 130  
 
 131  
     private Action actionExtensionPoint;
 132  
 
 133  
     /**
 134  
      * Construct a new use case diagram with no defined namespace.<p>
 135  
      *
 136  
      * Note we must never call this directly, since defining the
 137  
      * namespace is what makes everything work. However GEF will call
 138  
      * it directly when loading a new diagram, so it must remain
 139  
      * public.<p>
 140  
      *
 141  
      * A unique name is constructed by using the serial index.
 142  
      * We allow for the possibility
 143  
      * that setting this may fail, in which case no name is set.<p>
 144  
      * @deprecated ony for use by PGML parser.
 145  
      */
 146  
     @Deprecated
 147  
     public UMLUseCaseDiagram() {
 148  973
         super(new UseCaseDiagramGraphModel());
 149  
         try {
 150  973
             setName(getNewDiagramName());
 151  973
         } catch (PropertyVetoException pve) { }
 152  973
     }
 153  
 
 154  
     /**
 155  
      * Construct a new use case diagram with in a defined namespace.<p>
 156  
      *
 157  
      * Invokes the generic constructor {@link #UMLUseCaseDiagram()},
 158  
      * then intialises the namespace (which initializes all the
 159  
      * graphics).<p>
 160  
      *
 161  
      * This is the constructor which should always be used.<p>
 162  
      *
 163  
      * @param m  the desired namespace for this diagram.
 164  
      */
 165  
     public UMLUseCaseDiagram(Object m) {
 166  973
         this();
 167  973
         if (!Model.getFacade().isANamespace(m)) {
 168  0
             throw new IllegalArgumentException();
 169  
         }
 170  973
         setNamespace(m);
 171  973
     }
 172  
 
 173  
     /**
 174  
      * Constructor.
 175  
      *
 176  
      * @param name the name for the diagram
 177  
      * @param namespace the namespace for the diagram
 178  
      */
 179  
     public UMLUseCaseDiagram(String name, Object namespace) {
 180  0
         this(namespace);
 181  0
         if (!Model.getFacade().isANamespace(namespace)) {
 182  0
             throw new IllegalArgumentException();
 183  
         }
 184  
         try {
 185  0
             setName(name);
 186  0
         } catch (PropertyVetoException v) { }
 187  0
     }
 188  
 
 189  
     /**
 190  
      * Perform a number of important initializations of a <em>Use Case
 191  
      * Diagram</em>.<p>
 192  
      *
 193  
      * Creates a new graph model for the diagram, settings its
 194  
      * namespace to that supplied.<p>
 195  
      *
 196  
      * Changed <em>lay</em> from <em>LayerPerspective</em> to
 197  
      * <em>LayerPerspectiveMutable</em>. This class is a child of
 198  
      * <em>LayerPerspective</em> and was implemented to correct some
 199  
      * difficulties in changing the model. <em>lay</em> is used mainly
 200  
      * in <em>LayerManager</em>(GEF) to control the adding, changing
 201  
      * and deleting of items in a layer of the diagram.<p>
 202  
      *
 203  
      * Set a renderer suitable for the use case diagram.<p>
 204  
      *
 205  
      * <em>Note</em>. This is declared as public. Not clear that other
 206  
      * classes should be allowed to invoke this method.<p>
 207  
      *
 208  
      * @param handle Namespace to be used for this diagram.
 209  
      *
 210  
      * @author   psager@tigris.org  Jan 24, 2002
 211  
      */
 212  
     @Override
 213  
     public void setNamespace(Object handle) {
 214  973
         if (!Model.getFacade().isANamespace(handle)) {
 215  0
             LOG.error(
 216  
                 "Illegal argument. Object " + handle + " is not a namespace");
 217  0
             throw new IllegalArgumentException(
 218  
                 "Illegal argument. Object " + handle + " is not a namespace");
 219  
         }
 220  973
         Object m = handle;
 221  973
         super.setNamespace(m);
 222  
 
 223  973
         UseCaseDiagramGraphModel gm = 
 224  
             (UseCaseDiagramGraphModel) getGraphModel();
 225  973
         gm.setHomeModel(m);
 226  973
         LayerPerspective lay =
 227  
             new LayerPerspectiveMutable(Model.getFacade().getName(m), gm);
 228  973
         UseCaseDiagramRenderer rend = new UseCaseDiagramRenderer();
 229  973
         lay.setGraphNodeRenderer(rend);
 230  973
         lay.setGraphEdgeRenderer(rend);
 231  973
         setLayer(lay);
 232  
 
 233  
         // The renderer should be a singleton
 234  
 
 235  973
     }
 236  
     
 237  
     /*
 238  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getUmlActions()
 239  
      */
 240  
     protected Object[] getUmlActions() {
 241  54
         Object[] actions =
 242  
         {
 243  
             getActionActor(),
 244  
             getActionUseCase(),
 245  
             null,
 246  
             getAssociationActions(),
 247  
             getActionDependency(),
 248  
             getActionGeneralize(),
 249  
             getActionExtend(),
 250  
             getActionInclude(),
 251  
             null,
 252  
             getActionExtensionPoint(),
 253  
         };
 254  54
         return actions;
 255  
     }
 256  
 
 257  
     private Object[] getAssociationActions() {
 258  54
         Object[][] actions = {
 259  
             {getActionAssociation(), getActionUniAssociation() },
 260  
             {getActionAggregation(), getActionUniAggregation() },
 261  
             {getActionComposition(), getActionUniComposition() },
 262  
         };
 263  54
         ToolBarUtility.manageDefault(actions, "diagram.usecase.association");
 264  54
         return actions;
 265  
     }
 266  
 
 267  
     /*
 268  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#getLabelName()
 269  
      */
 270  
     public String getLabelName() {
 271  984
         return Translator.localize("label.usecase-diagram");
 272  
     }
 273  
 
 274  
     /**
 275  
      * @return Returns the actionActor.
 276  
      */
 277  
     protected Action getActionActor() {
 278  54
         if (actionActor == null) {
 279  54
             actionActor = new RadioAction(new CmdCreateNode(
 280  
                     Model.getMetaTypes().getActor(), "button.new-actor"));
 281  
         }
 282  54
         return actionActor;
 283  
     }
 284  
     /**
 285  
      * @return Returns the actionAggregation.
 286  
      */
 287  
     protected Action getActionAggregation() {
 288  54
         if (actionAggregation == null) {
 289  54
             actionAggregation = new RadioAction(
 290  
                     new ActionSetAddAssociationMode(
 291  
                         Model.getAggregationKind().getAggregate(),
 292  
                         false,
 293  
                         "button.new-aggregation"));
 294  
         }
 295  54
         return actionAggregation;
 296  
     }
 297  
     /**
 298  
      * @return Returns the actionAssociation.
 299  
      */
 300  
     protected Action getActionAssociation() {
 301  54
         if (actionAssociation == null) {
 302  54
             actionAssociation = new RadioAction(
 303  
                     new ActionSetAddAssociationMode(
 304  
                         Model.getAggregationKind().getNone(),
 305  
                         false,
 306  
                         "button.new-association"));
 307  
         }
 308  54
         return actionAssociation;
 309  
     }
 310  
     /**
 311  
      * @return Returns the actionComposition.
 312  
      */
 313  
     protected Action getActionComposition() {
 314  54
         if (actionComposition == null) {
 315  54
             actionComposition = new RadioAction(
 316  
                     new ActionSetAddAssociationMode(
 317  
                         Model.getAggregationKind().getComposite(),
 318  
                         false,
 319  
                         "button.new-composition"));
 320  
         }
 321  54
         return actionComposition;
 322  
     }
 323  
     /**
 324  
      * @return Returns the actionDependency.
 325  
      */
 326  
     protected Action getActionDependency() {
 327  54
         if (actionDependency == null) {
 328  54
             actionDependency = new RadioAction(
 329  
                     new ActionSetMode(
 330  
                         ModeCreatePolyEdge.class,
 331  
                         "edgeClass",
 332  
                         Model.getMetaTypes().getDependency(),
 333  
                         "button.new-dependency"));
 334  
         }
 335  54
         return actionDependency;
 336  
     }
 337  
     /**
 338  
      * @return Returns the actionExtend.
 339  
      */
 340  
     protected Action getActionExtend() {
 341  54
         if (actionExtend == null) {
 342  54
             actionExtend = new RadioAction(
 343  
                     new ActionSetMode(
 344  
                         ModeCreatePolyEdge.class,
 345  
                         "edgeClass",
 346  
                         Model.getMetaTypes().getExtend(),
 347  
                         "button.new-extend"));
 348  
         }
 349  54
         return actionExtend;
 350  
     }
 351  
     /**
 352  
      * @return Returns the actionGeneralize.
 353  
      */
 354  
     protected Action getActionGeneralize() {
 355  54
         if (actionGeneralize == null) {
 356  54
             actionGeneralize = new RadioAction(
 357  
                     new ActionSetMode(
 358  
                         ModeCreatePolyEdge.class,
 359  
                         "edgeClass",
 360  
                         Model.getMetaTypes().getGeneralization(),
 361  
                         "button.new-generalization"));
 362  
         }
 363  54
         return actionGeneralize;
 364  
     }
 365  
     /**
 366  
      * @return Returns the actionInclude.
 367  
      */
 368  
     protected Action getActionInclude() {
 369  54
         if (actionInclude == null) {
 370  54
             actionInclude = new RadioAction(
 371  
                     new ActionSetMode(
 372  
                         ModeCreatePolyEdge.class,
 373  
                         "edgeClass",
 374  
                         Model.getMetaTypes().getInclude(),
 375  
                         "button.new-include"));
 376  
         }
 377  54
         return actionInclude;
 378  
     }
 379  
     /**
 380  
      * @return Returns the actionUniAggregation.
 381  
      */
 382  
     protected Action getActionUniAggregation() {
 383  54
         if (actionUniAggregation == null) {
 384  54
             actionUniAggregation  = new RadioAction(
 385  
                     new ActionSetAddAssociationMode(
 386  
                             Model.getAggregationKind().getAggregate(),
 387  
                             true,
 388  
                             "button.new-uniaggregation"));
 389  
         }
 390  54
         return actionUniAggregation;
 391  
     }
 392  
     /**
 393  
      * @return Returns the actionUniAssociation.
 394  
      */
 395  
     protected Action getActionUniAssociation() {
 396  54
         if (actionUniAssociation == null) {
 397  54
             actionUniAssociation  = new RadioAction(
 398  
                     new ActionSetAddAssociationMode(
 399  
                             Model.getAggregationKind().getNone(),
 400  
                             true,
 401  
                             "button.new-uniassociation"));
 402  
         }
 403  54
         return actionUniAssociation;
 404  
     }
 405  
     /**
 406  
      * @return Returns the actionUniComposition.
 407  
      */
 408  
     protected Action getActionUniComposition() {
 409  54
         if (actionUniComposition == null) {
 410  54
             actionUniComposition  = new RadioAction(
 411  
                     new ActionSetAddAssociationMode(
 412  
                             Model.getAggregationKind().getComposite(),
 413  
                             true,
 414  
                             "button.new-unicomposition"));
 415  
         }
 416  54
         return actionUniComposition;
 417  
     }
 418  
     /**
 419  
      * @return Returns the actionUseCase.
 420  
      */
 421  
     protected Action getActionUseCase() {
 422  54
         if (actionUseCase == null) {
 423  54
             actionUseCase = new RadioAction(new CmdCreateNode(
 424  
                     Model.getMetaTypes().getUseCase(), "button.new-usecase"));
 425  
         }
 426  54
         return actionUseCase;
 427  
     }
 428  
 
 429  
     /**
 430  
      * @return the action to create an extension point
 431  
      */
 432  
     protected Action getActionExtensionPoint() {
 433  54
         if (actionExtensionPoint == null) {
 434  54
             actionExtensionPoint = ActionAddExtensionPoint.singleton();
 435  
         }
 436  54
         return actionExtensionPoint;
 437  
     }
 438  
 
 439  
     /*
 440  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#isRelocationAllowed(java.lang.Object)
 441  
      */
 442  
     public boolean isRelocationAllowed(Object base)  {
 443  0
             return Model.getFacade().isAPackage(base)
 444  
                 || Model.getFacade().isAClassifier(base);
 445  
     }
 446  
 
 447  
     /*
 448  
      * @see org.argouml.uml.diagram.ui.UMLDiagram#relocate(java.lang.Object)
 449  
      */
 450  
     public boolean relocate(Object base) {
 451  0
         setNamespace(base);
 452  0
         damage();
 453  0
         return true;
 454  
     }
 455  
 
 456  
     /*
 457  
      * Allow all Packages and Classifiers..
 458  
      */
 459  
     @SuppressWarnings("unchecked")
 460  
     public Collection getRelocationCandidates(Object root) {
 461  0
         Collection c = new HashSet();
 462  0
         c.add(Model.getModelManagementHelper()
 463  
                 .getAllModelElementsOfKindWithModel(root, 
 464  
                         Model.getMetaTypes().getPackage()));
 465  0
         c.add(Model.getModelManagementHelper()
 466  
                 .getAllModelElementsOfKindWithModel(root, 
 467  
                         Model.getMetaTypes().getClassifier()));
 468  0
         return c;
 469  
     }
 470  
 
 471  
     public void encloserChanged(FigNode enclosed, 
 472  
             FigNode oldEncloser, FigNode newEncloser) {
 473  
         // Do nothing.        
 474  0
     }
 475  
     
 476  
     @Override
 477  
     public boolean doesAccept(Object objectToAccept) {
 478  0
         if (Model.getFacade().isAActor(objectToAccept)) {
 479  0
             return true;
 480  0
         } else if (Model.getFacade().isAUseCase(objectToAccept)) {
 481  0
             return true;
 482  0
         } else if (Model.getFacade().isAComment(objectToAccept)) {
 483  0
             return true;
 484  0
         } else if (Model.getFacade().isAPackage(objectToAccept)) {
 485  
             /* We accept a Package, but not a Model or a Subsystem. */
 486  0
             if (Model.getFacade().isAModel(objectToAccept)) {
 487  0
                 return false;
 488  0
             } else if (Model.getFacade().isASubsystem(objectToAccept)) {
 489  0
                 return false;
 490  
             }
 491  0
             return true;
 492  
         }
 493  0
         return false;
 494  
 
 495  
     }
 496  
     
 497  
     @Override
 498  
     public DiagramElement drop(Object droppedObject, Point location) {
 499  0
         DiagramElement figNode = null;
 500  
        
 501  
         // If location is non-null, convert to a rectangle that we can use
 502  0
         Rectangle bounds = null;
 503  0
         if (location != null) {
 504  0
             bounds = new Rectangle(location.x, location.y, 0, 0);
 505  
         }
 506  
 
 507  0
         return createDiagramElement(droppedObject, bounds);
 508  
     }
 509  
 
 510  
     public DiagramElement createDiagramElement(
 511  
             final Object modelElement,
 512  
             final Rectangle bounds) {
 513  
         
 514  0
         FigNodeModelElement figNode = null;
 515  
         
 516  0
         DiagramSettings settings = getDiagramSettings();
 517  
         
 518  0
         if (Model.getFacade().isAActor(modelElement)) {
 519  0
             figNode = new FigActor(modelElement, bounds, settings);
 520  0
         } else if (Model.getFacade().isAUseCase(modelElement)) {
 521  0
             figNode = new FigUseCase(modelElement, bounds, settings);
 522  0
         } else if (Model.getFacade().isAComment(modelElement)) {
 523  0
             figNode = new FigComment(modelElement, bounds, settings);
 524  0
         } else if (Model.getFacade().isAPackage(modelElement)) {
 525  0
             if (!Model.getFacade().isAModel(modelElement)
 526  
                     && !Model.getFacade().isASubsystem(modelElement)) {
 527  
                 /* If we do not exclude a Model here, then dropping the 
 528  
                  * Model on a UseCase diagram causes a package 
 529  
                  * to be drawn. */
 530  0
                 figNode = new FigPackage(modelElement, bounds, settings);
 531  
             }
 532  
         }
 533  0
         if (figNode != null) {
 534  0
             LOG.debug("Model element " + modelElement + " converted to " 
 535  
                     + figNode);
 536  
         } else {
 537  0
             LOG.debug("Dropped object NOT added " + figNode);
 538  
         }
 539  0
         return figNode;
 540  
     }
 541  
 }