Coverage Report - org.argouml.uml.reveng.DiagramInterface
 
Classes in this File Line Coverage Branch Coverage Complexity
DiagramInterface
0%
0/81
0%
0/34
2.176
 
 1  
 /* $Id: DiagramInterface.java 17870 2010-01-12 20:49:32Z 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  
  *    mvw
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 1996-2009 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.reveng;
 40  
 
 41  
 import java.awt.Rectangle;
 42  
 import java.beans.PropertyVetoException;
 43  
 import java.util.ArrayList;
 44  
 import java.util.List;
 45  
 
 46  
 import org.apache.log4j.Logger;
 47  
 import org.argouml.kernel.Project;
 48  
 import org.argouml.model.Model;
 49  
 import org.argouml.uml.diagram.ArgoDiagram;
 50  
 import org.argouml.uml.diagram.DiagramElement;
 51  
 import org.argouml.uml.diagram.DiagramFactory;
 52  
 import org.argouml.uml.diagram.static_structure.ClassDiagramGraphModel;
 53  
 import org.argouml.uml.diagram.static_structure.ui.FigClassifierBox;
 54  
 import org.argouml.uml.diagram.ui.FigNodeModelElement;
 55  
 import org.tigris.gef.base.Editor;
 56  
 import org.tigris.gef.base.LayerPerspective;
 57  
 import org.tigris.gef.presentation.Fig;
 58  
 
 59  
 /**
 60  
  * Instances of this class interface the current Class diagram.<p>
 61  
  *
 62  
  * This class is used by the import mechanism to create packages,
 63  
  * interfaces and classes within the diagrams.
 64  
  * It is also used to find the correct diagram to work in.
 65  
  *
 66  
  * @author Andreas Rueckert
 67  
  * @since 0.9
 68  
  */
 69  
 public class DiagramInterface {
 70  
 
 71  
     private static final char DIAGRAM_NAME_SEPARATOR = '_';
 72  
     private static final String DIAGRAM_NAME_SUFFIX = "classes";
 73  
 
 74  0
     private static final Logger LOG =
 75  
         Logger.getLogger(DiagramInterface.class);
 76  
 
 77  
     private Editor currentEditor;
 78  
 
 79  
     /**
 80  
      * To know what diagrams we have to layout after the import,
 81  
      * we store them in this list.
 82  
      */
 83  0
     private List<ArgoDiagram> modifiedDiagrams = 
 84  
         new ArrayList<ArgoDiagram>();
 85  
 
 86  
     /**
 87  
      * The current GraphModel of the current classdiagram.
 88  
      */
 89  
     private ClassDiagramGraphModel currentGM;
 90  
 
 91  
     /**
 92  
      * The current Layer of the current classdiagram.
 93  
      */
 94  
     private LayerPerspective currentLayer;
 95  
 
 96  
     /**
 97  
      * The current diagram for the isInDiagram method.
 98  
      */
 99  
     private ArgoDiagram currentDiagram;
 100  
 
 101  
     private Project currentProject;
 102  
     
 103  
     /**
 104  
      * Creates a new DiagramInterface.
 105  
      *
 106  
      * @param editor The editor to operate on.
 107  
      */
 108  0
     public DiagramInterface(Editor editor) {
 109  0
           currentEditor = editor;
 110  0
           LayerPerspective layer = 
 111  
               (LayerPerspective) editor.getLayerManager().getActiveLayer();
 112  0
           currentProject = ((ArgoDiagram) layer.getDiagram()).getProject();
 113  0
     }
 114  
 
 115  
     /**
 116  
      * Creates a new DiagramInterface.
 117  
      *
 118  
      * @param editor The editor to operate on.
 119  
      * @param project the project being operated on
 120  
      */
 121  0
     public DiagramInterface(Editor editor, Project project) {
 122  0
         currentEditor = editor;
 123  0
     }
 124  
     
 125  
     /**
 126  
      * Get the current editor.
 127  
      *
 128  
      * @return The current editor.
 129  
      */
 130  
     Editor getEditor() {
 131  0
         return currentEditor;
 132  
     }
 133  
 
 134  
     /**
 135  
      * Mark a diagram as modified, so we can layout it, after the
 136  
      * import is complete.<p>
 137  
      *
 138  
      * If the diagram is not already marked, add it to the list.<p>
 139  
      *
 140  
      * @param diagram The diagram to mark as modified.
 141  
      */
 142  
     void markDiagramAsModified(ArgoDiagram diagram) {
 143  0
         if (!modifiedDiagrams.contains(diagram)) {
 144  0
             modifiedDiagrams.add(diagram);
 145  
         }
 146  0
     }
 147  
     
 148  
 
 149  
     /**
 150  
      * Get the list of modified diagrams.
 151  
      *
 152  
      * @return The list of modified diagrams.
 153  
      */
 154  
     public List<ArgoDiagram> getModifiedDiagramList() {
 155  0
         return modifiedDiagrams;
 156  
     }
 157  
     
 158  
     /**
 159  
      * Reset the list of modified diagrams.
 160  
      */
 161  
     void resetModifiedDiagrams() {
 162  0
         modifiedDiagrams = new ArrayList<ArgoDiagram>();
 163  0
     }
 164  
 
 165  
     /**
 166  
      * Add a package to the current diagram. If the package already has
 167  
      * a representation in the current diagram, it is not(!) added.
 168  
      *
 169  
      * @param newPackage The package to add.
 170  
      */
 171  
     public void addPackage(Object newPackage) {
 172  0
         if (!isInDiagram(newPackage)) {
 173  0
             if (currentGM.canAddNode(newPackage)) {
 174  0
                 DiagramElement newPackageFig =
 175  
                     currentDiagram.createDiagramElement(
 176  
                         newPackage,
 177  
                         new Rectangle(0, 0, 0, 0));
 178  0
                 currentLayer.add((FigNodeModelElement) newPackageFig);
 179  0
                 currentGM.addNode(newPackage);
 180  0
                 currentLayer.putInPosition((FigNodeModelElement) newPackageFig);
 181  
             }
 182  
         }
 183  0
     }
 184  
 
 185  
     /**
 186  
      * Check if a given package has a representation in the current
 187  
      * diagram.
 188  
      *
 189  
      * @param p The package to lookup in the current diagram.
 190  
      * @return true if this package has a figure in the current diagram,
 191  
      *         false otherwise.
 192  
      */
 193  
     public boolean isInDiagram(Object p) {
 194  0
         if (currentDiagram == null) {
 195  0
             return false;
 196  
         } else {
 197  0
             return currentDiagram.getNodes().contains(p);
 198  
         }
 199  
     }
 200  
 
 201  
     /**
 202  
      * Check if this diagram already exists in the project.<p>
 203  
      *
 204  
      * @param name package name (converted to class name)
 205  
      * @return true if diagram exists in project.
 206  
      */
 207  
     public boolean isDiagramInProject(String name) {
 208  0
         if (currentProject == null) {
 209  0
             throw new RuntimeException("current project not set yet");
 210  
         }
 211  0
         return currentProject.getDiagram(getDiagramName(name)) != null;
 212  
     }
 213  
 
 214  
     /**
 215  
      * Create a diagram name from a package name.
 216  
      *
 217  
      * @param packageName The package name.
 218  
      * @return The name for the diagram.
 219  
      */
 220  
     private String getDiagramName(String packageName) {
 221  
         /*
 222  
          * TODO: This transformation is Java specific. We need a more
 223  
          * language/notation scheme for specifying qualified names.
 224  
          * Possible algorithm - replace all punctuation with our
 225  
          * internal separator, replace multiple separators with a single
 226  
          * instance (for languages like C++).  What about I18N? - tfm
 227  
          */
 228  0
         return packageName.replace('.', DIAGRAM_NAME_SEPARATOR)
 229  
                 + DIAGRAM_NAME_SEPARATOR + DIAGRAM_NAME_SUFFIX;
 230  
     }
 231  
 
 232  
     /**
 233  
      * Select a class diagram as the current diagram, creating it
 234  
      * if necessary.
 235  
      *
 236  
      * @param p The package.
 237  
      * @param name The fully qualified name of this package.
 238  
      */
 239  
     public void selectClassDiagram(Object p, String name) {
 240  
         // Check if this diagram already exists in the project
 241  0
         if (currentProject == null) {
 242  0
             throw new RuntimeException("current project not set yet");
 243  
         }
 244  0
         ArgoDiagram m = currentProject.getDiagram(getDiagramName(name));
 245  0
         if (m != null) {
 246  
             // The diagram already exists in this project. Select it
 247  
             // as the current target.
 248  0
             setCurrentDiagram(m);
 249  
         } else {
 250  
             // Otherwise create a new classdiagram for the package.
 251  0
             addClassDiagram(p, name);
 252  
         }
 253  0
     }
 254  
 
 255  
     /**
 256  
      * Add a new class diagram for a package to the project.
 257  
      * 
 258  
      * @param ns
 259  
      *            The namespace to contain the diagram. If null, the root model
 260  
      *            will be used.
 261  
      * @param name
 262  
      *            The fully qualified name of the package, which is used to
 263  
      *            generate the diagram name from.
 264  
      */
 265  
     public void addClassDiagram(Object ns, String name) {
 266  0
         if (currentProject == null) {
 267  0
             throw new RuntimeException("current project not set yet");
 268  
         }
 269  0
         ArgoDiagram d = DiagramFactory.getInstance().createDiagram(
 270  
                 DiagramFactory.DiagramType.Class,
 271  
                 ns == null ? currentProject.getRoot() : ns, null);
 272  
 
 273  
         try {
 274  0
             d.setName(getDiagramName(name));
 275  0
         } catch (PropertyVetoException pve) { 
 276  0
             LOG.error("Failed to set diagram name.", pve);
 277  0
         }
 278  0
         currentProject.addMember(d);
 279  0
         setCurrentDiagram(d);
 280  0
     }
 281  
 
 282  
     /**
 283  
      * Add a class to the current diagram.
 284  
      *
 285  
      * @param newClass The new class to add to the editor.
 286  
      * @param minimise minimise the class fig by hiding compartiments
 287  
      *                 (of attributes and operations)
 288  
      */
 289  
     public void addClass(Object newClass, boolean minimise) {
 290  0
         addClassifier(newClass, minimise);
 291  0
     }
 292  
 
 293  
     /**
 294  
      * Add a classier to the current diagram.
 295  
      *
 296  
      * @param classifier The new class or interface to add to the editor.
 297  
      * @param minimise minimise the class fig by hiding compartments
 298  
      *                 (of attributes and operations)
 299  
      */
 300  
     private void addClassifier(Object classifier, boolean minimise) {
 301  
         // if the classifier is not in the current diagram, add it:
 302  0
         if (currentGM.canAddNode(classifier)) {
 303  0
             FigClassifierBox newFig =
 304  
                 (FigClassifierBox) currentDiagram.createDiagramElement(
 305  
                         classifier,
 306  
                         new Rectangle(0, 0, 0, 0));
 307  
             
 308  
             /*
 309  
              * The following calls are ORDER DEPENDENT. Not sure why, but the
 310  
              * layer add must come before the model add or we'll end up with
 311  
              * duplicate figures in the diagram. - tfm
 312  
              */            
 313  0
             currentLayer.add(newFig);
 314  0
             currentGM.addNode(classifier);
 315  0
             currentLayer.putInPosition(newFig);
 316  
 
 317  0
             newFig.setOperationsVisible(!minimise);
 318  0
             if (Model.getFacade().isAClass(classifier)) {
 319  0
                 newFig.setAttributesVisible(!minimise);
 320  
             }
 321  
 
 322  0
             newFig.renderingChanged();
 323  0
         } else {
 324  
             // the class is in the diagram
 325  
             // so we are on a second pass,
 326  
             // find the fig for this class can update its visible state.
 327  0
             FigClassifierBox existingFig = null;
 328  0
             List figs = currentLayer.getContentsNoEdges();
 329  0
             for (int i = 0; i < figs.size(); i++) {
 330  0
                 Fig fig = (Fig) figs.get(i);
 331  0
                 if (classifier == fig.getOwner()) {
 332  0
                     existingFig = (FigClassifierBox) fig;
 333  
                 }
 334  
             }
 335  0
             existingFig.renderingChanged();
 336  
         }
 337  
 
 338  
         // add edges
 339  
         // for a 2-pass r.e. process we might have already added the
 340  
         // class but not its edges
 341  0
         currentGM.addNodeRelatedEdges(classifier);
 342  0
     }
 343  
 
 344  
     /**
 345  
      * Add a interface to the current diagram.
 346  
      *
 347  
      * @param newInterface The interface to add.
 348  
      * @param minimise minimise the class fig by hiding compartiments
 349  
      *                 (of attributes and operations)
 350  
      */
 351  
     public void addInterface(Object newInterface, boolean minimise) {
 352  0
         addClassifier(newInterface, minimise);
 353  0
     }
 354  
 
 355  
 
 356  
     /**
 357  
      * Creates class diagram under the root.
 358  
      * Is used for classes out of packages.
 359  
      *
 360  
      */
 361  
     public void createRootClassDiagram() {
 362  0
         selectClassDiagram(null, "");
 363  0
     }
 364  
 
 365  
     /**
 366  
      * selects a diagram without affecting the gui.
 367  
      *
 368  
      * @param diagram the diagram
 369  
      */
 370  
     public void setCurrentDiagram(ArgoDiagram diagram) {
 371  0
         if (diagram == null) {
 372  0
             throw new RuntimeException("you can't select a null diagram");
 373  
         }
 374  
 
 375  0
         currentGM = (ClassDiagramGraphModel) diagram.getGraphModel();
 376  0
         currentLayer = diagram.getLayer();
 377  0
         currentDiagram = diagram;
 378  0
         currentProject = diagram.getProject();
 379  
         
 380  0
         markDiagramAsModified(diagram);
 381  0
     }
 382  
 
 383  
 }
 384  
 
 385  
 
 386  
 
 387  
 
 388  
 
 389  
 
 390  
 
 391  
 
 392  
 
 393  
 
 394  
 
 395  
 
 396  
 
 397  
 
 398  
 
 399  
 
 400  
 
 401  
 
 402  
 
 403  
 
 404  
 
 405  
 
 406  
 
 407  
 
 408