/* $Id: UmlDiagramRenderer.java 18404 2010-05-26 07:42:05Z bobtarling $ ***************************************************************************** * Copyright (c) 2009 Contributors - see below * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * bobtarling ***************************************************************************** * * Some portions of this file was previously release using the BSD License: */ // Copyright (c) 1996-2009 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.uml.diagram; import java.util.Map; import org.argouml.model.Model; import org.argouml.uml.CommentEdge; import org.argouml.uml.diagram.ui.FigCompartment; import org.argouml.uml.diagram.ui.FigCompartmentBox; import org.argouml.uml.diagram.ui.FigEdgeModelElement; import org.tigris.gef.base.Layer; import org.tigris.gef.graph.GraphEdgeRenderer; import org.tigris.gef.graph.GraphNodeRenderer; import org.tigris.gef.presentation.Fig; import org.tigris.gef.presentation.FigEdge; import org.tigris.gef.presentation.FigNode; /** * Factory methods to create Figs based an model elements with supplementary * data provided by a map of name value pairs.<p> * * Provides {@link org.tigris.gef.graph.GraphNodeRenderer#getFigNodeFor( * Object, int, int, Map)} to implement the {@link GraphNodeRenderer} * interface and {@link * org.tigris.gef.graph.GraphEdgeRenderer#getFigEdgeFor(Object, Map)} * to implement the {@link GraphEdgeRenderer} interface. */ public abstract class UmlDiagramRenderer implements GraphNodeRenderer, GraphEdgeRenderer { /** * @deprecated for 0.27.3 by tfmorris. Only used by * {@link DiagramFactory#createRenderingElement(Object, Object)} * which is itself unused (and now deprecated). */ @Deprecated public FigNode getFigNodeFor( Object node, int x, int y, Map styleAttributes) { return null; // if (node == null) { // throw new IllegalArgumentException( // "A model element must be supplied"); // } // FigNode figNode = null; // if (Model.getFacade().isAComment(node)) { // figNode = new FigComment(); // } else if (Model.getFacade().isAStubState(node)) { // return new FigStubState(); // } else if (Model.getFacade().isAAssociationClass(node)) { // figNode = new FigClassAssociationClass(node, x, y, 10, 10); // } else if (Model.getFacade().isAClass(node)) { // figNode = new FigClass(node, x, y, 10, 10); // } else if (Model.getFacade().isAInterface(node)) { // figNode = new FigInterface(); // } else if (Model.getFacade().isAEnumeration(node)) { // figNode = new FigEnumeration(); // } else if (Model.getFacade().isAStereotype(node)) { // figNode = new FigStereotypeDeclaration(); // } else if (Model.getFacade().isADataType(node)) { // figNode = new FigDataType(); // } else if (Model.getFacade().isAModel(node)) { // figNode = new FigModel(node, x, y); // } else if (Model.getFacade().isASubsystem(node)) { // figNode = new FigSubsystem(node, x, y); // } else if (Model.getFacade().isAPackage(node)) { // figNode = new FigPackage(node, x, y); // } else if (Model.getFacade().isAAssociation(node)) { // figNode = new FigNodeAssociation(); // } else if (Model.getFacade().isAActor(node)) { // figNode = new FigActor(); // } else if (Model.getFacade().isAUseCase(node)) { // figNode = new FigUseCase(); // } else if (Model.getFacade().isAPartition(node)) { // figNode = new FigPartition(); // } else if (Model.getFacade().isACallState(node)) { // figNode = new FigCallState(); // } else if (Model.getFacade().isAObjectFlowState(node)) { // figNode = new FigObjectFlowState(); // } else if (Model.getFacade().isASubactivityState(node)) { // figNode = new FigSubactivityState(); // } else if (Model.getFacade().isAClassifierRole(node)) { // figNode = new FigClassifierRole(); // } else if (Model.getFacade().isAMessage(node)) { // figNode = new FigMessage(); // } else if (Model.getFacade().isANode(node)) { // figNode = new FigMNode(); // } else if (Model.getFacade().isANodeInstance(node)) { // figNode = new FigNodeInstance(); // } else if (Model.getFacade().isAComponent(node)) { // figNode = new FigComponent(); // } else if (Model.getFacade().isAComponentInstance(node)) { // figNode = new FigComponentInstance(); // } else if (Model.getFacade().isAObject(node)) { // figNode = new FigObject(); // } else if (Model.getFacade().isAComment(node)) { // figNode = new FigComment(); // } else if (Model.getFacade().isAActionState(node)) { // figNode = new FigActionState(); // } else if (Model.getFacade().isAFinalState(node)) { // figNode = new FigFinalState(); // } else if (Model.getFacade().isASubmachineState(node)) { // figNode = new FigSubmachineState(); // } else if (Model.getFacade().isAConcurrentRegion(node)) { // figNode = new FigConcurrentRegion(); // } else if (Model.getFacade().isASynchState(node)) { // figNode = new FigSynchState(); // } else if (Model.getFacade().isACompositeState(node)) { // figNode = new FigCompositeState(); // } else if (Model.getFacade().isAState(node)) { // figNode = new FigSimpleState(); // } else if (Model.getFacade().isAPseudostate(node)) { // Object pState = node; // Object kind = Model.getFacade().getKind(pState); // if (Model.getPseudostateKind().getInitial().equals(kind)) { // figNode = new FigInitialState(); // } else if (Model.getPseudostateKind().getChoice() // .equals(kind)) { // figNode = new FigBranchState(); // } else if (Model.getPseudostateKind().getJunction() // .equals(kind)) { // figNode = new FigJunctionState(); // } else if (Model.getPseudostateKind().getFork().equals(kind)) { // figNode = new FigForkState(); // } else if (Model.getPseudostateKind().getJoin().equals(kind)) { // figNode = new FigJoinState(); // } else if (Model.getPseudostateKind().getShallowHistory() // .equals(kind)) { // figNode = new FigShallowHistoryState(); // } else if (Model.getPseudostateKind().getDeepHistory() // .equals(kind)) { // figNode = new FigDeepHistoryState(); // } // } // // if (figNode == null) { // throw new IllegalArgumentException( // "Failed to construct a FigNode for " + node); // } // setStyleAttributes(figNode, styleAttributes); // // return figNode; } /** * Set the fig style according to attributes. <p> * * TODO: This is never used! Can we remove? * * @param fig the fig to style. * @param attributeMap a map of name value pairs */ private void setStyleAttributes(Fig fig, Map<String, String> attributeMap) { String name; String value; for (Map.Entry<String, String> entry : attributeMap.entrySet()) { name = entry.getKey(); value = entry.getValue(); if(fig instanceof FigCompartmentBox) { FigCompartmentBox fcb = (FigCompartmentBox) fig; if ("operationsVisible".equals(name)) { fcb.showCompartment( Model.getMetaTypes().getOperation(), value.equalsIgnoreCase("true")); } else if ("attributesVisible".equals(name)) { fcb.showCompartment( Model.getMetaTypes().getAttribute(), value.equalsIgnoreCase("true")); } else if ("enumerationLiteralsVisible".equals(name)) { fcb.showCompartment( Model.getMetaTypes().getEnumerationLiteral(), value.equalsIgnoreCase("true")); } else if ("extensionPointVisible".equals(name)) { fcb.showCompartment( Model.getMetaTypes().getExtensionPoint(), value.equalsIgnoreCase("true")); } } } } /** * @deprecated for 0.27.3 by tfmorris. Use method of same name which takes * a GraphModel argument in the subclasses of this class. * @see org.tigris.gef.graph.GraphEdgeRenderer#getFigEdgeFor(java.lang.Object, java.util.Map) */ @Deprecated public FigEdge getFigEdgeFor(Object edge, Map styleAttributes) { return null; // if (edge == null) { // throw new IllegalArgumentException("A model edge must be supplied"); // } // FigEdge newEdge = null; // if (Model.getFacade().isAAssociationClass(edge)) { // newEdge = new FigAssociationClass(); // } else if (Model.getFacade().isAAssociationEnd(edge)) { // newEdge = new FigAssociationEnd(); // } else if (Model.getFacade().isAAssociation(edge)) { // newEdge = new FigAssociation(); // } else if (Model.getFacade().isALink(edge)) { // newEdge = new FigLink(); // } else if (Model.getFacade().isAGeneralization(edge)) { // newEdge = new FigGeneralization(); // } else if (Model.getFacade().isAPackageImport(edge)) { // newEdge = new FigPermission(); // } else if (Model.getFacade().isAUsage(edge)) { // newEdge = new FigUsage(); // } else if (Model.getFacade().isADependency(edge)) { // if (Model.getExtensionMechanismsHelper().hasStereotype(edge, // CoreFactory.REALIZE_STEREOTYPE)) { // newEdge = new FigAbstraction(); // } else { // newEdge = new FigDependency(); // } // } else if (edge instanceof CommentEdge) { // newEdge = null; // } else if (Model.getFacade().isAAssociationRole(edge)) { // newEdge = new FigAssociationRole(); // } else if (Model.getFacade().isATransition(edge)) { // newEdge = new FigTransition(); // } else if (Model.getFacade().isAExtend(edge)) { // newEdge = new FigExtend(); // } else if (Model.getFacade().isAInclude(edge)) { // newEdge = new FigInclude(); // } // // if (newEdge == null) { // throw new IllegalArgumentException( // "Failed to construct a FigEdge for " + edge); // } // // return newEdge; } /** * Find the Figs in the given layer that should be the source and * destination and attach these to either end of the FigEdge * @param layer the layer to look for the FigNodes * @param newEdge The edge to attach */ protected final void setPorts(Layer layer, FigEdge newEdge) { Object modelElement = newEdge.getOwner(); if (newEdge.getSourcePortFig() == null) { Object source; if (modelElement instanceof CommentEdge) { source = ((CommentEdge) modelElement).getSource(); } else { source = Model.getUmlHelper().getSource(modelElement); } FigNode sourceNode = getNodePresentationFor(layer, source); assert (sourceNode != null) : "No FigNode found for " + source; setSourcePort(newEdge, sourceNode); } if (newEdge.getDestPortFig() == null) { Object dest; if (modelElement instanceof CommentEdge) { dest = ((CommentEdge) modelElement).getDestination(); } else { dest = Model.getUmlHelper().getDestination(newEdge.getOwner()); } setDestPort(newEdge, getNodePresentationFor(layer, dest)); } if (newEdge.getSourcePortFig() == null || newEdge.getDestPortFig() == null) { throw new IllegalStateException("Edge of type " + newEdge.getClass().getName() + " created with no source or destination port"); } } private void setSourcePort(FigEdge edge, FigNode source) { edge.setSourcePortFig(source); edge.setSourceFigNode(source); } private void setDestPort(FigEdge edge, FigNode dest) { edge.setDestPortFig(dest); edge.setDestFigNode(dest); } /** * Get the FigNode from the given layer that represents the given * model element. * The FigNode portion of an association class is returned in preference * to the FigEdge portion. * If no FigNode is found then a FIgEdge is searched for and the FigNode * that acts as its edge port is returned. * @param lay the layer containing the Fig * @param modelElement the model element to find presentation for * @return the FigNode presentation of the model element */ private FigNode getNodePresentationFor(Layer lay, Object modelElement) { assert modelElement != null : "A modelElement must be supplied"; for (Object fig : lay.getContentsNoEdges()) { if (fig instanceof FigNode && modelElement.equals(((FigNode) fig).getOwner())) { return ((FigNode) fig); } } for (Object fig : lay.getContentsEdgesOnly()) { if (fig instanceof FigEdgeModelElement && modelElement.equals(((FigEdgeModelElement) fig) .getOwner())) { return ((FigEdgeModelElement) fig).getEdgePort(); } } return null; } protected FigNode getFigNodeForAssociationEnd( final ArgoDiagram diagram, final Object associationEnd) { Object classifier = Model.getFacade().getClassifier(associationEnd); return getNodePresentationFor(diagram.getLayer(), classifier); } protected void addEdge(Layer lay, FigEdge newEdge, Object edge) { if (newEdge == null) { throw new IllegalArgumentException( "Don't know how to create FigEdge for model type " + edge.getClass().getName()); } setPorts(lay, newEdge); assert newEdge != null : "There has been no FigEdge created"; // newEdge.setDiElement( // GraphChangeAdapter.getInstance().createElement(gm, edge)); assert newEdge != null : "There has been no FigEdge created"; assert (newEdge.getDestFigNode() != null) : "The FigEdge has no dest node"; assert (newEdge.getDestPortFig() != null) : "The FigEdge has no dest port"; assert (newEdge.getSourceFigNode() != null) : "The FigEdge has no source node"; assert (newEdge.getSourcePortFig() != null) : "The FigEdge has no source port"; lay.add(newEdge); } }