/* $Id: UMLActivityDiagram.java 17853 2010-01-12 19:55:46Z linus $
*****************************************************************************
* 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-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.activity.ui;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import javax.swing.Action;
import org.apache.log4j.Logger;
import org.argouml.i18n.Translator;
import org.argouml.model.ActivityGraphsHelper;
import org.argouml.model.DeleteInstanceEvent;
import org.argouml.model.Model;
import org.argouml.ui.CmdCreateNode;
import org.argouml.uml.diagram.DiagramElement;
import org.argouml.uml.diagram.DiagramSettings;
import org.argouml.uml.diagram.UMLMutableGraphSupport;
import org.argouml.uml.diagram.activity.ActivityDiagramGraphModel;
import org.argouml.uml.diagram.state.StateDiagramGraphModel;
import org.argouml.uml.diagram.state.ui.ActionCreatePseudostate;
import org.argouml.uml.diagram.state.ui.ButtonActionNewCallEvent;
import org.argouml.uml.diagram.state.ui.ButtonActionNewChangeEvent;
import org.argouml.uml.diagram.state.ui.ButtonActionNewSignalEvent;
import org.argouml.uml.diagram.state.ui.ButtonActionNewTimeEvent;
import org.argouml.uml.diagram.state.ui.FigBranchState;
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.FigStateVertex;
import org.argouml.uml.diagram.static_structure.ui.FigComment;
import org.argouml.uml.diagram.ui.ActionSetMode;
import org.argouml.uml.diagram.ui.FigNodeModelElement;
import org.argouml.uml.diagram.ui.RadioAction;
import org.argouml.uml.diagram.ui.UMLDiagram;
import org.argouml.uml.ui.behavior.common_behavior.ActionNewActionSequence;
import org.argouml.uml.ui.behavior.common_behavior.ActionNewCallAction;
import org.argouml.uml.ui.behavior.common_behavior.ActionNewCreateAction;
import org.argouml.uml.ui.behavior.common_behavior.ActionNewDestroyAction;
import org.argouml.uml.ui.behavior.common_behavior.ActionNewReturnAction;
import org.argouml.uml.ui.behavior.common_behavior.ActionNewSendAction;
import org.argouml.uml.ui.behavior.common_behavior.ActionNewTerminateAction;
import org.argouml.uml.ui.behavior.common_behavior.ActionNewUninterpretedAction;
import org.argouml.uml.ui.behavior.state_machines.ButtonActionNewGuard;
import org.argouml.util.ToolBarUtility;
import org.tigris.gef.base.LayerPerspective;
import org.tigris.gef.base.LayerPerspectiveMutable;
import org.tigris.gef.base.ModeCreatePolyEdge;
import org.tigris.gef.graph.GraphModel;
import org.tigris.gef.presentation.Fig;
import org.tigris.gef.presentation.FigNode;
/**
* The Activity diagram.<p>
*
* TODO: Finish the work on subactivity states.
*/
public class UMLActivityDiagram extends UMLDiagram {
/**
* Logger.
*/
private static final Logger LOG =
Logger.getLogger(UMLActivityDiagram.class);
/**
* The UID.
*/
private static final long serialVersionUID = 6223128918989919230L;
/**
* this diagram needs to be deleted when its statemachine is deleted.
*/
private Object theActivityGraph;
private Action actionState;
private Action actionStartPseudoState;
private Action actionFinalPseudoState;
private Action actionJunctionPseudoState;
private Action actionForkPseudoState;
private Action actionJoinPseudoState;
private Action actionTransition;
private Action actionObjectFlowState;
private Action actionSwimlane;
private Action actionCallState;
private Action actionSubactivityState;
private Action actionCallEvent;
private Action actionChangeEvent;
private Action actionSignalEvent;
private Action actionTimeEvent;
private Action actionGuard;
private Action actionCallAction;
private Action actionCreateAction;
private Action actionDestroyAction;
private Action actionReturnAction;
private Action actionSendAction;
private Action actionTerminateAction;
private Action actionUninterpretedAction;
private Action actionActionSequence;
/**
* Constructor.
*
* @deprecated for 0.28 by tfmorris. Use
* {@link #UMLActivityDiagram(String, Object, GraphModel)}.
*/
@Deprecated
public UMLActivityDiagram() {
super();
try {
setName(getNewDiagramName());
} catch (PropertyVetoException pve) {
// no action required in case of veto on setName
}
// TODO: All super constructors should take a GraphModel
setGraphModel(createGraphModel());
}
/**
* Constructor.
*
* @param namespace the namespace for the diagram
* @param agraph the ActivityGraph for the diagram
* @deprecated for 0.28 by tfmorris. Use
* {@link #UMLActivityDiagram(String, Object, GraphModel)}.
*/
@Deprecated
public UMLActivityDiagram(Object namespace, Object agraph) {
this();
if (namespace == null) {
namespace = Model.getFacade().getNamespace(agraph);
}
if (!Model.getFacade().isANamespace(namespace)
|| !Model.getFacade().isAActivityGraph(agraph)) {
throw new IllegalArgumentException();
}
if (Model.getFacade().getName(namespace) != null) {
if (!Model.getFacade().getName(namespace).trim().equals("")) {
String name =
Model.getFacade().getName(namespace)
+ " activity "
+ (Model.getFacade().getBehaviors(namespace).size());
try {
setName(name);
} catch (PropertyVetoException pve) {
// no action required
}
}
}
setup(namespace, agraph);
}
/*
* @see org.tigris.gef.base.Diagram#initialize(java.lang.Object)
*/
public void initialize(Object o) {
if (!(Model.getFacade().isAActivityGraph(o))) {
return;
}
Object context = Model.getFacade().getContext(o);
if (context != null) {
if (Model.getFacade().isABehavioralFeature(context)) {
setup(Model.getFacade().getNamespace(
Model.getFacade().getOwner(context)), o);
} else {
setup(context, o);
}
} else {
Object namespace4Diagram = Model.getFacade().getNamespace(o);
if (namespace4Diagram != null) {
setup(namespace4Diagram, o);
} else {
throw new IllegalStateException("Cannot find context "
+ "nor namespace while initializing activity diagram");
}
}
}
/**
* Method to perform a number of important initializations of an
* <em>Activity Diagram</em>.<p>
*
* Each diagram type has a similar <em>UMLxxxDiagram</em> class.<p>
*
* Changed <em>lay</em> from <em>LayerPerspective</em> to
* <em>LayerPerspectiveMutable</em>. This class is a child of
* <em>LayerPerspective</em> and was implemented to correct some
* difficulties in changing the model. <em>lay</em> is used mainly
* in <em>LayerManager</em>(GEF) to control the adding, changing and
* deleting layers on the diagram... psager@tigris.org Jan. 24,
* 2002
* @param namespace Namespace from the model
* @param agraph ActivityGraph from the model
*/
public void setup(Object namespace, Object agraph) {
if (!Model.getFacade().isANamespace(namespace)
|| !Model.getFacade().isAActivityGraph(agraph)) {
throw new IllegalArgumentException();
}
setNamespace(namespace);
theActivityGraph = agraph;
ActivityDiagramGraphModel gm = createGraphModel();
gm.setHomeModel(namespace);
if (theActivityGraph != null) {
gm.setMachine(theActivityGraph);
}
ActivityDiagramRenderer rend = new ActivityDiagramRenderer();
LayerPerspective lay = new LayerPerspectiveMutable(
Model.getFacade().getName(namespace), gm);
lay.setGraphNodeRenderer(rend);
lay.setGraphEdgeRenderer(rend);
setLayer(lay);
/* Listen to activitygraph deletion,
* delete this diagram. */
Model.getPump().addModelEventListener(this, theActivityGraph,
new String[] {"remove", "namespace"});
}
// TODO: Needs to be tidied up after stable release. Graph model
// should be created in constructor
private ActivityDiagramGraphModel createGraphModel() {
if ((getGraphModel() instanceof ActivityDiagramGraphModel)) {
return (ActivityDiagramGraphModel) getGraphModel();
} else {
return new ActivityDiagramGraphModel();
}
}
/*
* @see org.argouml.uml.diagram.ui.UMLDiagram#propertyChange(java.beans.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent evt) {
if ((evt.getSource() == theActivityGraph)
&& (evt instanceof DeleteInstanceEvent)
&& "remove".equals(evt.getPropertyName())) {
Model.getPump().removeModelEventListener(this,
theActivityGraph, new String[] {"remove", "namespace"});
getProject().moveToTrash(this);
}
if (evt.getSource() == getStateMachine()) {
Object newNamespace =
Model.getFacade().getNamespace(getStateMachine());
if (getNamespace() != newNamespace) {
/* The namespace of the activitygraph is changed! */
setNamespace(newNamespace);
((UMLMutableGraphSupport) getGraphModel())
.setHomeModel(newNamespace);
}
}
}
/*
* @see org.argouml.uml.diagram.ui.UMLDiagram#getOwner()
*/
public Object getOwner() {
if (!(getGraphModel() instanceof ActivityDiagramGraphModel)) {
throw new IllegalStateException(
"Incorrect graph model of "
+ getGraphModel().getClass().getName());
}
ActivityDiagramGraphModel gm =
(ActivityDiagramGraphModel) getGraphModel();
return gm.getMachine();
}
/**
* @return the statemachine
*
* TODO: If this method is called by any of the Figs, it will introduce
* a dependency cycle. It would be much better if they could just
* use {@link org.argouml.uml.diagram.ArgoDiagram#getOwner()} which does
* the same thing.
*/
public Object getStateMachine() {
GraphModel gm = getGraphModel();
if (gm instanceof StateDiagramGraphModel) {
Object machine = ((StateDiagramGraphModel) gm).getMachine();
if (!Model.getUmlFactory().isRemoved(machine)) {
return machine;
}
}
return null;
}
/**
* @param sm set the statemachine for this diagram
*/
public void setStateMachine(Object sm) {
if (!Model.getFacade().isAStateMachine(sm)) {
throw new IllegalArgumentException();
}
((ActivityDiagramGraphModel) getGraphModel()).setMachine(sm);
}
/**
* Get the actions from which to create a toolbar or equivalent
* graphic triggers.
*
* @see org.argouml.uml.diagram.ui.UMLDiagram#getUmlActions()
* @return the array of actions
*/
protected Object[] getUmlActions() {
Object[] actions =
{
getActionState(),
getActionTransition(),
null,
getActionStartPseudoState(),
getActionFinalPseudoState(),
getActionJunctionPseudoState(),
getActionForkPseudoState(),
getActionJoinPseudoState(),
getActionSwimlane(),
null,
getActionCallState(),
getActionObjectFlowState(),
/*getActionSubactivityState()*/
null,
getTriggerActions(),
getActionGuard(),
getEffectActions(),
};
return actions;
}
protected Object[] getTriggerActions() {
Object[] actions = {
getActionCallEvent(),
getActionChangeEvent(),
getActionSignalEvent(),
getActionTimeEvent(),
};
ToolBarUtility.manageDefault(actions, "diagram.activity.trigger");
return actions;
}
protected Object[] getEffectActions() {
Object[] actions = {
getActionCallAction(),
getActionCreateAction(),
getActionDestroyAction(),
getActionReturnAction(),
getActionSendAction(),
getActionTerminateAction(),
getActionUninterpretedAction(),
getActionActionSequence(),
};
ToolBarUtility.manageDefault(actions, "diagram.activity.effect");
return actions;
}
/*
* @see org.argouml.uml.diagram.ui.UMLDiagram#getLabelName()
*/
public String getLabelName() {
return Translator.localize("label.activity-diagram");
}
/**
* @return Returns the actionCallState.
*/
protected Action getActionCallState() {
if (actionCallState == null) {
actionCallState =
new RadioAction(
new CmdCreateNode(
Model.getMetaTypes().getCallState(),
"button.new-callstate"));
}
return actionCallState;
}
/**
* @return Returns the actionFinalPseudoState.
*/
protected Action getActionFinalPseudoState() {
if (actionFinalPseudoState == null) {
actionFinalPseudoState =
new RadioAction(
new CmdCreateNode(
Model.getMetaTypes().getFinalState(),
"button.new-finalstate"));
}
return actionFinalPseudoState;
}
/**
* @return Returns the actionForkPseudoState.
*/
protected Action getActionForkPseudoState() {
if (actionForkPseudoState == null) {
actionForkPseudoState =
new RadioAction(
new ActionCreatePseudostate(
Model.getPseudostateKind().getFork(),
"button.new-fork"));
}
return actionForkPseudoState;
}
/**
* @return Returns the actionJoinPseudoState.
*/
protected Action getActionJoinPseudoState() {
if (actionJoinPseudoState == null) {
actionJoinPseudoState =
new RadioAction(
new ActionCreatePseudostate(
Model.getPseudostateKind().getJoin(),
"button.new-join"));
}
return actionJoinPseudoState;
}
/**
* @return Returns the actionJunctionPseudoState.
*/
protected Action getActionJunctionPseudoState() {
if (actionJunctionPseudoState == null) {
actionJunctionPseudoState =
new RadioAction(
new ActionCreatePseudostate(
Model.getPseudostateKind().getJunction(),
"button.new-junction"));
}
return actionJunctionPseudoState;
}
/**
* @return Returns the actionSwimlane.
*/
protected Action getActionSwimlane() {
if (actionSwimlane == null) {
actionSwimlane =
new ActionCreatePartition(getStateMachine());
}
return actionSwimlane;
}
/**
* @return Returns the actionObjectFlowState.
*/
protected Action getActionObjectFlowState() {
if (actionObjectFlowState == null) {
actionObjectFlowState =
new RadioAction(
new CmdCreateNode(
Model.getMetaTypes().getObjectFlowState(),
"button.new-objectflowstate"));
}
return actionObjectFlowState;
}
/**
* @return Returns the actionStartPseudoState.
*/
protected Action getActionStartPseudoState() {
if (actionStartPseudoState == null) {
actionStartPseudoState =
new RadioAction(
new ActionCreatePseudostate(
Model.getPseudostateKind().getInitial(),
"button.new-initial"));
}
return actionStartPseudoState;
}
/**
* @return Returns the actionState.
*/
protected Action getActionState() {
if (actionState == null) {
actionState =
new RadioAction(
new CmdCreateNode(
Model.getMetaTypes().getActionState(),
"button.new-actionstate"));
}
return actionState;
}
/**
* @return Returns the actionSubactivityState.
*/
protected Action getActionSubactivityState() {
if (actionSubactivityState == null) {
actionSubactivityState =
new RadioAction(
new CmdCreateNode(
Model.getMetaTypes().getSubactivityState(),
"button.new-subactivitystate"));
}
return actionSubactivityState;
}
/**
* @return Returns the actionTransition.
*/
protected Action getActionTransition() {
if (actionTransition == null) {
actionTransition =
new RadioAction(
new ActionSetMode(
ModeCreatePolyEdge.class,
"edgeClass",
Model.getMetaTypes().getTransition(),
"button.new-transition"));
}
return actionTransition;
}
/**
* @return Returns the actionCallEvent.
*/
protected Action getActionCallEvent() {
if (actionCallEvent == null) {
actionCallEvent = new ButtonActionNewCallEvent();
}
return actionCallEvent;
}
/**
* @return Returns the actionCallEvent.
*/
protected Action getActionChangeEvent() {
if (actionChangeEvent == null) {
actionChangeEvent = new ButtonActionNewChangeEvent();
}
return actionChangeEvent;
}
/**
* @return Returns the actionCallEvent.
*/
protected Action getActionSignalEvent() {
if (actionSignalEvent == null) {
actionSignalEvent = new ButtonActionNewSignalEvent();
}
return actionSignalEvent;
}
/**
* @return Returns the actionCallEvent.
*/
protected Action getActionTimeEvent() {
if (actionTimeEvent == null) {
actionTimeEvent = new ButtonActionNewTimeEvent();
}
return actionTimeEvent;
}
protected Action getActionGuard() {
if (actionGuard == null) {
actionGuard = new ButtonActionNewGuard();
}
return actionGuard;
}
protected Action getActionCallAction() {
if (actionCallAction == null) {
actionCallAction = ActionNewCallAction.getButtonInstance();
}
return actionCallAction;
}
protected Action getActionCreateAction() {
if (actionCreateAction == null) {
actionCreateAction = ActionNewCreateAction.getButtonInstance();
}
return actionCreateAction;
}
protected Action getActionDestroyAction() {
if (actionDestroyAction == null) {
actionDestroyAction = ActionNewDestroyAction.getButtonInstance();
}
return actionDestroyAction;
}
protected Action getActionReturnAction() {
if (actionReturnAction == null) {
actionReturnAction = ActionNewReturnAction.getButtonInstance();
}
return actionReturnAction;
}
protected Action getActionSendAction() {
if (actionSendAction == null) {
actionSendAction = ActionNewSendAction.getButtonInstance();
}
return actionSendAction;
}
protected Action getActionTerminateAction() {
if (actionTerminateAction == null) {
actionTerminateAction =
ActionNewTerminateAction.getButtonInstance();
}
return actionTerminateAction;
}
protected Action getActionUninterpretedAction() {
if (actionUninterpretedAction == null) {
actionUninterpretedAction =
ActionNewUninterpretedAction.getButtonInstance();
}
return actionUninterpretedAction;
}
protected Action getActionActionSequence() {
if (actionActionSequence == null) {
actionActionSequence =
ActionNewActionSequence.getButtonInstance();
}
return actionActionSequence;
}
/*
* @see org.argouml.uml.diagram.ui.UMLDiagram#getDependentElement()
*/
public Object getDependentElement() {
return getStateMachine(); /* The ActivityGraph. */
}
/*
* @see org.argouml.uml.diagram.ui.UMLDiagram#isRelocationAllowed(java.lang.Object)
*/
public boolean isRelocationAllowed(Object base) {
return false;
/* TODO: We may return the following when the
* relocate() has been implemented.
*/
// Model.getActivityGraphsHelper()
// .isAddingActivityGraphAllowed(base);
}
@SuppressWarnings("unchecked")
public Collection getRelocationCandidates(Object root) {
/* TODO: We may return something useful when the
* relocate() has been implemented. */
Collection c = new HashSet();
c.add(getOwner());
return c;
}
/*
* @see org.argouml.uml.diagram.ui.UMLDiagram#relocate(java.lang.Object)
*/
public boolean relocate(Object base) {
return false;
}
/**
* Once the diagram has loaded we build the previous/next links between
* any swimlanes.
*/
@Override
public void postLoad() {
FigPartition previous = null;
// Create a map of partitions keyed by x coordinate
HashMap map = new HashMap();
Iterator it = new ArrayList(getLayer().getContents()).iterator();
while (it.hasNext()) {
Fig f = (Fig) it.next();
if (f instanceof FigPartition) {
map.put(Integer.valueOf(f.getX()), f);
}
}
// Sort the x coordinates into order
List xList = new ArrayList(map.keySet());
Collections.sort(xList);
// Link the previous/next reference of the swimlanes
// according to the x order.
it = xList.iterator();
while (it.hasNext()) {
Fig f = (Fig) map.get(it.next());
if (f instanceof FigPartition) {
FigPartition fp = (FigPartition) f;
if (previous != null) {
previous.setNextPartition(fp);
}
fp.setPreviousPartition(previous);
fp.setNextPartition(null);
previous = fp;
}
}
}
/**
* Extends basic functionality to handle logic for enclosement of states
* within a swimlane.
* @param enclosed The FigNode enclosed.
* @param oldEncloser The previous encloser (null if none)
* @param newEncloser The encloser (null if none)
*/
public void encloserChanged(
FigNode enclosed, FigNode oldEncloser, FigNode newEncloser) {
if (oldEncloser == null && newEncloser == null) {
return;
}
if (enclosed instanceof FigStateVertex
|| enclosed instanceof FigObjectFlowState) {
changePartition(enclosed);
}
}
/**
* Extends basic functionality to handle logic for enclosement of states
* within a swimlane.
* @param enclosed The FigNode enclosed.
*/
private void changePartition(FigNode enclosed) {
assert enclosed != null;
Object state = enclosed.getOwner();
ActivityGraphsHelper activityGraph = Model.getActivityGraphsHelper();
for (Object f : getLayer().getContentsNoEdges()) {
if (f instanceof FigPartition) {
FigPartition fig = (FigPartition) f;
Object partition = fig.getOwner();
if (fig.getBounds().intersects(enclosed.getBounds())) {
activityGraph.addContent(partition, state);
} else if (isStateInPartition(state, partition)) {
activityGraph.removeContent(partition, state);
}
}
}
}
private boolean isStateInPartition(Object state, Object partition) {
return Model.getFacade().getContents(partition).contains(state);
}
@Override
public boolean doesAccept(Object objectToAccept) {
if (Model.getFacade().isAPartition(objectToAccept)) {
return true;
} else if (Model.getFacade().isAState(objectToAccept)) {
return true;
} else if (Model.getFacade().isAPseudostate(objectToAccept)) {
Object kind = Model.getFacade().getKind(objectToAccept);
if (kind == null) {
LOG.warn("found a null type pseudostate");
return false;
}
if (kind.equals(
Model.getPseudostateKind().getShallowHistory())) {
return false;
} else if (kind.equals(
Model.getPseudostateKind().getDeepHistory())) {
return false;
}
return true;
} else if (Model.getFacade().isAComment(objectToAccept)) {
return true;
}
return false;
}
public DiagramElement createDiagramElement(
final Object modelElement,
final Rectangle bounds) {
FigNodeModelElement figNode = null;
DiagramSettings settings = getDiagramSettings();
if (Model.getFacade().isAPartition(modelElement)) {
figNode = new FigPartition(modelElement, bounds, settings);
} else if (Model.getFacade().isAActionState(modelElement)) {
figNode = new FigActionState(modelElement, bounds, settings);
} else if (Model.getFacade().isACallState(modelElement)) {
figNode = new FigCallState(modelElement, bounds, settings);
} else if (Model.getFacade().isAObjectFlowState(modelElement)) {
figNode = new FigObjectFlowState(modelElement, bounds, settings);
} else if (Model.getFacade().isASubactivityState(modelElement)) {
figNode = new FigSubactivityState(modelElement, bounds, settings);
} else if (Model.getFacade().isAFinalState(modelElement)) {
figNode = new FigFinalState(modelElement, bounds, settings);
} else if (Model.getFacade().isAPseudostate(modelElement)) {
Object kind = Model.getFacade().getKind(modelElement);
if (kind == null) {
LOG.warn("found a null type pseudostate");
return null;
}
if (kind.equals(Model.getPseudostateKind().getInitial())) {
figNode = new FigInitialState(modelElement, bounds, settings);
} else if (kind.equals(
Model.getPseudostateKind().getChoice())) {
figNode = new FigBranchState(modelElement, bounds, settings);
} else if (kind.equals(
Model.getPseudostateKind().getJunction())) {
figNode = new FigJunctionState(modelElement, bounds, settings);
} else if (kind.equals(
Model.getPseudostateKind().getFork())) {
figNode = new FigForkState(modelElement, bounds, settings);
} else if (kind.equals(
Model.getPseudostateKind().getJoin())) {
figNode = new FigJoinState(modelElement, bounds, settings);
} else {
LOG.warn("found a type not known");
}
} else if (Model.getFacade().isAComment(modelElement)) {
figNode = new FigComment(modelElement, bounds, settings);
}
if (figNode != null) {
LOG.debug("Model element " + modelElement + " converted to "
+ figNode);
} else {
LOG.debug("Dropped object NOT added " + figNode);
}
return figNode;
}
}