|
What this is
Other links
The source code// $Id: StateDiagramGraphModel.java,v 1.46 2004/09/28 11:12:21 bobtarling Exp $ // Copyright (c) 1996-2004 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. // File: StateDiagramGraphModel.java // Classes: StateDiagramGraphModel // Original Author: your email address here package org.argouml.uml.diagram.state; import java.beans.PropertyChangeEvent; import java.beans.VetoableChangeListener; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.apache.log4j.Logger; import org.argouml.kernel.ProjectManager; import org.argouml.model.ModelFacade; import org.argouml.model.uml.UmlFactory; import org.argouml.model.uml.behavioralelements.statemachines.StateMachinesFactory; import org.argouml.model.uml.behavioralelements.statemachines.StateMachinesHelper; import org.argouml.uml.diagram.UMLMutableGraphSupport; import org.argouml.uml.diagram.static_structure.ui.CommentEdge; /** * This class defines a bridge between the UML meta-model representation of the * design and the GraphModel interface used by GEF. This class handles only UML * MState Digrams. */ public class StateDiagramGraphModel extends UMLMutableGraphSupport implements VetoableChangeListener { private static final Logger LOG = Logger.getLogger(StateDiagramGraphModel.class); /** * The "home" UML model of this diagram, not all ModelElements in * this graph are in the home model, but if they are added and * don't already have a model, they are placed in the "home * model". Also, elements from other models will have their * FigNodes add a line to say what their model is. */ private Object namespace; /** The statemachine we are diagramming */ private Object machine; //////////////////////////////////////////////////////////////// // accessors /** * @see org.argouml.uml.diagram.UMLMutableGraphSupport#getNamespace() */ public Object getNamespace() { return namespace; } /** * @param ns the namespace */ public void setNamespace(Object ns) { if (!ModelFacade.isANamespace(ns)) throw new IllegalArgumentException(); namespace = ns; } /** * @return the statemachine of this diagram */ public Object getMachine() { return machine; } /** * @param sm the statemachine of this diagram */ public void setMachine(Object sm) { if (!ModelFacade.isAStateMachine(sm)) throw new IllegalArgumentException(); if (sm != null) { machine = sm; } } //////////////////////////////////////////////////////////////// // GraphModel implementation /** * Return all ports on node or edge. * * @return The ports. * @param nodeOrEdge The node or the edge. */ public List getPorts(Object nodeOrEdge) { Vector res = new Vector(); //wasteful! if (ModelFacade.isAState(nodeOrEdge)) { res.addElement(nodeOrEdge); } if (ModelFacade.isAPseudostate(nodeOrEdge)) { res.addElement(nodeOrEdge); } return res; } /** * Return the node or edge that owns the given port. * * @param port the port * @return The owner of the port. * @see org.tigris.gef.graph.BaseGraphModel#getOwner(java.lang.Object) */ public Object getOwner(Object port) { return port; } /** Return all edges going to given port * * @see org.tigris.gef.graph.GraphModel#getInEdges(java.lang.Object) */ public List getInEdges(Object port) { if (ModelFacade.isAStateVertex(port)) { return new Vector(ModelFacade.getIncomings(port)); } LOG.debug("TODO: getInEdges of MState"); return new Vector(); //wasteful! } /** Return all edges going from given port * * @see org.tigris.gef.graph.GraphModel#getOutEdges(java.lang.Object) */ public List getOutEdges(Object port) { if (ModelFacade.isAStateVertex(port)) { return new Vector(ModelFacade.getOutgoings(port)); } LOG.debug("TODO: getOutEdges of MState"); return new Vector(); //wasteful! } /** Return one end of an edge * * @see org.tigris.gef.graph.BaseGraphModel#getSourcePort(java.lang.Object) */ public Object getSourcePort(Object edge) { if (ModelFacade.isATransition(edge)) { return StateMachinesHelper.getHelper() .getSource(/* (MTransition) */edge); } LOG.debug("TODO: getSourcePort of MTransition"); return null; } /** Return the other end of an edge * * @see org.tigris.gef.graph.BaseGraphModel#getDestPort(java.lang.Object) */ public Object getDestPort(Object edge) { if (ModelFacade.isATransition(edge)) { return StateMachinesHelper.getHelper() .getDestination(/* (MTransition) */edge); } LOG.debug("TODO: getDestPort of MTransition"); return null; } //////////////////////////////////////////////////////////////// // MutableGraphModel implementation /** Return true if the given object is a valid node in this graph * * @see org.tigris.gef.graph.MutableGraphModel#canAddNode(java.lang.Object) */ public boolean canAddNode(Object node) { if (node == null) return false; if (containsNode(node)) return false; return (ModelFacade.isAStateVertex(node) || ModelFacade.isAPartition(node) || ModelFacade.isAComment(node)); } /** Return true if the given object is a valid edge in this graph * * @see org.tigris.gef.graph.MutableGraphModel#canAddEdge(java.lang.Object) */ public boolean canAddEdge(Object edge) { if (super.canAddEdge(edge)) { return true; } if (edge == null) return false; if (containsEdge(edge)) return false; Object end0 = null, end1 = null, state = null; if (ModelFacade.isATransition(edge)) { state = ModelFacade.getState(edge); end0 = ModelFacade.getSource(edge); end1 = ModelFacade.getTarget(edge); // it's not allowed to directly draw a transition // from a composite state to one of it's substates. if (ModelFacade.isACompositeState(end0) && StateMachinesHelper.getHelper().getAllSubStates(end0) .contains(end1)) { return false; } } if (end0 == null || end1 == null) return false; // if all states are equal it is an internal transition if ((state == end0) && (state == end1)) return false; if (!containsNode(end0)) return false; if (!containsNode(end1)) return false; return true; } /** Add the given node to the graph, if valid. * * @see org.tigris.gef.graph.MutableGraphModel#addNode(java.lang.Object) */ public void addNode(Object node) { LOG.debug("adding statechart diagram node: " + node); if (!canAddNode(node)) return; if (!(ModelFacade.isAStateVertex(node))) { LOG.error("internal error: got past canAddNode"); return; } Object sv = /* (MStateVertex) */node; if (containsNode(sv)) return; getNodes().add(sv); // TODO: assumes public, user pref for default visibility? //if (sv.getNamespace() == null) //_namespace.addOwnedElement(sv); // TODO: assumes not nested in another composite state Object top = /* (MCompositeState) */StateMachinesHelper.getHelper() .getTop(getMachine()); ModelFacade.addSubvertex(top, sv); // sv.setParent(top); this is done in setEnclosingFig!! // if ((sv instanceof MState) && // (sv.getNamespace()==null)) // ((MState)sv).setStateMachine(_machine); fireNodeAdded(node); } /** Add the given edge to the graph, if valid. * @see org.tigris.gef.graph.MutableGraphModel#addEdge(java.lang.Object) */ public void addEdge(Object edge) { LOG.debug("adding statechart diagram edge!!!!!!"); if (!canAddEdge(edge)) return; Object transition = /* (MTransition) */edge; getEdges().add(transition); fireEdgeAdded(edge); } /** * @see org.tigris.gef.graph.MutableGraphModel#addNodeRelatedEdges(java.lang.Object) */ public void addNodeRelatedEdges(Object node) { if (ModelFacade.isAStateVertex(node)) { Vector transen = new Vector(ModelFacade.getOutgoings(node)); transen.addAll(ModelFacade.getIncomings(node)); Iterator iter = transen.iterator(); while (iter.hasNext()) { Object dep = /* (MTransition) */iter.next(); if (canAddEdge(dep)) addEdge(dep); } } } /** * Return true if the two given ports can be connected by a kind of edge to * be determined by the ports. * * @see org.tigris.gef.graph.MutableGraphModel#canConnect(java.lang.Object, * java.lang.Object) */ public boolean canConnect(Object fromPort, Object toPort) { if (!(ModelFacade.isAStateVertex(fromPort))) { LOG.error("internal error not from sv"); return false; } if (!(ModelFacade.isAStateVertex(toPort))) { LOG.error("internal error not to sv"); return false; } if (ModelFacade.isAFinalState(fromPort)) { return false; } if (ModelFacade.isAPseudostate(toPort)) { if ((ModelFacade.INITIAL_PSEUDOSTATEKIND).equals(ModelFacade .getKind(toPort))) { return false; } } return true; } /** Contruct and add a new edge of the given kind * * @see org.tigris.gef.graph.MutableGraphModel#connect(java.lang.Object, * java.lang.Object, java.lang.Class) */ public Object connect(Object fromPort, Object toPort, Class edgeClass) { if (ModelFacade.isAFinalState(fromPort)) { return null; } if (ModelFacade.isAPseudostate(toPort)) { if ((ModelFacade.INITIAL_PSEUDOSTATEKIND).equals( ModelFacade.getKind(toPort))) { return null; } } if (edgeClass == (Class) ModelFacade.TRANSITION) { Object tr = null; Object comp = ModelFacade.getContainer(fromPort); tr = StateMachinesFactory.getFactory() .buildTransition(fromPort, toPort); if (canAddEdge(tr)) { addEdge(tr); } else { ProjectManager.getManager().getCurrentProject().moveToTrash(tr); tr = null; } return tr; } else if (edgeClass == CommentEdge.class) { try { Object connection = UmlFactory.getFactory() .buildConnection(edgeClass, fromPort, null, toPort, null, null); addEdge(connection); return connection; } catch (Exception ex) { // fail silently } return null; } else { LOG.debug("wrong kind of edge in StateDiagram connect3 " + edgeClass); return null; } } //////////////////////////////////////////////////////////////// // VetoableChangeListener implementation /** * @see java.beans.VetoableChangeListener#vetoableChange(java.beans.PropertyChangeEvent) */ public void vetoableChange(PropertyChangeEvent pce) { //throws PropertyVetoException if ("ownedElement".equals(pce.getPropertyName())) { Vector oldOwned = (Vector) pce.getOldValue(); Object eo = /* (MElementImport) */pce.getNewValue(); Object me = ModelFacade.getModelElement(eo); if (oldOwned.contains(eo)) { LOG.debug("model removed " + me); if (ModelFacade.isAState(me)) removeNode(me); if (ModelFacade.isAPseudostate(me)) removeNode(me); if (ModelFacade.isATransition(me)) removeEdge(me); } else { LOG.debug("model added " + me); } } } static final long serialVersionUID = -8056507319026044174L; /** * @param newNode * this is the new node that one of the ends is dragged to. * @param oldNode * this is the existing node that is already connected. * @param edge * this is the edge that is being dragged/rerouted * @return true if a transition is being rerouted between two states. */ public boolean canChangeConnectedNode(Object newNode, Object oldNode, Object edge) { // prevent no changes... if (newNode == oldNode) return false; // check parameter types: if (!(ModelFacade.isAState(newNode) || ModelFacade.isAState(oldNode) || ModelFacade.isATransition(edge))) { return false; } return true; } /** * Reroutes the connection to the old node to be connected to the new node. * * @param newNode * this is the new node that one of the ends is dragged to. * @param oldNode * this is the existing node that is already connected. * @param edge * this is the edge that is being dragged/rerouted * @param isSource * tells us which end is being rerouted. */ public void changeConnectedNode(Object newNode, Object oldNode, Object edge, boolean isSource) { if (isSource) ModelFacade.setSource(edge, newNode); else ModelFacade.setTarget(edge, newNode); } } /* end class StateDiagramGraphModel */ |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.