// $Id: UmlDiagramRenderer.java 16640 2009-01-17 22:06:52Z tfmorris $ // Copyright (c) 1996-2008 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.CoreFactory; import org.argouml.model.Model; import org.argouml.uml.CommentEdge; import org.argouml.uml.diagram.activity.ui.FigActionState; import org.argouml.uml.diagram.activity.ui.FigCallState; import org.argouml.uml.diagram.activity.ui.FigObjectFlowState; import org.argouml.uml.diagram.activity.ui.FigPartition; import org.argouml.uml.diagram.activity.ui.FigSubactivityState; import org.argouml.uml.diagram.collaboration.ui.FigAssociationRole; import org.argouml.uml.diagram.collaboration.ui.FigClassifierRole; import org.argouml.uml.diagram.deployment.ui.FigComponent; import org.argouml.uml.diagram.deployment.ui.FigComponentInstance; import org.argouml.uml.diagram.deployment.ui.FigMNode; import org.argouml.uml.diagram.deployment.ui.FigNodeInstance; import org.argouml.uml.diagram.deployment.ui.FigObject; import org.argouml.uml.diagram.state.ui.FigBranchState; import org.argouml.uml.diagram.state.ui.FigCompositeState; import org.argouml.uml.diagram.state.ui.FigConcurrentRegion; import org.argouml.uml.diagram.state.ui.FigDeepHistoryState; import org.argouml.uml.diagram.state.ui.FigFinalState; import org.argouml.uml.diagram.state.ui.FigForkState; import org.argouml.uml.diagram.state.ui.FigInitialState; import org.argouml.uml.diagram.state.ui.FigJoinState; import org.argouml.uml.diagram.state.ui.FigJunctionState; import org.argouml.uml.diagram.state.ui.FigShallowHistoryState; import org.argouml.uml.diagram.state.ui.FigSimpleState; import org.argouml.uml.diagram.state.ui.FigStubState; import org.argouml.uml.diagram.state.ui.FigSubmachineState; import org.argouml.uml.diagram.state.ui.FigSynchState; import org.argouml.uml.diagram.state.ui.FigTransition; import org.argouml.uml.diagram.static_structure.ui.FigClass; import org.argouml.uml.diagram.static_structure.ui.FigComment; import org.argouml.uml.diagram.static_structure.ui.FigDataType; import org.argouml.uml.diagram.static_structure.ui.FigEdgeNote; import org.argouml.uml.diagram.static_structure.ui.FigEnumeration; import org.argouml.uml.diagram.static_structure.ui.FigInterface; import org.argouml.uml.diagram.static_structure.ui.FigLink; import org.argouml.uml.diagram.static_structure.ui.FigModel; import org.argouml.uml.diagram.static_structure.ui.FigPackage; import org.argouml.uml.diagram.static_structure.ui.FigStereotypeDeclaration; import org.argouml.uml.diagram.static_structure.ui.FigSubsystem; import org.argouml.uml.diagram.ui.FigAbstraction; import org.argouml.uml.diagram.ui.FigAssociation; import org.argouml.uml.diagram.ui.FigAssociationClass; import org.argouml.uml.diagram.ui.FigAssociationEnd; import org.argouml.uml.diagram.ui.FigClassAssociationClass; import org.argouml.uml.diagram.ui.FigDependency; import org.argouml.uml.diagram.ui.FigEdgeModelElement; import org.argouml.uml.diagram.ui.FigGeneralization; import org.argouml.uml.diagram.ui.FigMessage; import org.argouml.uml.diagram.ui.FigNodeAssociation; import org.argouml.uml.diagram.ui.FigPermission; import org.argouml.uml.diagram.ui.FigUsage; import org.argouml.uml.diagram.use_case.ui.FigActor; import org.argouml.uml.diagram.use_case.ui.FigExtend; import org.argouml.uml.diagram.use_case.ui.FigInclude; import org.argouml.uml.diagram.use_case.ui.FigUseCase; 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) { if (node == null) { throw new IllegalArgumentException( "A model element must be supplied"); } FigNode figNode = null; if (Model.getFacade().isAComment(node)) { figNode = new FigComment(); } if (Model.getFacade().isAStubState(node)) { return new FigStubState(); } 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(); } if (Model.getFacade().isAPartition(node)) { figNode = new FigPartition(); } if (Model.getFacade().isACallState(node)) { figNode = new FigCallState(); } if (Model.getFacade().isAObjectFlowState(node)) { figNode = new FigObjectFlowState(); } if (Model.getFacade().isASubactivityState(node)) { figNode = new FigSubactivityState(); } 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(); } if (Model.getFacade().isAActionState(node)) { figNode = new FigActionState(); } 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. * * @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 ("operationsVisible".equals(name)) { ((OperationsCompartmentContainer) fig) .setOperationsVisible(value.equalsIgnoreCase("true")); } else if ("attributesVisible".equals(name)) { ((AttributesCompartmentContainer) fig) .setAttributesVisible(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) { 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(); } if (Model.getFacade().isATransition(edge)) { newEdge = new FigTransition(); } if (Model.getFacade().isAExtend(edge)) { newEdge = new FigExtend(); } 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 && ((FigNode) fig).getOwner().equals(modelElement)) { return ((FigNode) fig); } } for (Object fig : lay.getContentsEdgesOnly()) { if (fig instanceof FigEdgeModelElement && modelElement.equals(((FigEdgeModelElement) fig) .getOwner())) { return ((FigEdgeModelElement) fig).getEdgePort(); } } return null; } }