Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rentz-Reichert2018-07-06 17:19:51 +0000
committerHenrik Rentz-Reichert2018-07-06 17:22:00 +0000
commit0509ac03bea494b08a92251e68e9efc92e415a20 (patch)
treed070ca8800c829827df8aff75c1b773fe1115908 /plugins/org.eclipse.etrice.ui.behavior.fsm
parentc2dfdeabf15d7e367bcd92731e6ac8651ffb9cac (diff)
parentbed42b94fbf934db15e792b247ee747f0c37ebf4 (diff)
downloadorg.eclipse.etrice-0509ac03bea494b08a92251e68e9efc92e415a20.tar.gz
org.eclipse.etrice-0509ac03bea494b08a92251e68e9efc92e415a20.tar.xz
org.eclipse.etrice-0509ac03bea494b08a92251e68e9efc92e415a20.zip
Merge remote-tracking branch 'newfsmgen_finalize'
Conflicts: plugins/org.eclipse.etrice.ui.behavior.fsm/META-INF/MANIFEST.MF plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF Change-Id: Icc81a851cdcdb35081b8eaa3d5b025c1f850de54
Diffstat (limited to 'plugins/org.eclipse.etrice.ui.behavior.fsm')
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/.classpath3
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/META-INF/MANIFEST.MF10
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/PopulateDiagramCommand.java27
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/StateGraphContext.java274
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/AbstractMemberAwarePropertyDialog.java2
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/ChoicePointPropertyDialog.java2
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TrPointPropertyDialog.java2
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TransitionTriggerCompartment.java2
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramTypeProvider.java12
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMEditor.java29
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/BehaviorExporter.java2
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/DiagnosingModelObserver.java10
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/provider/BaseDiagramProvider.xtend83
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/provider/GenModelProvider.xtend68
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/AbstractFSMProviderDispatcher.java12
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/BaseDiagramPositionProvider.xtend165
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ChoicePointSupport.java11
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/Constants.java1
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ContextSwitcher.java1
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DefaultPositionProvider.java349
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DiagramUpdateFeature.java41
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/FSMSupportUtil.java997
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/GenModelStateGraphContext.xtend91
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/IStateGraphContext.java45
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/InitialPointSupport.java97
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphSupport.java35
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphUpdateContext.java7
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateSupport.java32
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TrPointSupport.java8
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TransitionSupport.java9
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramEditingUtil.java743
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramExtensions.xtend29
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/FSMSupportUtil.java271
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/ModelEditingUtil.xtend84
35 files changed, 1842 insertions, 1719 deletions
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/.classpath b/plugins/org.eclipse.etrice.ui.behavior.fsm/.classpath
index 1fa3e6803..87e8cd659 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/.classpath
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/.classpath
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="xtend-gen"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.etrice.ui.behavior.fsm/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.ui.behavior.fsm/META-INF/MANIFEST.MF
index 8e73b0042..af6a4bf54 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/META-INF/MANIFEST.MF
@@ -8,6 +8,7 @@ Bundle-Vendor: eTrice
Require-Bundle: org.eclipse.etrice.core.common.ui;bundle-version="1.1.3",
org.eclipse.etrice.ui.common.base;bundle-version="1.1.3",
org.eclipse.etrice.core.fsm;bundle-version="1.1.3",
+ org.eclipse.etrice.core.genmodel.fsm;bundle-version="1.1.3",
org.eclipse.etrice.core.fsm.ui;bundle-version="1.1.3",
org.eclipse.graphiti;bundle-version="0.8.0",
org.eclipse.graphiti.ui;bundle-version="0.8.0",
@@ -18,13 +19,16 @@ Require-Bundle: org.eclipse.etrice.core.common.ui;bundle-version="1.1.3",
org.eclipse.xtext.ui;bundle-version="2.7.0",
org.eclipse.xtend.lib;bundle-version="2.7.0",
org.eclipse.xtext.ui.shared;bundle-version="2.7.0",
- org.eclipse.etrice.expressions.ui;bundle-version="1.1.3"
+ org.eclipse.etrice.expressions.ui;bundle-version="1.1.3",
+ org.eclipse.xtext.ui.shared;bundle-version="2.7.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.etrice.ui.behavior.fsm.actioneditor,
+Export-Package: org.eclipse.etrice.ui.behavior.fsm,
+ org.eclipse.etrice.ui.behavior.fsm.actioneditor,
org.eclipse.etrice.ui.behavior.fsm.actioneditor.preferences,
org.eclipse.etrice.ui.behavior.fsm.commands,
org.eclipse.etrice.ui.behavior.fsm.dialogs,
org.eclipse.etrice.ui.behavior.fsm.editor,
org.eclipse.etrice.ui.behavior.fsm.provider,
- org.eclipse.etrice.ui.behavior.fsm.support
+ org.eclipse.etrice.ui.behavior.fsm.support,
+ org.eclipse.etrice.ui.behavior.fsm.support.util
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/PopulateDiagramCommand.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/PopulateDiagramCommand.java
index 28d00f9cc..6bc96f050 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/PopulateDiagramCommand.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/PopulateDiagramCommand.java
@@ -16,42 +16,33 @@ import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
import org.eclipse.etrice.ui.behavior.fsm.support.ContextSwitcher;
-import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
-import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.impl.UpdateContext;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.ui.services.GraphitiUi;
-import com.google.inject.Injector;
-
public class PopulateDiagramCommand extends RecordingCommand {
+ private String providerId;
private ModelComponent mc;
private Diagram diagram;
- private IFeatureProvider fp;
- private Injector injector;
- public PopulateDiagramCommand(String providerId, Diagram diag, ModelComponent mc, Injector injector, TransactionalEditingDomain domain) {
+ public PopulateDiagramCommand(String providerId, Diagram diag, ModelComponent mc, TransactionalEditingDomain domain) {
super(domain);
+ this.providerId = providerId;
this.diagram = diag;
this.mc = mc;
- this.injector = injector;
-
- IDiagramTypeProvider dtp = GraphitiUi.getExtensionManager().createDiagramTypeProvider(diagram, providerId); //$NON-NLS-1$
- fp = dtp.getFeatureProvider();
}
@Override
protected void doExecute() {
+ IDiagramTypeProvider dtp = GraphitiUi.getExtensionManager().createDiagramTypeProvider(diagram, providerId); //$NON-NLS-1$
- fp.link(diagram, mc);
-
- // we use a temporary structure to create the whole tree
- StateGraphContext tree = StateGraphContext.createContextTree(mc, injector);
- //System.out.println(tree);
-
- FSMSupportUtil.getInstance().addStateGraph(tree, diagram, fp);
+ dtp.getFeatureProvider().link(diagram, mc);
+
+ UpdateContext ctx = new UpdateContext(diagram);
+ dtp.getFeatureProvider().getUpdateFeature(ctx).update(ctx);
ContextSwitcher.switchTop(diagram);
}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/StateGraphContext.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/StateGraphContext.java
deleted file mode 100644
index 867ab3953..000000000
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/commands/StateGraphContext.java
+++ /dev/null
@@ -1,274 +0,0 @@
-package org.eclipse.etrice.ui.behavior.fsm.commands;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.etrice.core.fsm.fSM.ChoicePoint;
-import org.eclipse.etrice.core.fsm.fSM.FSMFactory;
-import org.eclipse.etrice.core.fsm.fSM.InitialTransition;
-import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
-import org.eclipse.etrice.core.fsm.fSM.RefinedState;
-import org.eclipse.etrice.core.fsm.fSM.SimpleState;
-import org.eclipse.etrice.core.fsm.fSM.State;
-import org.eclipse.etrice.core.fsm.fSM.StateGraph;
-import org.eclipse.etrice.core.fsm.fSM.StateGraphItem;
-import org.eclipse.etrice.core.fsm.fSM.TrPoint;
-import org.eclipse.etrice.core.fsm.fSM.Transition;
-import org.eclipse.etrice.ui.behavior.fsm.support.DefaultPositionProvider;
-import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil;
-import org.eclipse.etrice.ui.behavior.fsm.support.IPositionProvider;
-
-import com.google.inject.Injector;
-
-public class StateGraphContext {
- private ArrayList<StateGraphContext> children = new ArrayList<StateGraphContext>();
-
- private StateGraph stateGraph;
- private ArrayList<State> states = new ArrayList<State>();
- private ArrayList<ChoicePoint> chPoints = new ArrayList<ChoicePoint>();
- private ArrayList<TrPoint> trPoints = new ArrayList<TrPoint>();
- private ArrayList<Transition> transitions = new ArrayList<Transition>();
- private IPositionProvider positionProvider;
- private HashMap<StateGraphItem, StateGraphContext> obj2ctx;
-
- public static StateGraphContext createContextTree(ModelComponent mc, Injector injector) {
-
- // the top level state graph is always the one of our actor class
- if (mc.getStateMachine()==null || mc.getStateMachine().eIsProxy()) {
- mc.setStateMachine(FSMFactory.eINSTANCE.createStateGraph());
- }
-
- // base classes in reverse order
- ArrayList<ModelComponent> classes = new ArrayList<ModelComponent>();
- {
- ModelComponent a = mc;
- while (a!=null) {
- classes.add(0, a);
- a = a.getBase();
- }
- }
-
- // build and merge contexts from base classes to derived classes
- StateGraphContext tree = null;
- for (ModelComponent cls : classes) {
- if (cls.getStateMachine()!=null) {
- if (tree==null)
- tree = new StateGraphContext(cls.getStateMachine(), new HashMap<StateGraphItem, StateGraphContext>());
- else
- tree.merge(cls.getStateMachine());
- }
- }
-
- tree.positionProvider = new DefaultPositionProvider(mc, injector);
- makePositionsAvailableToChildrenContexts(tree);
-
- return tree;
- }
-
- private StateGraphContext(StateGraph sg, HashMap<StateGraphItem, StateGraphContext> obj2ctx) {
- this.stateGraph = sg;
- this.obj2ctx = obj2ctx;
-
- init(sg);
- }
-
- private void init(StateGraph sg) {
- for (State s : sg.getStates()) {
- states.add(s);
- obj2ctx.put(s, this);
- }
- for (ChoicePoint cp : sg.getChPoints()) {
- chPoints.add(cp);
- obj2ctx.put(cp, this);
- }
- for (TrPoint tp : sg.getTrPoints()) {
- trPoints.add(tp);
- obj2ctx.put(tp, this);
- }
- for (Transition t : sg.getTransitions()) {
- transitions.add(t);
- obj2ctx.put(t, this);
- }
-
- // recurse
- for (State s : sg.getStates()) {
- if (s.getSubgraph()!=null)
- children.add(new StateGraphContext(s.getSubgraph(), obj2ctx));
- }
- }
-
- private void merge(StateGraph derived) {
- stateGraph = derived;
-
- // add derived contents up to refined states
- for (State s : derived.getStates()) {
- if (s instanceof SimpleState) {
- states.add(s);
- obj2ctx.put(s, this);
- }
- }
- for (ChoicePoint cp : derived.getChPoints()) {
- chPoints.add(cp);
- obj2ctx.put(cp, this);
- }
- for (TrPoint tp : derived.getTrPoints()) {
- trPoints.add(tp);
- obj2ctx.put(tp, this);
- }
- for (Transition t : derived.getTransitions()) {
- transitions.add(t);
- obj2ctx.put(t, this);
- }
-
- // recurse for non-refined states
- for (State s : derived.getStates()) {
- if (s instanceof SimpleState)
- if (s.getSubgraph()!=null)
- children.add(new StateGraphContext(s.getSubgraph(), obj2ctx));
- }
-
- // refined states
- for (State refined : derived.getStates()) {
- if (refined instanceof RefinedState) {
- State base = ((RefinedState) refined).getTarget();
- StateGraphContext ctx = obj2ctx.get(base);
- assert(ctx!=null): "should have visited base state already";
-
- // remove base and put refined in place
- ctx.getStates().remove(base);
- ctx.getStates().add(refined);
- obj2ctx.put(refined, this);
-
- // merge sub contexts
- if (FSMSupportUtil.getInstance().getFSMHelpers().hasDirectSubStructure(base)) {
- StateGraphContext basesub = null;
- for (StateGraphContext bs : ctx.getChildren()) {
- if (bs.getParentState()==base) {
- basesub = bs;
- break;
- }
- }
- if (basesub!=null) {
- if (FSMSupportUtil.getInstance().getFSMHelpers().hasDirectSubStructure(refined)) {
- basesub.merge(refined.getSubgraph());
- }
- }
- else {
- assert(false): "context not found";
- }
- }
- else if (FSMSupportUtil.getInstance().getFSMHelpers().hasDirectSubStructure(refined)) {
- StateGraphContext sub = new StateGraphContext(refined.getSubgraph(), obj2ctx);
- ctx.getChildren().add(sub);
- }
- }
- }
- }
-
- /**
- * Propagate the position map to all children recursively
- *
- * @param tree
- */
- private static void makePositionsAvailableToChildrenContexts(StateGraphContext tree) {
- for (StateGraphContext child : tree.getChildren()) {
- child.positionProvider = tree.positionProvider;
- makePositionsAvailableToChildrenContexts(child);
- }
- }
-
- public State getParentState() {
- if (stateGraph.eContainer() instanceof State)
- return (State) stateGraph.eContainer();
-
- return null;
- }
-
- public ArrayList<StateGraphContext> getChildren() {
- return children;
- }
-
- public ArrayList<State> getStates() {
- return states;
- }
-
- public ArrayList<ChoicePoint> getChPoints() {
- return chPoints;
- }
-
- public StateGraph getStateGraph() {
- return stateGraph;
- }
-
- public ArrayList<TrPoint> getTrPoints() {
- return trPoints;
- }
-
- public ArrayList<Transition> getTransitions() {
- return transitions;
- }
-
- public IPositionProvider getPositionProvider() {
- return positionProvider;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return dump("");
- }
-
- /**
- * @param indent
- * @return context tree in human readable form
- */
- private String dump(String indent) {
- StringBuilder result = new StringBuilder();
- result.append(indent+">>> "+getText(stateGraph)+"\n");
- indent += " ";
- for (State s : states) {
- result.append(indent+getText(s)+"\n");
- }
-
- for (StateGraphContext child : children) {
- result.append(child.dump(indent));
- }
- return result.toString();
- }
-
- private String getText(StateGraph sg) {
- ModelComponent mc = getModelComponent(sg);
- EObject parent = sg.eContainer();
- String item = parent instanceof ModelComponent? "diagram" : (parent.eClass().getName()+" "+((State)parent).getName());
- return "state graph of "+item+" of "+(mc==null? "?":mc.getComponentName());
- }
-
- private String getText(StateGraphItem item) {
- ModelComponent mc = getModelComponent(item);
- return item.eClass().getName()+" "+item.getName()+" of "+(mc==null? "?":mc.getComponentName());
- }
-
- private ModelComponent getModelComponent(EObject obj) {
- EObject parent = obj.eContainer();
- while (parent!=null) {
- if (parent instanceof ModelComponent)
- return (ModelComponent) parent;
- parent = parent.eContainer();
- }
- return null;
- }
-
- public StateGraphContext getContext(StateGraphItem item) {
- return obj2ctx.get(item);
- }
-
- public StateGraph getInitialPoint(){
- for(Transition t : transitions)
- if(t instanceof InitialTransition)
- return (StateGraph) t.eContainer();
- return null;
- }
-}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/AbstractMemberAwarePropertyDialog.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/AbstractMemberAwarePropertyDialog.java
index 90ebde21c..72419ec9d 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/AbstractMemberAwarePropertyDialog.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/AbstractMemberAwarePropertyDialog.java
@@ -29,7 +29,7 @@ import org.eclipse.etrice.ui.behavior.fsm.actioneditor.ActionCodeEditorRegistry;
import org.eclipse.etrice.ui.behavior.fsm.actioneditor.ActionCodeEditorRegistry.ActionCodeEditorRegistryEntry;
import org.eclipse.etrice.ui.behavior.fsm.actioneditor.IActionCodeEditor;
import org.eclipse.etrice.ui.behavior.fsm.actioneditor.preferences.PreferenceConstants;
-import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.etrice.ui.common.base.dialogs.AbstractPropertyDialog;
import org.eclipse.etrice.ui.common.base.dialogs.MultiValidator2;
import org.eclipse.jface.preference.IPreferenceStore;
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/ChoicePointPropertyDialog.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/ChoicePointPropertyDialog.java
index 6eb48c402..ccdc035e0 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/ChoicePointPropertyDialog.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/ChoicePointPropertyDialog.java
@@ -9,7 +9,7 @@ import org.eclipse.etrice.core.fsm.fSM.ChoicePoint;
import org.eclipse.etrice.core.fsm.fSM.FSMPackage;
import org.eclipse.etrice.core.fsm.validation.FSMValidationUtilXtend.Result;
import org.eclipse.etrice.ui.behavior.fsm.Activator;
-import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.etrice.ui.common.base.dialogs.AbstractPropertyDialog;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TrPointPropertyDialog.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TrPointPropertyDialog.java
index d9a369885..7c0fd40d5 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TrPointPropertyDialog.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TrPointPropertyDialog.java
@@ -10,7 +10,7 @@ import org.eclipse.etrice.core.fsm.fSM.TrPoint;
import org.eclipse.etrice.core.fsm.fSM.TransitionPoint;
import org.eclipse.etrice.core.fsm.validation.FSMValidationUtilXtend.Result;
import org.eclipse.etrice.ui.behavior.fsm.Activator;
-import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.etrice.ui.common.base.dialogs.AbstractPropertyDialog;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TransitionTriggerCompartment.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TransitionTriggerCompartment.java
index 1fcef7532..d86bc6790 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TransitionTriggerCompartment.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/dialogs/TransitionTriggerCompartment.java
@@ -25,7 +25,7 @@ import org.eclipse.etrice.core.fsm.fSM.Transition;
import org.eclipse.etrice.core.fsm.fSM.Trigger;
import org.eclipse.etrice.core.fsm.fSM.TriggeredTransition;
import org.eclipse.etrice.core.fsm.naming.FSMNameProvider;
-import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.etrice.ui.common.base.dialogs.AbstractPropertyDialog;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramTypeProvider.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramTypeProvider.java
index fa38f2706..80044564b 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramTypeProvider.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramTypeProvider.java
@@ -12,6 +12,8 @@
package org.eclipse.etrice.ui.behavior.fsm.editor;
+import org.eclipse.etrice.ui.behavior.fsm.provider.GenModelProvider;
+import org.eclipse.etrice.ui.behavior.fsm.provider.IInjectorProvider;
import org.eclipse.etrice.ui.common.base.editor.AbstractBaseDiagramTypeProvider;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.platform.IDiagramContainer;
@@ -21,7 +23,15 @@ import org.eclipse.graphiti.platform.IDiagramContainer;
* functionality provided by {@link AbstractFSMEditor}. Diagram editor plugins
* that extend {@link AbstractFSMEditor} should also extend and use this class.
*/
-public abstract class AbstractFSMDiagramTypeProvider extends AbstractBaseDiagramTypeProvider {
+public abstract class AbstractFSMDiagramTypeProvider extends AbstractBaseDiagramTypeProvider implements IInjectorProvider {
+
+ public GenModelProvider getGenModelProvider() {
+ // create always new one for now
+// Stopwatch timer = Stopwatch.createStarted();
+// GenModelProvider genModelProvider = new GenModelProvider(this);
+// System.out.println(timer.stop().elapsed(TimeUnit.MILLISECONDS));
+ return new GenModelProvider(this);
+ }
/* (non-Javadoc)
* @see org.eclipse.graphiti.dt.AbstractDiagramTypeProvider#resourceReloaded(org.eclipse.graphiti.mm.pictograms.Diagram)
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMEditor.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMEditor.java
index 389a9ff45..bc2609c17 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMEditor.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMEditor.java
@@ -13,6 +13,7 @@
package org.eclipse.etrice.ui.behavior.fsm.editor;
import java.util.ArrayList;
+import java.util.EventObject;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -27,8 +28,9 @@ import org.eclipse.etrice.core.fsm.fSM.RefinedState;
import org.eclipse.etrice.core.fsm.fSM.State;
import org.eclipse.etrice.core.fsm.fSM.StateGraph;
import org.eclipse.etrice.core.fsm.util.FSMHelpers;
+import org.eclipse.etrice.core.fsm.validation.FSMValidationUtil;
import org.eclipse.etrice.ui.behavior.fsm.support.ContextSwitcher;
-import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.etrice.ui.common.base.editor.DiagramEditorBase;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IFeatureProvider;
@@ -38,6 +40,8 @@ import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.ui.editor.DiagramBehavior;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
import com.google.common.base.Function;
@@ -139,6 +143,23 @@ public abstract class AbstractFSMEditor extends DiagramEditorBase {
@Override
public void doSave(IProgressMonitor monitor) {
+
+ FSMValidationUtil fsmValidationUtil = FSMSupportUtil.getInstance().getFSMValidationUtil();
+ Diagram diagram = getDiagramTypeProvider().getDiagram();
+ ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(diagram);
+ if (mc.getStateMachine()!=null) {
+ for (State s : mc.getStateMachine().getStates()) {
+ if (s instanceof RefinedState) {
+ if (fsmValidationUtil.isRefinedStateEmpty((RefinedState) s)) {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(),
+ "Check of Refined State",
+ "A Refined State with empty action codes must have a non-empty sub state graph.");
+ return;
+ }
+ }
+ }
+ }
+
getEditingDomain().getCommandStack().execute(new RecordingCommand(getEditingDomain()) {
protected void doExecute() {
cleanupBeforeSave();
@@ -270,4 +291,10 @@ public abstract class AbstractFSMEditor extends DiagramEditorBase {
featureProvider.updateIfPossible(updateCtx);
diagramTypeProvider.getDiagramBehavior().refresh();
}
+
+ @Override
+ public void commandStackChanged(EventObject event) {
+ // TODO Auto-generated method stub
+ super.commandStackChanged(event);
+ }
}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/BehaviorExporter.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/BehaviorExporter.java
index 782b7a916..95d2b3499 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/BehaviorExporter.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/BehaviorExporter.java
@@ -18,7 +18,7 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
import org.eclipse.etrice.core.fsm.fSM.State;
import org.eclipse.etrice.core.fsm.fSM.StateGraph;
-import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.etrice.ui.common.base.export.DiagramExporter;
import org.eclipse.etrice.ui.common.base.export.IBulkDiagramExporter;
import org.eclipse.etrice.ui.common.base.support.DiagramAccessBase;
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/DiagnosingModelObserver.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/DiagnosingModelObserver.java
index ba29924be..8a7eea9a3 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/DiagnosingModelObserver.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/DiagnosingModelObserver.java
@@ -23,6 +23,7 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.eclipse.etrice.core.fsm.fSM.DetailCode;
import org.eclipse.etrice.core.fsm.fSM.StateGraph;
import org.eclipse.etrice.core.fsm.fSM.Trigger;
import org.eclipse.xtext.validation.FeatureBasedDiagnostic;
@@ -116,10 +117,13 @@ public class DiagnosingModelObserver extends EContentAdapter {
super.notifyChanged(notification);
// Re-Validate on each notification except Adapter Removal.
- // This prevents the editor to hang on dispose (since all adapters are
- // then removed).
+ // This prevents the editor to hang on dispose (since all adapters are then removed).
if (notification.getEventType() < Notification.REMOVING_ADAPTER) {
- updateElementDiagnosticMap();
+ if(!(notification.getNewValue() instanceof EObject) || notification.getNewValue() instanceof DetailCode) {
+ // Bug 531689: skip validation when user is typing in DetailCode or text field to prevent delay
+ } else {
+ updateElementDiagnosticMap();
+ }
}
}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/provider/BaseDiagramProvider.xtend b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/provider/BaseDiagramProvider.xtend
new file mode 100644
index 000000000..d6ad81747
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/provider/BaseDiagramProvider.xtend
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.provider
+
+import com.google.common.collect.ArrayListMultimap
+import com.google.common.collect.Multimap
+import java.util.Collection
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.util.EcoreUtil
+import org.eclipse.etrice.core.fsm.fSM.ModelComponent
+import org.eclipse.etrice.core.fsm.fSM.StateGraph
+import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMDiagramTypeProvider
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil
+import org.eclipse.etrice.ui.common.base.support.DiagramAccessBase
+import org.eclipse.graphiti.mm.pictograms.PictogramElement
+import org.eclipse.graphiti.mm.pictograms.PictogramLink
+import org.eclipse.graphiti.services.Graphiti
+
+/**
+ * Provides the {@linkplain PictogramElement} objects of the base class diagram.
+ * This is a reverse mapping from room business objects to linked base diagram pictograms.
+ *
+ * TODO: use fsmgenmodel instead
+ */
+class BaseDiagramProvider {
+
+ val Multimap<EObject, PictogramElement> baseDiagramBusinessObjs = ArrayListMultimap.create
+ val fsmHelpers = FSMSupportUtil.instance.FSMHelpers
+
+ new(AbstractFSMDiagramTypeProvider diagramTypeProvider) {
+ val diagramAccess = diagramTypeProvider.injector.getInstance(DiagramAccessBase)
+ val mc = Graphiti.linkService.getBusinessObjectForLinkedPictogramElement(diagramTypeProvider.diagram) as ModelComponent
+ val rs = diagramTypeProvider.diagram.eResource.resourceSet
+
+ // open base diagrams => causes full recursive update or creation of all base diagrams
+ // all base diagrams have to be considered because inherited subgraph could not exist yet
+ val baseClasses = newArrayList => [
+ var base = mc.base
+ while(base !== null && it.add(base)) {
+ base = base.base
+ }
+ ]
+ baseClasses.reverseView.forEach[ base |
+ val baseDiagram = diagramAccess.getDiagram(base, rs)
+ if(baseDiagram !== null) {
+ // create mapping from business object to pictogram elements
+ EcoreUtil.ExternalCrossReferencer.find(baseDiagram).forEach [ targetEObj, eFeatureSetting |
+ eFeatureSetting.map[getEObject].filter(PictogramLink).map[pictogramElement].forEach [ pe |
+ put(mc, targetEObj, pe)
+ ]
+ ]
+
+ // base diagram resource not needed anymore
+ rs.resources.remove(baseDiagram.eResource)
+ }
+ ]
+ }
+
+ private def put(ModelComponent mc, EObject obj, PictogramElement value) {
+ if (obj instanceof StateGraph) {
+ if (fsmHelpers.isTopLevel(obj)) {
+ // to find the initial point of the TOP level we need the ModelComponent's stateMachine as a key
+ baseDiagramBusinessObjs.put(mc.stateMachine, value)
+ }
+ }
+ baseDiagramBusinessObjs.put(obj, value)
+ }
+
+ def Collection<PictogramElement> getPictograms(EObject roomObj) {
+ if(roomObj === null) emptyList else baseDiagramBusinessObjs.get(roomObj)
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/provider/GenModelProvider.xtend b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/provider/GenModelProvider.xtend
new file mode 100644
index 000000000..7b9c50473
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/provider/GenModelProvider.xtend
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.provider
+
+import java.util.Map
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.etrice.core.fsm.fSM.ModelComponent
+import org.eclipse.etrice.core.genmodel.fsm.BasicFsmGenBuilder
+import org.eclipse.etrice.core.genmodel.fsm.fsmgen.Graph
+import org.eclipse.etrice.core.genmodel.fsm.fsmgen.GraphContainer
+import org.eclipse.etrice.core.genmodel.fsm.fsmgen.Link
+import org.eclipse.etrice.core.genmodel.fsm.fsmgen.Node
+import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMDiagramTypeProvider
+import org.eclipse.graphiti.dt.IDiagramTypeProvider
+import org.eclipse.graphiti.services.Graphiti
+import org.eclipse.etrice.core.genmodel.fsm.fsmgen.FSMGenElement
+
+class GenModelProvider {
+
+ val BasicFsmGenBuilder builder
+ val IDiagramTypeProvider fsmDiagramProvider
+ var Map<EObject, FSMGenElement> graphMap = newHashMap
+
+ var GraphContainer modelInstance = null
+
+ new(AbstractFSMDiagramTypeProvider fsmDiagramProvider) {
+ this.fsmDiagramProvider = fsmDiagramProvider
+ builder = new BasicFsmGenBuilder(fsmDiagramProvider.injector)
+ }
+
+ def updateModel() {
+ Graphiti.linkService.getBusinessObjectForLinkedPictogramElement(fsmDiagramProvider.diagram) => [
+ modelInstance = if(it instanceof ModelComponent) builder.createTransformedModel(it) else null
+ ]
+ if (modelInstance !== null) {
+ graphMap.clear
+ modelInstance.eAllContents.forEach [
+ switch (it) {
+ Graph: graphMap.put(stateGraph, it)
+ Node: graphMap.put(stateGraphNode, it)
+ Link: graphMap.put(transition, it)
+ }
+ ]
+ }
+ }
+
+ def getModel() {
+ if (modelInstance === null) {
+ updateModel()
+ }
+
+ return modelInstance;
+ }
+
+ def <T extends FSMGenElement> getCasted(EObject roomObj) {
+ return graphMap.get(roomObj) as T
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/AbstractFSMProviderDispatcher.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/AbstractFSMProviderDispatcher.java
index 1b231a161..9fad672db 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/AbstractFSMProviderDispatcher.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/AbstractFSMProviderDispatcher.java
@@ -24,6 +24,7 @@ import org.eclipse.etrice.core.fsm.fSM.TrPoint;
import org.eclipse.etrice.core.fsm.fSM.Transition;
import org.eclipse.etrice.core.fsm.fSM.util.FSMSwitch;
import org.eclipse.etrice.core.fsm.naming.FSMFragmentProvider;
+import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMDiagramTypeProvider;
import org.eclipse.etrice.ui.behavior.fsm.provider.IInjectorProvider;
import org.eclipse.etrice.ui.common.base.support.CantDeleteFeature;
import org.eclipse.etrice.ui.common.base.support.CantRemoveFeature;
@@ -78,7 +79,7 @@ import org.eclipse.graphiti.util.IColorConstant;
import com.google.inject.Injector;
-public abstract class AbstractFSMProviderDispatcher implements IInjectorProvider {
+public class AbstractFSMProviderDispatcher {
private class FeatureProviderSwitch extends FSMSwitch<IFeatureProvider> {
private ContainerShape parent = null;
@@ -235,9 +236,9 @@ public abstract class AbstractFSMProviderDispatcher implements IInjectorProvider
private IInjectorProvider injectorProvider;
- public DispatchingFeatureProvider(IDiagramTypeProvider dtp, IInjectorProvider injectorProvider) {
+ public DispatchingFeatureProvider(AbstractFSMDiagramTypeProvider dtp) {
super(dtp);
- this.injectorProvider = injectorProvider;
+ this.injectorProvider = dtp;
}
@Override
@@ -550,9 +551,9 @@ public abstract class AbstractFSMProviderDispatcher implements IInjectorProvider
private DispatchingToolBehaviorProvider dispatchingBP;
- public AbstractFSMProviderDispatcher(IDiagramTypeProvider dtp) {
+ public AbstractFSMProviderDispatcher(AbstractFSMDiagramTypeProvider dtp) {
// create those first before using them
- dispatchingFP = new DispatchingFeatureProvider(dtp, this);
+ dispatchingFP = new DispatchingFeatureProvider(dtp);
dispatchingBP = new DispatchingToolBehaviorProvider(dtp);
stateGraphSupport = new StateGraphSupport(dtp, dispatchingFP);
@@ -582,6 +583,7 @@ public abstract class AbstractFSMProviderDispatcher implements IInjectorProvider
return featureSwitch.getCreateConnectionFeatures();
}
+ @SafeVarargs
private static <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/BaseDiagramPositionProvider.xtend b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/BaseDiagramPositionProvider.xtend
new file mode 100644
index 000000000..083c0e12e
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/BaseDiagramPositionProvider.xtend
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.support
+
+import java.util.List
+import org.eclipse.etrice.core.fsm.fSM.InitialTransition
+import org.eclipse.etrice.core.fsm.fSM.ModelComponent
+import org.eclipse.etrice.core.fsm.fSM.RefinedState
+import org.eclipse.etrice.core.fsm.fSM.RefinedTransition
+import org.eclipse.etrice.core.fsm.fSM.State
+import org.eclipse.etrice.core.fsm.fSM.StateGraph
+import org.eclipse.etrice.core.fsm.fSM.StateGraphNode
+import org.eclipse.etrice.core.fsm.fSM.TrPoint
+import org.eclipse.etrice.core.fsm.fSM.Transition
+import org.eclipse.etrice.ui.behavior.fsm.provider.BaseDiagramProvider
+import org.eclipse.graphiti.mm.algorithms.Text
+import org.eclipse.graphiti.mm.pictograms.Connection
+import org.eclipse.graphiti.mm.pictograms.FreeFormConnection
+import org.eclipse.graphiti.mm.pictograms.PictogramElement
+import org.eclipse.graphiti.services.Graphiti
+import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
+
+/**
+ * IPositionProvider based on {@linkplain BaseDiagramProvider}
+ * Logic copied from DefaultPositionProvider
+ */
+@FinalFieldsConstructor
+class BaseDiagramPositionProvider implements IPositionProvider {
+
+ val BaseDiagramProvider baseDiagram
+
+ // TODO: positions should not rely on graphics internals
+ def getMargin(StateGraphNode node) {
+ switch node {
+ State: StateSupport.MARGIN
+ TrPoint: TrPointSupport.MARGIN
+ default: 0
+ }
+ }
+
+ // TODO: positions should not rely on graphics internals
+ def getMargin(StateGraph graph){
+ return 0
+ }
+
+ def private toPosAndSize(PictogramElement pe, int margin){
+ val borderGa = (pe.eContainer as PictogramElement).graphicsAlgorithm.graphicsAlgorithmChildren.head
+ val ga = pe.graphicsAlgorithm
+
+ val x = (ga.getX() / borderGa.width as double) * sx + margin
+ val y = (ga.getY() / borderGa.height as double) * sy + margin
+ val width = ((ga.getWidth() - 2 * margin) / borderGa.width as double) * sx
+ val height = ((ga.getHeight() - 2 * margin) / borderGa.height as double) * sy
+
+ new PosAndSize(x as int, y as int, width as int, height as int)
+ }
+
+ override getGraphPosAndSize(StateGraph sg) {
+ // graph is child of border shape, see initial point
+ val pe = baseDiagram.getPictograms(sg).findFirst[parentBo instanceof ModelComponent]
+ if (pe !== null){
+ val visibleGa = pe.graphicsAlgorithm.graphicsAlgorithmChildren.head
+ new PosAndSize(pe.graphicsAlgorithm.x, pe.graphicsAlgorithm.y, visibleGa.width, visibleGa.height)
+ }
+ }
+
+ override getPoints(Transition trans) {
+ val pe = {
+ if (trans instanceof RefinedTransition)
+ baseDiagram.getPictograms(trans.target).head
+ else
+ baseDiagram.getPictograms(trans).head
+ }
+ newArrayList => [ pointList |
+ if (pe instanceof Connection){
+ val graphPosAndSize = getGraphPosAndSize(trans.eContainer as StateGraph)
+ val text = pe.connectionDecorators.map[graphicsAlgorithm].filter(Text).head
+ if (text !== null){
+ pointList += new Pos(
+ (((text.x / graphPosAndSize.width as double) * sx) as int),
+ (((text.y / graphPosAndSize.height as double) * sy) as int)
+ )
+ if (pe instanceof FreeFormConnection){
+ pointList += pe.bendpoints.map[pt | new Pos(
+ (((pt.x / graphPosAndSize.width as double) * sx + x) as int) - StateGraphSupport.MARGIN,
+ (((pt.y / graphPosAndSize.height as double) * sy + y) as int) - StateGraphSupport.MARGIN
+ )]
+ }
+ }
+ }
+ ]
+ }
+
+ override getPosition(StateGraphNode node) {
+ val getBasePos = [baseDiagram.getPictograms(it).findFirst[parentBo instanceof StateGraph]?.toPosAndSize(node.margin)]
+
+ return if(node instanceof RefinedState){
+ // 1. RefinedState is base diagram
+ // 2. RefinedState target is in base diagram
+ getBasePos.apply(node)?:getBasePos.apply(node.target)
+ } else {
+ getBasePos.apply(node)
+ }
+ }
+
+ override getInitialPoint(StateGraph stateGraph) {
+ val initTransPe = baseDiagram.getPictograms(stateGraph.transitions.filter(InitialTransition).head).head
+ if(initTransPe instanceof Connection){
+ val sourceAnchorBo = Graphiti.linkService.getBusinessObjectForLinkedPictogramElement(initTransPe.start)
+ if(sourceAnchorBo instanceof StateGraph)
+ return sourceAnchorBo
+ }
+ }
+
+ // TODO: better naming, this is the initial point
+ override getPosition(StateGraph graph) {
+ // initial point bo is graph and it is child of border shape
+ baseDiagram.getPictograms(graph).findFirst[parentBo instanceof StateGraph]?.toPosAndSize(graph.margin)
+ }
+
+ override <T extends StateGraphNode> getPositions(List<T> items) {
+ items.map[baseDiagram.getPictograms(it).head?.toPosAndSize(it.margin)]
+ }
+
+ override getSubPosition(StateGraphNode subNode) {
+ val pe = baseDiagram.getPictograms(subNode).findFirst[parentBo instanceof State]
+ if (pe !== null){
+ val parentPe = pe.eContainer as PictogramElement
+ val relX = pe.graphicsAlgorithm.getX() as double / (parentPe.graphicsAlgorithm.getWidth() - 2 * StateSupport.MARGIN)
+ val relY = pe.graphicsAlgorithm.getY() as double / (parentPe.graphicsAlgorithm.getHeight() - 2 * StateSupport.MARGIN)
+ return #[relX, relY]
+ }
+ }
+
+ var int x
+ var int y
+
+ override setPosition(int x, int y) {
+ this.x = x
+ this.y = y
+ }
+
+ var double sx
+ var double sy
+
+ override setScale(double sx, double sy) {
+ this.sx = sx
+ this.sy = sy
+ }
+
+ def private getParentBo(PictogramElement pe) {
+ Graphiti.linkService.getBusinessObjectForLinkedPictogramElement(pe.eContainer as PictogramElement)
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ChoicePointSupport.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ChoicePointSupport.java
index 8cb7bced3..d7891a575 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ChoicePointSupport.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ChoicePointSupport.java
@@ -27,6 +27,8 @@ import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMEditor;
import org.eclipse.etrice.ui.behavior.fsm.editor.DecoratorUtil;
import org.eclipse.etrice.ui.behavior.fsm.provider.IInjectorProvider;
import org.eclipse.etrice.ui.behavior.fsm.provider.ImageProvider;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.ModelEditingUtil;
import org.eclipse.etrice.ui.common.base.support.ChangeAwareCreateFeature;
import org.eclipse.etrice.ui.common.base.support.ChangeAwareCustomFeature;
import org.eclipse.etrice.ui.common.base.support.CommonSupportUtil;
@@ -92,7 +94,7 @@ import org.eclipse.ui.PlatformUI;
import com.google.inject.Injector;
public class ChoicePointSupport {
-
+
public static final int ITEM_SIZE = (int) (StateGraphSupport.MARGIN*0.625);
protected static final int LINE_WIDTH = 2;
@@ -121,9 +123,8 @@ public class ChoicePointSupport {
StateGraph sg = (StateGraph) targetContainer.getLink().getBusinessObjects().get(0);
ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
- boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg);
- if (inherited) {
- sg = FSMSupportUtil.getInstance().insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
+ if (!FSMSupportUtil.getInstance().isOwnedBy(mc, sg)) {
+ sg = ModelEditingUtil.insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
}
// create choice point and add it
@@ -193,7 +194,7 @@ public class ChoicePointSupport {
ContainerShape containerShape =
peCreateService.createContainerShape(sgShape, true);
- Graphiti.getPeService().setPropertyValue(containerShape, Constants.TYPE_KEY, Constants.TRP_TYPE);
+ Graphiti.getPeService().setPropertyValue(containerShape, Constants.TYPE_KEY, Constants.CP_TYPE);
int x = context.getX()-ITEM_SIZE;
int y = context.getY()-ITEM_SIZE;
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/Constants.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/Constants.java
index a7d17712c..9af3edb57 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/Constants.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/Constants.java
@@ -20,5 +20,6 @@ public interface Constants {
static final String STATE_TYPE = "state";
static final String CP_TYPE = "cp";
static final String TRP_TYPE = "trp";
+ static final String INI_TYPE = "ini";
static final String TRANS_TYPE = "trans";
}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ContextSwitcher.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ContextSwitcher.java
index cdde42d97..4256eaf38 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ContextSwitcher.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/ContextSwitcher.java
@@ -9,6 +9,7 @@ import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
import org.eclipse.etrice.core.fsm.fSM.RefinedState;
import org.eclipse.etrice.core.fsm.fSM.State;
import org.eclipse.etrice.core.fsm.fSM.StateGraph;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DefaultPositionProvider.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DefaultPositionProvider.java
deleted file mode 100644
index 3be1be189..000000000
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DefaultPositionProvider.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 protos software gmbh (http://www.protos.de).
- * 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:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.ui.behavior.fsm.support;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.etrice.core.fsm.fSM.ChoicePoint;
-import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
-import org.eclipse.etrice.core.fsm.fSM.State;
-import org.eclipse.etrice.core.fsm.fSM.StateGraph;
-import org.eclipse.etrice.core.fsm.fSM.StateGraphItem;
-import org.eclipse.etrice.core.fsm.fSM.StateGraphNode;
-import org.eclipse.etrice.core.fsm.fSM.TrPoint;
-import org.eclipse.etrice.core.fsm.fSM.Transition;
-import org.eclipse.etrice.core.fsm.naming.FSMNameProvider;
-import org.eclipse.etrice.ui.behavior.fsm.commands.StateGraphContext;
-import org.eclipse.etrice.ui.common.base.support.DiagramAccessBase;
-import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
-import org.eclipse.graphiti.mm.algorithms.Text;
-import org.eclipse.graphiti.mm.algorithms.styles.Point;
-import org.eclipse.graphiti.mm.pictograms.Connection;
-import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
-import org.eclipse.graphiti.mm.pictograms.ContainerShape;
-import org.eclipse.graphiti.mm.pictograms.Diagram;
-import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
-import org.eclipse.graphiti.mm.pictograms.Shape;
-import org.eclipse.graphiti.services.Graphiti;
-import org.eclipse.graphiti.services.ILinkService;
-
-import com.google.inject.Injector;
-
-/**
- * @author Henrik Rentz-Reichert (initial contribution)
- *
- */
-public class DefaultPositionProvider implements IPositionProvider {
- private static class Position {
- double x;
- double y;
- double sx;
- double sy;
- }
-
- private HashMap<String, Position> obj2pos = new HashMap<String, Position>();
- private HashMap<String, Position> subObj2pos = new HashMap<String, Position>();
- private HashMap<String, ArrayList<Position>> trans2points = new HashMap<String, ArrayList<Position>>();
- private HashMap<String, StateGraph> initialPointObj = new HashMap<String, StateGraph>();
- private HashMap<String, PosAndSize> sg2sz = new HashMap<String, PosAndSize>();
- private double scaleX;
- private double scaleY;
- private int posX, posY;
-
- public DefaultPositionProvider(ModelComponent mc, Injector injector) {
- mapPositions(mc.getBase(), injector);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.etrice.ui.behavior.support.IPositionProvider#setScale(double, double)
- */
- @Override
- public void setScale(double sx, double sy) {
- this.scaleX = sx;
- this.scaleY = sy;
- }
-
- @Override
- public void setPosition(int x, int y){
- this.posX = x;
- this.posY = y;
- }
-
- public PosAndSize getPosition(StateGraphNode node) {
- Position pos = obj2pos.get(FSMSupportUtil.getInstance().getFSMNameProvider().getFullPath(node));
- if (pos==null)
- return null;
-
- int margin = getMargin(node);
- PosAndSize pt = new PosAndSize(
- (int) (pos.x * scaleX) + margin,
- (int) (pos.y * scaleY) + margin,
- (int) (pos.sx * scaleX),
- (int) (pos.sy * scaleY)
- );
- return pt;
- }
-
- @Override
- public PosAndSize getPosition(StateGraph graph) {
- EObject container = graph.eContainer();
- String path = "#init";
- if(container instanceof StateGraphNode)
- path = FSMSupportUtil.getInstance().getFSMNameProvider().getFullPath((StateGraphNode)container) + path;
- Position pos = obj2pos.get(path);
-
- if (pos==null)
- return null;
-
- int margin = getMargin(graph);
- PosAndSize pt = new PosAndSize(
- (int) (pos.x * scaleX) + margin,
- (int) (pos.y * scaleY) + margin,
- (int) (pos.sx * scaleX),
- (int) (pos.sy * scaleY)
- );
- return pt;
- }
-
- public List<Pos> getPoints(Transition trans) {
- ArrayList<Pos> result = new ArrayList<Pos>();
-
- ArrayList<Position> list = trans2points.get(FSMSupportUtil.getInstance().getFSMNameProvider().getFullPath(trans));
- if (list!=null) {
- int i = 0;
- for (Position p : list) {
- Pos pos =
- new Pos(
- (int) (p.x * scaleX) + ((i==0)?0:posX),
- (int) (p.y * scaleY) + ((i==0)?0:posY)
- );
- result.add(pos);
- i++;
- }
- }
-
- return result;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.etrice.ui.behavior.support.IPositionProvider#getPositions(java.util.List)
- */
- @Override
- public <T extends StateGraphNode> List<PosAndSize> getPositions(List<T> nodes) {
- ArrayList<PosAndSize> result = new ArrayList<PosAndSize>(nodes.size());
-
- if (nodes.isEmpty())
- return result;
-
- int n = 0;
- for (T node : nodes) {
- PosAndSize pt = getPosition(node);
- result.add(pt);
- if (pt==null)
- n++;
- }
-
- int delta = (int) (scaleX/(n+1));
- int pos = delta;
-
- int h = StateGraphSupport.MARGIN;
- if (nodes.get(0) instanceof State)
- h = StateGraphSupport.MARGIN + StateGraphSupport.DEFAULT_SIZE_Y/4;
- else if (nodes.get(0) instanceof ChoicePoint)
- h = StateGraphSupport.MARGIN + StateGraphSupport.DEFAULT_SIZE_Y/2;
- else if (nodes.get(0) instanceof TrPoint)
- h = StateGraphSupport.MARGIN;
- else {
- assert(false): "unexpected sub type";
- }
-
- for (int i=0; i<nodes.size(); ++i) {
- if (result.get(i)==null) {
- PosAndSize pt = new PosAndSize(
- pos,
- h,
- 0,
- 0
- );
- result.set(i, pt);
-
- pos += delta;
- }
- }
-
- return result;
- }
-
- /**
- * Load base class diagrams recursively and put midpoint positions relative to boundary rectangle into map.
- *
- * Positions are relative to the invisible rectangle. They are transformed to the border rectangle and normalized.
- *
- * @param mc
- * @param obj2pos
- */
- private void mapPositions(ModelComponent mc, Injector injector) {
- if (mc==null)
- return;
-
- DiagramAccessBase diagramAccess = injector.getInstance(DiagramAccessBase.class);
- Diagram diagram = diagramAccess.getDiagram(mc);
- if (diagram==null)
- return;
-
- StateGraphContext tree = StateGraphContext.createContextTree(FSMSupportUtil.getInstance().getModelComponent(diagram), injector);
- FSMNameProvider fsmNameProvider = FSMSupportUtil.getInstance().getFSMNameProvider();
-
- ILinkService linkService = Graphiti.getLinkService();
- for (Shape sgShape : diagram.getChildren()) {
- // this is the level of StateGraphs
- if (sgShape instanceof ContainerShape) {
- EObject obj = linkService.getBusinessObjectForLinkedPictogramElement(sgShape);
- GraphicsAlgorithm borderRect = sgShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0);
- double width = borderRect.getWidth();
- double height = borderRect.getHeight();
- PosAndSize sz = new PosAndSize(
- sgShape.getGraphicsAlgorithm().getX(), sgShape.getGraphicsAlgorithm().getY(),
- borderRect.getWidth(), borderRect.getHeight());
- sg2sz.put(fsmNameProvider.getFullPath((StateGraph) obj), sz);
- for (Shape sgItemShape : ((ContainerShape)sgShape).getChildren()) {
- // this is the level of States, TrPoints and ChoicePoints
- obj = linkService.getBusinessObjectForLinkedPictogramElement(sgItemShape);
- GraphicsAlgorithm ga = sgItemShape.getGraphicsAlgorithm();
- if(ga==null)
- continue;
- int margin = 0;
- String path = null;
- if (obj instanceof StateGraphNode) {
- StateGraphNode node = (StateGraphNode)obj;
- margin = getMargin(node);
- path = fsmNameProvider.getFullPath((StateGraphItem) obj);
-
- if(sgItemShape instanceof ContainerShape){
- // sub items
- for(Shape childShape : ((ContainerShape)sgItemShape).getChildren()){
- EObject childObj = linkService.getBusinessObjectForLinkedPictogramElement(childShape);
- if(childObj instanceof StateGraphItem){
- GraphicsAlgorithm childGa = childShape.getGraphicsAlgorithm();
- String childPath = fsmNameProvider.getFullPath((StateGraphItem) childObj);
- if (childPath != null) {
- Position pos = new Position();
- pos.x = childGa.getX() / (double) (ga.getWidth() - 2 * margin);
- pos.y = childGa.getY() / (double) (ga.getHeight() - 2 * margin);
- pos.sx = -1;
- pos.sy = -1;
- subObj2pos.put(childPath, pos);
- }
- }
- }
- }
- } else if(obj instanceof StateGraph){
- StateGraph graph = (StateGraph)obj;
- margin = getMargin(graph);
- EObject container = graph.eContainer();
- path = "#init";
- if(container instanceof StateGraphNode)
- path = fsmNameProvider.getFullPath((StateGraphNode)container) + path;
- initialPointObj.put(path, graph);
- }
- if(path != null){
- Position pos = new Position();
- pos.x = ga.getX() / width;
- pos.y = ga.getY() / height;
- pos.sx = (ga.getWidth() - 2*margin) / width;
- pos.sy = (ga.getHeight()- 2*margin) / height;
- obj2pos.put(path, pos);
- }
-
- // Entry and Exit Points on State borders are treated by the insertion of the State
- }
- }
- }
-
- for (Connection conn : diagram.getConnections()) {
- EObject obj = linkService.getBusinessObjectForLinkedPictogramElement(conn);
- if (obj instanceof Transition) {
- ConnectionDecorator cd = conn.getConnectionDecorators().get(1);
- if (cd.getGraphicsAlgorithm() instanceof Text) {
- Transition trans = (Transition) obj;
- StateGraph sg = tree.getContext(trans).getStateGraph();
-
- // graph size
- PosAndSize sz = sg2sz.get(fsmNameProvider.getFullPath(sg));
- ArrayList<Position> points = new ArrayList<Position>();
- trans2points.put(fsmNameProvider.getFullPath((Transition) obj), points);
-
- // label position
- Position pos = new Position();
- pos.x = cd.getGraphicsAlgorithm().getX() / ((double)sz.getWidth());
- pos.y = cd.getGraphicsAlgorithm().getY() / ((double)sz.getHeight());
- points.add(pos);
-
- if (conn instanceof FreeFormConnection) {
- for (Point bp : ((FreeFormConnection) conn).getBendpoints()) {
- pos = new Position();
- pos.x = (bp.getX() - sz.getX()) / ((double)sz.getWidth());
- pos.y = (bp.getY() - sz.getY()) / ((double)sz.getHeight());
- points.add(pos);
- }
- }
- }
-
- }
- }
-
- // recursion
- mapPositions(mc.getBase(), injector);
- }
-
- private int getMargin(StateGraphNode node) {
- if (node instanceof State)
- return StateSupport.MARGIN;
- else if (node instanceof TrPoint)
- return TrPointSupport.MARGIN;
-
- return 0;
- }
-
- private int getMargin(StateGraph graph) {
- return 0;
- }
-
- public StateGraph getInitialPoint(StateGraph graph){
- EObject container = graph.eContainer();
- String path = "#init";
- if(container instanceof StateGraphNode)
- path = FSMSupportUtil.getInstance().getFSMNameProvider().getFullPath((StateGraphNode)container) + path;
- return initialPointObj.get(path);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.etrice.ui.behavior.support.IPositionProvider#getGraphSize(org.eclipse.etrice.core.room.StateGraph)
- */
- @Override
- public PosAndSize getGraphPosAndSize(StateGraph sg) {
- return sg2sz.get(FSMSupportUtil.getInstance().getFSMNameProvider().getFullPath(sg));
- }
-
- @Override
- public double[] getSubPosition(StateGraphNode subNode) {
- Position pos = subObj2pos.get(FSMSupportUtil.getInstance().getFSMNameProvider().getFullPath(subNode));
- if (pos==null)
- return null;
-
- return new double[]{pos.x, pos.y};
- }
-}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DiagramUpdateFeature.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DiagramUpdateFeature.java
index 860e53b2f..bf9b7ceab 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DiagramUpdateFeature.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/DiagramUpdateFeature.java
@@ -14,10 +14,12 @@ package org.eclipse.etrice.ui.behavior.fsm.support;
import java.util.ArrayList;
+import org.eclipse.etrice.core.fsm.fSM.FSMFactory;
import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
import org.eclipse.etrice.core.fsm.fSM.StateGraph;
-import org.eclipse.etrice.ui.behavior.fsm.commands.StateGraphContext;
-import org.eclipse.etrice.ui.behavior.fsm.provider.IInjectorProvider;
+import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMDiagramTypeProvider;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.DiagramEditingUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.IReason;
import org.eclipse.graphiti.features.IRemoveFeature;
@@ -33,8 +35,6 @@ import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.platform.IDiagramBehavior;
-import com.google.inject.Injector;
-
/**
* @author Henrik Rentz-Reichert (initial contribution)
*
@@ -63,9 +63,7 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature {
*/
@Override
public IReason updateNeeded(IUpdateContext context) {
- ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
- Injector injector = ((IInjectorProvider) getFeatureProvider()).getInjector();
- StateGraphContext tree = StateGraphContext.createContextTree(mc, injector);
+ IStateGraphContext tree = createStateGraphContext();
usedShapes.clear();
@@ -108,9 +106,7 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature {
*/
@Override
public boolean update(IUpdateContext context) {
- ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
- Injector injector = ((IInjectorProvider) getFeatureProvider()).getInjector();
- StateGraphContext tree = StateGraphContext.createContextTree(mc, injector);
+ IStateGraphContext tree = createStateGraphContext();
StateGraph currentStateGraph = ContextSwitcher.getCurrentStateGraph(getDiagram());
@@ -169,7 +165,7 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature {
* @param ctx
* @return
*/
- private IReason updateNeeded(StateGraphContext ctx) {
+ private IReason updateNeeded(IStateGraphContext ctx) {
StateGraph sg = ctx.getStateGraph();
ContainerShape cont = findStateGraphContainer(sg);
if (cont==null)
@@ -196,7 +192,7 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature {
}
// recursion
- for (StateGraphContext child : ctx.getChildren()) {
+ for (IStateGraphContext child : ctx.getChildren()) {
IReason needUpdate = updateNeeded(child);
if (needUpdate.toBoolean())
return needUpdate;
@@ -209,14 +205,14 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature {
* @param ctx
* @return
*/
- private boolean update(StateGraphContext ctx) {
+ private boolean update(IStateGraphContext ctx) {
boolean changed = false;
StateGraph sg = ctx.getStateGraph();
ContainerShape cont = findStateGraphContainer(sg);
if (cont==null) {
// create
- cont = FSMSupportUtil.getInstance().addStateGraph(ctx, getDiagram(), getFeatureProvider());
+ cont = DiagramEditingUtil.getInstance().addStateGraph(ctx, getDiagram(), getFeatureProvider());
changed = true;
usedShapes.add(cont);
}
@@ -242,7 +238,7 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature {
}
// recursion
- for (StateGraphContext child : ctx.getChildren()) {
+ for (IStateGraphContext child : ctx.getChildren()) {
if (update(child))
changed = true;
}
@@ -262,5 +258,20 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature {
}
return null;
}
+
+ private IStateGraphContext createStateGraphContext(){
+ ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
+// Injector injector = ((IInjectorProvider) getFeatureProvider()).getInjector();
+// StateGraphContext tree = StateGraphContext.createContextTree(mc, injector);
+
+ // side effect on model, but diagram needs that for initial graph shape
+ if(mc.getStateMachine() == null || mc.getStateMachine().eIsProxy()){
+ mc.setStateMachine(FSMFactory.eINSTANCE.createStateGraph());
+ }
+
+ IStateGraphContext tree = new GenModelStateGraphContext((AbstractFSMDiagramTypeProvider)getFeatureProvider().getDiagramTypeProvider());
+
+ return tree;
+ }
}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/FSMSupportUtil.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/FSMSupportUtil.java
deleted file mode 100644
index 999b607e6..000000000
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/FSMSupportUtil.java
+++ /dev/null
@@ -1,997 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014 protos software gmbh (http://www.protos.de).
- * 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:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.ui.behavior.fsm.support;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.etrice.core.fsm.fSM.ChoicePoint;
-import org.eclipse.etrice.core.fsm.fSM.ChoicepointTerminal;
-import org.eclipse.etrice.core.fsm.fSM.EntryPoint;
-import org.eclipse.etrice.core.fsm.fSM.ExitPoint;
-import org.eclipse.etrice.core.fsm.fSM.FSMFactory;
-import org.eclipse.etrice.core.fsm.fSM.InitialTransition;
-import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
-import org.eclipse.etrice.core.fsm.fSM.NonInitialTransition;
-import org.eclipse.etrice.core.fsm.fSM.RefinedState;
-import org.eclipse.etrice.core.fsm.fSM.RefinedTransition;
-import org.eclipse.etrice.core.fsm.fSM.State;
-import org.eclipse.etrice.core.fsm.fSM.StateGraph;
-import org.eclipse.etrice.core.fsm.fSM.StateGraphItem;
-import org.eclipse.etrice.core.fsm.fSM.StateGraphNode;
-import org.eclipse.etrice.core.fsm.fSM.StateTerminal;
-import org.eclipse.etrice.core.fsm.fSM.SubStateTrPointTerminal;
-import org.eclipse.etrice.core.fsm.fSM.TrPoint;
-import org.eclipse.etrice.core.fsm.fSM.TrPointTerminal;
-import org.eclipse.etrice.core.fsm.fSM.Transition;
-import org.eclipse.etrice.core.fsm.fSM.TransitionTerminal;
-import org.eclipse.etrice.core.fsm.naming.FSMNameProvider;
-import org.eclipse.etrice.core.fsm.ui.FSMUiModule;
-import org.eclipse.etrice.core.fsm.util.FSMHelpers;
-import org.eclipse.etrice.core.fsm.util.FSMNewNamingUtil;
-import org.eclipse.etrice.core.fsm.validation.FSMValidationUtil;
-import org.eclipse.etrice.ui.behavior.fsm.commands.StateGraphContext;
-import org.eclipse.etrice.ui.behavior.fsm.support.IPositionProvider.Pos;
-import org.eclipse.etrice.ui.behavior.fsm.support.IPositionProvider.PosAndSize;
-import org.eclipse.etrice.ui.common.base.support.CommonSupportUtil;
-import org.eclipse.graphiti.datatypes.ILocation;
-import org.eclipse.graphiti.features.IFeatureProvider;
-import org.eclipse.graphiti.features.IRemoveFeature;
-import org.eclipse.graphiti.features.context.IRemoveContext;
-import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
-import org.eclipse.graphiti.features.context.impl.AddContext;
-import org.eclipse.graphiti.features.context.impl.LayoutContext;
-import org.eclipse.graphiti.features.context.impl.RemoveContext;
-import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
-import org.eclipse.graphiti.mm.algorithms.styles.Point;
-import org.eclipse.graphiti.mm.pictograms.Anchor;
-import org.eclipse.graphiti.mm.pictograms.Connection;
-import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
-import org.eclipse.graphiti.mm.pictograms.ContainerShape;
-import org.eclipse.graphiti.mm.pictograms.Diagram;
-import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
-import org.eclipse.graphiti.mm.pictograms.PictogramElement;
-import org.eclipse.graphiti.mm.pictograms.Shape;
-import org.eclipse.graphiti.services.Graphiti;
-import org.eclipse.graphiti.services.IGaService;
-import org.eclipse.graphiti.services.ILinkService;
-
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-
-/**
- * @author Henrik Rentz-Reichert
- *
- */
-public class FSMSupportUtil {
-
- private static final String INITIAL = "init";
- private static final String STATE = "state:";
- private static final String TP = "tp:";
- private static final String CP = "cp:";
- private static final String SEP = ".";
- private static FSMSupportUtil instance = null;
-
- /**
- * @return the instance
- */
- public static FSMSupportUtil getInstance() {
- if (instance==null) {
- // this class has members that have to be filled by the FSMUi injector
- Injector injector = FSMUiModule.getInjector();
- instance = injector.getInstance(FSMSupportUtil.class);
- }
- return instance;
- }
-
- @Inject
- private FSMHelpers fsmHelpers;
- @Inject
- private FSMValidationUtil fsmValidationUtil;
- @Inject
- private FSMNameProvider fsmNameProvider;
- @Inject
- private FSMNewNamingUtil fsmNewNamingUtil;
-
- /**
- * @return the roomHelpers
- */
- public FSMHelpers getFSMHelpers() {
- return fsmHelpers;
- }
-
- /**
- * @return the validationUtil
- */
- public FSMValidationUtil getFSMValidationUtil() {
- return fsmValidationUtil;
- }
-
- /**
- * @return the roomUtil
- */
- public FSMNewNamingUtil getFSMNewNamingUtil() {
- return fsmNewNamingUtil;
- }
-
- /**
- * @return the roomNameProvider
- */
- public FSMNameProvider getFSMNameProvider() {
- return fsmNameProvider;
- }
-
- public EObject getOwnObject(EObject obj, ResourceSet rs) {
- URI uri = EcoreUtil.getURI(obj);
- EObject own = rs.getEObject(uri, true);
- assert(own!=null): "own object must exist";
- return own;
- }
-
- public boolean isInherited(Diagram diag, EObject obj) {
- if(obj instanceof StateGraph)
- obj = obj.eContainer();
- else if (obj instanceof ModelComponent)
- return ((ModelComponent) obj).getBase() != null;
-
- return obj instanceof RefinedState || obj instanceof RefinedTransition || !EcoreUtil.isAncestor(getModelComponent(diag), obj);
- }
-
- public boolean showAsInherited(Diagram diag, State obj) {
-
- if (obj instanceof RefinedState)
- return true;
-
- return fsmHelpers.getModelComponent(obj)!=getModelComponent(diag);
- }
-
- public Diagram getDiagram(GraphicsAlgorithm ga) {
- if (ga.eContainer() instanceof GraphicsAlgorithm)
- return getDiagram((GraphicsAlgorithm)ga.eContainer());
- return getDiagram(ga.getPictogramElement());
- }
-
- /**
- * @param pictogramElement
- * @return
- */
- public Diagram getDiagram(PictogramElement pe) {
- while (pe.eContainer()!=null) {
- if (pe.eContainer() instanceof Diagram)
- return (Diagram) pe.eContainer();
- pe = (PictogramElement) pe.eContainer();
- }
- return null;
- }
-
- public ModelComponent getModelComponent(Diagram diag) {
- EObject bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(diag);
- if (bo instanceof ModelComponent)
- return (ModelComponent) bo;
- return null;
- }
-
- /**
- * @param sg
- * @param mc
- * @param targetContainer
- * @param fp
- * @return
- */
- public StateGraph insertRefinedState(StateGraph sg, ModelComponent mc, ContainerShape targetContainer,
- IFeatureProvider fp) {
- sg = getSubGraphOfRefinedStateFor((State) sg.eContainer(), mc);
- fp.link(targetContainer, sg);
- return sg;
- }
-
- /**
- * @param sg
- * @param mc
- * @param targetContainer
- */
- public void undoInsertRefinedState(StateGraph sg, ModelComponent mc,
- ContainerShape targetContainer, IFeatureProvider fp) {
- RefinedState rs = (RefinedState) sg.eContainer();
- fp.link(targetContainer, rs.getTarget().getSubgraph());
-
- if (!(fsmHelpers.hasDetailCode(rs.getEntryCode()) || fsmHelpers.hasDetailCode(rs.getExitCode()))) {
- mc.getStateMachine().getStates().remove(rs);
- }
- }
-
- /**
- * @param s
- * @param mc
- * @return
- */
- public StateGraph getSubGraphOfRefinedStateFor(State s, ModelComponent mc) {
- RefinedState rs = getRefinedStateFor(s, mc);
-
- if (rs.getSubgraph()==null)
- rs.setSubgraph(FSMFactory.eINSTANCE.createStateGraph());
-
- return rs.getSubgraph();
- }
-
- public RefinedState getRefinedStateFor(State s, ModelComponent mc) {
- HashMap<State, RefinedState> target2rs = new HashMap<State, RefinedState>();
- for (State st : mc.getStateMachine().getStates()) {
- if (st instanceof RefinedState)
- target2rs.put(((RefinedState) st).getTarget(), (RefinedState) st);
- }
-
- RefinedState rs = null;
-
- // do we already have a RefinedState pointing to s?
- if (target2rs.containsKey(s)) {
- rs = target2rs.get(s);
- }
- else {
- // we have to create one and place it in the best fitting context
- StateGraph sg = null;
- State parent = s;
- while (parent.eContainer().eContainer() instanceof State) {
- parent = (State) s.eContainer().eContainer();
- if (target2rs.containsKey(parent)) {
- RefinedState bestFitting = target2rs.get(parent);
- if (bestFitting.getSubgraph()==null)
- bestFitting.setSubgraph(FSMFactory.eINSTANCE.createStateGraph());
- sg = bestFitting.getSubgraph();
- break;
- }
- }
-
- if (sg==null)
- sg = mc.getStateMachine();
-
- rs = FSMFactory.eINSTANCE.createRefinedState();
- rs.setTarget(s);
- sg.getStates().add(rs);
- }
- return rs;
- }
-
- /**
- * @param state
- * @param diagram
- * @return
- */
- public State getTargettingState(State state, Diagram diagram) {
- ModelComponent mc = getModelComponent(diagram);
- return fsmHelpers.getTargettingState(state, mc);
- }
-
- /**
- * This method exploits the fact that the immediate children of the diagram are
- * associated with the state graphs.
- *
- * @param shape
- * @return the container shape that is associated with the state graph of the diagram
- */
- public ContainerShape getStateGraphContainer(ContainerShape shape) {
- while (shape!=null) {
- ContainerShape parent = shape.getContainer();
- if (parent instanceof Diagram)
- return shape;
- shape = parent;
- }
- return null;
- }
-
- public StateGraph getStateGraph(ContainerShape cs, IFeatureProvider fp) {
- ContainerShape shape = getStateGraphContainer(cs);
- Object bo = fp.getBusinessObjectForPictogramElement(shape);
- if (bo instanceof StateGraph)
- return (StateGraph) bo;
- else
- assert(false): "state graph expected";
-
- return null;
- }
-
- public TransitionTerminal getTransitionTerminal(Anchor anchor, IFeatureProvider fp) {
- if (anchor != null) {
- Object obj = fp.getBusinessObjectForPictogramElement(anchor.getParent());
- if (obj instanceof TrPoint) {
- Object parent = fp.getBusinessObjectForPictogramElement((ContainerShape) anchor.getParent().eContainer());
- if (parent instanceof State) {
- State state = (parent instanceof RefinedState)? ((RefinedState)parent).getTarget() : (State)parent;
- SubStateTrPointTerminal sstpt = FSMFactory.eINSTANCE.createSubStateTrPointTerminal();
- sstpt.setState(state);
- sstpt.setTrPoint((TrPoint) obj);
- return sstpt;
- }
- else {
- TrPointTerminal tpt = FSMFactory.eINSTANCE.createTrPointTerminal();
- tpt.setTrPoint((TrPoint) obj);
- return tpt;
- }
- }
- else if (obj instanceof State) {
- State state = (obj instanceof RefinedState)? ((RefinedState)obj).getTarget() : (State)obj;
- StateTerminal st = FSMFactory.eINSTANCE.createStateTerminal();
- st.setState(state);
- return st;
- }
- else if (obj instanceof ChoicePoint) {
- ChoicepointTerminal ct = FSMFactory.eINSTANCE.createChoicepointTerminal();
- ct.setCp((ChoicePoint) obj);
- return ct;
- }
- }
- return null;
- }
-
- public boolean isInitialPoint(Anchor anchor, IFeatureProvider fp) {
- if (anchor!=null) {
- Object obj = fp.getBusinessObjectForPictogramElement(anchor.getParent());
- if (obj instanceof StateGraph) {
- Object parent = fp.getBusinessObjectForPictogramElement((ContainerShape) anchor.getParent().eContainer());
- if (parent instanceof StateGraph)
- return true;
- }
- }
- return false;
- }
-
- public boolean canConnect(Anchor asrc, Anchor atgt, ContainerShape cs, IFeatureProvider fp) {
- return canConnect(asrc, atgt, null, cs, fp);
- }
-
- public boolean canConnect(Anchor asrc, Anchor atgt, Transition trans,
- ContainerShape cs, IFeatureProvider fp) {
- TransitionTerminal src = getTransitionTerminal(asrc, fp);
- TransitionTerminal tgt = getTransitionTerminal(atgt, fp);
-
- if (src==null && !isInitialPoint(asrc, fp))
- return false;
- if (tgt==null)
- return false;
-
- StateGraph sg = getStateGraph(cs, fp);
- if (sg==null)
- return false;
-
- return fsmValidationUtil.isConnectable(src, tgt, trans, sg).isOk();
- }
-
- /**
- * @param s the state whose sub structure should be deleted
- * @param mc the ModelComponent
- * @param diagram the current diagram
- * @param fp the feature provider
- */
- public void deleteSubStructureRecursive(State s, ModelComponent mc,
- Diagram diagram, IFeatureProvider fp) {
- if (fsmHelpers.hasSubStructure(s, mc)) {
- StateGraph subgraph = s.getSubgraph();
-
- // depth first
- for (State st : subgraph.getStates()) {
- deleteSubStructureRecursive(st, mc, diagram, fp);
- }
-
- ContainerShape subShape = ContextSwitcher.getContext(diagram, subgraph);
- CommonSupportUtil.deleteConnectionsRecursive(subShape, fp);
- EcoreUtil.delete(subShape, true);
- }
- }
-
- public List<State> getStates(ContainerShape shape, IFeatureProvider fp) {
- return getStates(shape, fp, null, null);
- }
-
- private List<State> getStates(ContainerShape shape, IFeatureProvider fp, Map<String, Anchor> item2anchor, List<Shape> stateShapes) {
- List<State> items = new ArrayList<State>();
- for (Shape ch : shape.getChildren()) {
- Object bo = fp.getBusinessObjectForPictogramElement(ch);
- if (bo instanceof State) {
- items.add((State)bo);
- if (item2anchor!=null)
- item2anchor.put(getKey((State)bo), ch.getAnchors().get(0));
- if (stateShapes!=null)
- stateShapes.add(ch);
- }
- }
- return items;
- }
-
- public List<ChoicePoint> getChoicePoints(ContainerShape shape, IFeatureProvider fp) {
- return getChoicePoints(shape, fp, null, null);
- }
-
- private List<ChoicePoint> getChoicePoints(ContainerShape shape, IFeatureProvider fp, Map<String, Anchor> item2anchor,
- List<Shape> cpShapes) {
- List<ChoicePoint> items = new ArrayList<ChoicePoint>();
- for (Shape ch : shape.getChildren()) {
- Object bo = fp.getBusinessObjectForPictogramElement(ch);
- if (bo instanceof ChoicePoint) {
- items.add((ChoicePoint)bo);
- if (item2anchor!=null)
- item2anchor.put(getKey((ChoicePoint)bo), ch.getAnchors().get(0));
- if (cpShapes!=null)
- cpShapes.add(ch);
- }
- }
- return items;
- }
-
- public List<TrPoint> getTrPoints(StateGraph sg, ContainerShape shape, IFeatureProvider fp) {
- return getTrPoints(sg, shape, fp, null, null);
- }
-
- private List<TrPoint> getTrPoints(StateGraph sg, ContainerShape shape, IFeatureProvider fp,
- Map<String, Anchor> item2anchor, List<Shape> tpShapes) {
- List<TrPoint> items = new ArrayList<TrPoint>();
- for (Shape ch : shape.getChildren()) {
- Object bo = fp.getBusinessObjectForPictogramElement(ch);
- if (bo instanceof TrPoint) {
- items.add((TrPoint)bo);
- if (item2anchor!=null)
- item2anchor.put(getKey((TrPoint)bo), ch.getAnchors().get(0));
- if (tpShapes!=null)
- tpShapes.add(ch);
- }
- }
- return items;
- }
-
- /**
- * @param diagram
- * @param fp
- * @return
- */
- public List<Transition> getTransitions(Diagram diagram, IFeatureProvider fp) {
- List<Transition> transitions = new ArrayList<Transition>();
- for (Connection conn : diagram.getConnections()) {
- Object bo = fp.getBusinessObjectForPictogramElement(conn);
- if (bo instanceof Transition)
- transitions.add((Transition) bo);
- }
- return transitions;
- }
-
- private Map<Transition, Connection> getTransitionsMap(ContainerShape sgShape, IFeatureProvider fp) {
- Diagram diagram = (Diagram) sgShape.eContainer();
- Map<Transition, Connection> transitions = new HashMap<Transition, Connection>();
- for (Connection conn : diagram.getConnections()) {
- Object bo = fp.getBusinessObjectForPictogramElement(conn);
-
- // we only collect connections that have a starting point contained in our sgShape
- if (bo instanceof Transition && EcoreUtil.isAncestor(sgShape, conn.getStart()))
- transitions.put((Transition) bo, conn);
- }
- return transitions;
- }
-
- /**
- * @param sgShape
- * @param node2anchor
- */
- private void getSubTpAnchors(ContainerShape sgShape, HashMap<String, Anchor> node2anchor) {
- for (Shape childShape : sgShape.getChildren()) {
- EObject bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(childShape);
- if (bo instanceof State)
- getAnchors((State) bo, childShape, node2anchor);
- }
- }
-
- public ContainerShape addStateGraph(StateGraphContext ctx, Diagram diagram, IFeatureProvider fp) {
- AddContext addContext = new AddContext();
- addContext.setNewObject(ctx.getStateGraph());
- addContext.setTargetContainer(diagram);
- PosAndSize graphPosAndSize = ctx.getPositionProvider().getGraphPosAndSize(ctx.getStateGraph());
- if (graphPosAndSize!=null) {
- addContext.setX(graphPosAndSize.getX());
- addContext.setY(graphPosAndSize.getY());
- addContext.setWidth(graphPosAndSize.getWidth());
- addContext.setHeight(graphPosAndSize.getHeight());
- }
- else {
- addContext.setX(StateGraphSupport.MARGIN);
- addContext.setY(StateGraphSupport.MARGIN);
- }
-
- ContainerShape sgShape = (ContainerShape) fp.addIfPossible(addContext);
- if (sgShape==null)
- return null;
-
- final HashMap<String, Anchor> node2anchor = new HashMap<String, Anchor>();
-
- GraphicsAlgorithm borderRect = sgShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0);
- ctx.getPositionProvider().setScale(borderRect.getWidth(), borderRect.getHeight());
- ctx.getPositionProvider().setPosition(sgShape.getGraphicsAlgorithm().getX(), sgShape.getGraphicsAlgorithm().getY());
-
- addInitialPointIff(ctx, ctx.getPositionProvider(), sgShape, fp, node2anchor);
- addStateGraphNodes(ctx.getTrPoints(), ctx.getPositionProvider(), sgShape, fp, node2anchor);
- addStateGraphNodes(ctx.getStates(), ctx.getPositionProvider(), sgShape, fp, node2anchor);
- addStateGraphNodes(ctx.getChPoints(), ctx.getPositionProvider(), sgShape, fp, node2anchor);
-
- for (StateGraphContext sub : ctx.getChildren()) {
- addStateGraph(sub, diagram, fp);
- }
-
- getSubTpAnchors(sgShape, node2anchor);
-
- addTransitions(ctx.getTransitions(), ctx.getPositionProvider(), sgShape, fp, node2anchor);
-
- return sgShape;
- }
-
- private void addInitialPointIff(StateGraphContext ctx, IPositionProvider positionProvider, ContainerShape sgShape,
- IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
-
- // model
- StateGraph sg = ctx.getInitialPoint();
- if(sg==null)
- // (super class) diagram
- sg = positionProvider.getInitialPoint(ctx.getStateGraph());
- if(sg==null)
- return;
-
- PosAndSize pos = positionProvider.getPosition(sg);
- AddContext addContext = new AddContext();
- addContext.setNewObject(sg);
- addContext.setTargetContainer(sgShape);
- if(pos != null){
- addContext.setX(pos.getX());
- addContext.setY(pos.getY());
- if (pos.getWidth()>0 && pos.getHeight()>0) {
- addContext.setWidth(pos.getWidth());
- addContext.setHeight(pos.getHeight());
- }
- } else {
- addContext.setX(3*StateGraphSupport.MARGIN);
- addContext.setY(3*StateGraphSupport.MARGIN);
- }
-
- ContainerShape pe = (ContainerShape) fp.addIfPossible(addContext);
- assert(pe!=null): "initial point should have been created";
- assert(!pe.getAnchors().isEmpty()): "initial point should have an anchor";
- node2anchor.put(INITIAL, pe.getAnchors().get(0));
- }
-
- public void updateStateGraph(StateGraph sg, StateGraphContext ctx, ContainerShape sgShape,
- IFeatureProvider fp) {
-
- HashMap<String, Anchor> node2anchor = new HashMap<String, Anchor>();
-
- GraphicsAlgorithm borderRect = sgShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0);
- ctx.getPositionProvider().setScale(borderRect.getWidth(), borderRect.getHeight());
- ctx.getPositionProvider().setPosition(sgShape.getGraphicsAlgorithm().getX(), sgShape.getGraphicsAlgorithm().getY());
-
- // states
- {
- ArrayList<Shape> shapes = new ArrayList<Shape>();
- List<State> present = getStates(sgShape, fp, node2anchor, shapes);
- checkDuplicates(present);
- List<State> expected = ctx.getStates();
- List<State> toAdd = new ArrayList<State>();
- List<State> toUpdate = new ArrayList<State>();
- List<State> toRemove = new ArrayList<State>();
- for (State item : expected) {
- if (present.contains(item))
- toUpdate.add(item);
- else
- toAdd.add(item);
- }
- for(State item : present){
- if(!expected.contains(item))
- toRemove.add(item);
- }
- addStateGraphNodes(toAdd, ctx.getPositionProvider(), sgShape, fp, node2anchor);
- updateStateGraphNodes(toUpdate, shapes, ctx.getPositionProvider(), fp);
- removeGraphicalRepresentation(toRemove, shapes, fp);
- }
-
- // transition points
- {
- ArrayList<Shape> shapes = new ArrayList<Shape>();
- List<TrPoint> present = getTrPoints(sg, sgShape, fp, node2anchor, shapes);
- checkDuplicates(present);
- List<TrPoint> expected = ctx.getTrPoints();
- List<TrPoint> toAdd = new ArrayList<TrPoint>();
- List<TrPoint> toUpdate = new ArrayList<TrPoint>();
- List<TrPoint> toRemove = new ArrayList<TrPoint>();
- for (TrPoint item : expected) {
- if (present.contains(item))
- toUpdate.add(item);
- else
- toAdd.add(item);
- }
- for(TrPoint item : present){
- if(!expected.contains(item))
- toRemove.add(item);
- }
- addStateGraphNodes(toAdd, ctx.getPositionProvider(), sgShape, fp, node2anchor);
- updateStateGraphNodes(toUpdate, shapes, ctx.getPositionProvider(), fp);
- removeGraphicalRepresentation(toRemove, shapes, fp);
- }
-
- // choice points
- {
- ArrayList<Shape> shapes = new ArrayList<Shape>();
- List<ChoicePoint> present = getChoicePoints(sgShape, fp, node2anchor, shapes);
- checkDuplicates(present);
- List<ChoicePoint> expected = ctx.getChPoints();
- List<ChoicePoint> toAdd = new ArrayList<ChoicePoint>();
- List<ChoicePoint> toUpdate = new ArrayList<ChoicePoint>();
- List<ChoicePoint> toRemove = new ArrayList<ChoicePoint>();
- for (ChoicePoint item : expected) {
- if (present.contains(item))
- toUpdate.add(item);
- else
- toAdd.add(item);
- }
- for(ChoicePoint item : present){
- if(!expected.contains(item))
- toRemove.add(item);
- }
- addStateGraphNodes(toAdd, ctx.getPositionProvider(), sgShape, fp, node2anchor);
- updateStateGraphNodes(toUpdate, shapes, ctx.getPositionProvider(), fp);
- removeGraphicalRepresentation(toRemove, shapes, fp);
- }
-
- getSubTpAnchors(sgShape, node2anchor);
-
- // initial point
- {
- // exists in this diagram ?
- Shape present = null;
- for (Shape ch : sgShape.getChildren()) {
- Object bo = fp.getBusinessObjectForPictogramElement(ch);
- if (bo instanceof StateGraph)
- present = ch;
- }
- if(present != null)
- node2anchor.put(INITIAL, present.getAnchors().get(0));
- // exists in model ?
- StateGraph expected = ctx.getInitialPoint();
- if(expected == null)
- // exists in (super class) diagram ?
- expected = ctx.getPositionProvider().getInitialPoint(ctx.getStateGraph());
- if(expected != null && present == null)
- addInitialPointIff(ctx, ctx.getPositionProvider(), sgShape, fp, node2anchor);
- else
- updateInitialPoint(present, ctx.getPositionProvider(), fp);
- }
-
- // transitions
- {
- // get transitions that belong to our state graph
- // (for other connections we might not have the node anchors yet)
- Map<Transition, Connection> present = getTransitionsMap(sgShape, fp);
- List<Transition> expected = ctx.getTransitions();
- List<Transition> toAdd = new ArrayList<Transition>();
- List<Transition> toRemove = new ArrayList<Transition>();
- for (Transition trans : expected)
- if (!present.containsKey(trans))
- toAdd.add(trans);
- for(Transition item : present.keySet()){
- if(!expected.contains(item))
- toRemove.add(item);
- }
- addTransitions(toAdd, ctx.getPositionProvider(), sgShape, fp, node2anchor);
- updateTransitions(present, ctx.getPositionProvider(), sgShape, fp, node2anchor);
- removeGraphicalRepresentation(toRemove, present.values(), fp);
- }
- }
-
- /**
- * @param items
- */
- private void checkDuplicates(List<? extends StateGraphItem> items) {
- for (StateGraphItem item : items) {
- if (items.indexOf(item)!=items.lastIndexOf(item)) {
- Assert.isTrue(
- items.indexOf(item)==items.lastIndexOf(item),
- "multiple occurrences of "+fsmNameProvider.getFullPath(item));
- }
- }
- }
-
- private void addTransitions(List<Transition> transitions, IPositionProvider positionProvider, ContainerShape sgShape,
- IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
-
- for (Transition trans : transitions) {
- String from = (trans instanceof InitialTransition)? INITIAL:getKey(((NonInitialTransition)trans).getFrom());
- String to = getKey(trans.getTo());
- Anchor src = node2anchor.get(from);
- Anchor dst = node2anchor.get(to);
-
- assert(src!=null && dst!=null): "transition endpoints must be present";
-
- AddConnectionContext context = new AddConnectionContext(src, dst);
- context.setNewObject(trans);
- PictogramElement pe = fp.addIfPossible(context);
- if (pe instanceof FreeFormConnection) {
- FreeFormConnection conn = (FreeFormConnection) pe;
-
- // JH: workaround for correct bend points of inherited self transition
- conn.getBendpoints().clear();
-
- List<Pos> points = positionProvider.getPoints(trans);
- if (points!=null && !points.isEmpty()) {
- Iterator<Pos> it = points.iterator();
-
- // first is label position
- Pos pos = it.next();
- ConnectionDecorator cd = conn.getConnectionDecorators().get(1);
- Graphiti.getGaService().setLocation(cd.getGraphicsAlgorithm(), pos.getX(), pos.getY());
-
- // remaining are bend points
- while (it.hasNext()) {
- pos = it.next();
- Point pt = Graphiti.getGaService().createPoint(pos.getX(), pos.getY());
- conn.getBendpoints().add(pt);
- }
- }
- else if (src==dst) {
- ILocation begin = Graphiti.getPeService().getLocationRelativeToDiagram(conn.getStart());
- Point pt = Graphiti.getGaService().createPoint(begin.getX(), begin.getY()+StateGraphSupport.MARGIN*3);
- conn.getBendpoints().add(pt);
- }
- }
- }
- }
-
- private void addStateGraphNodes(List<? extends StateGraphNode> nodes, IPositionProvider positionProvider, ContainerShape sgShape,
- IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
-
- List<PosAndSize> positions = positionProvider.getPositions(nodes);
-
- int idx = 0;
- for (StateGraphNode node : nodes) {
- addStateGraphNode(node, sgShape, positions.get(idx), fp, node2anchor);
- ++idx;
- }
- }
-
- private void addStateGraphNode(StateGraphNode tp, ContainerShape sgShape, PosAndSize pos,
- IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
- AddContext addContext = new AddContext();
- addContext.setNewObject(tp);
- addContext.setTargetContainer(sgShape);
- addContext.setX(pos.getX());
- addContext.setY(pos.getY());
- if (pos.getWidth()>0 && pos.getHeight()>0) {
- addContext.setWidth(pos.getWidth());
- addContext.setHeight(pos.getHeight());
- }
-
- ContainerShape pe = (ContainerShape) fp.addIfPossible(addContext);
- assert(pe!=null): tp.eClass().getName()+" should have been created";
- assert(!pe.getAnchors().isEmpty()): tp.eClass().getName()+" should have an anchor";
- node2anchor.put(getKey(tp), pe.getAnchors().get(0));
- }
-
- private void updateInitialPoint(Shape shape, IPositionProvider positionProvider, IFeatureProvider fp) {
- if (shape==null)
- return;
-
- StateGraph sg = (StateGraph) fp.getBusinessObjectForPictogramElement(shape);
- PosAndSize ps = positionProvider.getPosition(sg);
- if (ps==null)
- return;
-
- // relocate and resize the invisible rectangle
- GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
-
- Graphiti.getLayoutService().setLocationAndSize(
- ga,
- ps.getX(),
- ps.getY(),
- ps.getWidth(),
- ps.getHeight()
- );
-
- // have to call the layout to adjust the visible border
- LayoutContext lc = new LayoutContext(shape);
- fp.layoutIfPossible(lc);
- }
-
- private void updateStateGraphNodes(List<? extends StateGraphNode> nodes, List<Shape> shapes,
- IPositionProvider positionProvider, IFeatureProvider fp) {
-
- ILinkService linkService = Graphiti.getLinkService();
- IGaService gaService = Graphiti.getGaService();
-
- for (StateGraphNode node : nodes) {
- PosAndSize ps = positionProvider.getPosition(node);
- if (ps==null)
- continue;
-
- // TODO: sub-optimal since quadratic effort - use combined list for nodes and shapes or similar solution
- for (Shape shape : shapes) {
- EObject bo = linkService.getBusinessObjectForLinkedPictogramElement(shape);
- if (bo==node) {
- // relocate and resize the invisible rectangle
- GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
-// System.out.println(node + ": "+ga.getX()+" "+ga.getY()+" "+ga.getWidth()+" "+ga.getHeight());
-// System.out.println(" -> "+ps.getX()+" "+ps.getY()+" "+ps.getWidth()+" "+ps.getHeight());
-
- int margin = 0;
- if (node instanceof State)
- margin = StateSupport.MARGIN;
- else if (node instanceof TrPoint)
- margin = TrPointSupport.MARGIN;
-
- gaService.setLocationAndSize(
- ga,
- ps.getX()-margin,
- ps.getY()-margin,
- ps.getWidth()+2*margin,
- ps.getHeight()+2*margin
- );
-
- // have to call the layout to adjust the visible border
- LayoutContext lc = new LayoutContext(shape);
- fp.layoutIfPossible(lc);
-
- // update position of sub items
- if(shape instanceof ContainerShape){
- ContainerShape container = (ContainerShape) shape;
- for(Shape child : container.getChildren()){
- EObject childBo = linkService.getBusinessObjectForLinkedPictogramElement(child);
- if(!(childBo instanceof StateGraphNode))
- continue;
-
- double[] relPos = positionProvider.getSubPosition((StateGraphNode) childBo);
- if(relPos != null)
- gaService.setLocation(child.getGraphicsAlgorithm(), (int)(relPos[0] * ps.getWidth()), (int)(relPos[1]*ps.getHeight()));
- }
- }
-
- break;
- }
- }
- }
- }
-
- public void removeGraphicalRepresentation(Collection<? extends EObject> toRemove, Collection<? extends PictogramElement> pictograms, IFeatureProvider fp) {
- for(EObject bo : toRemove)
- for(PictogramElement pe : pictograms)
- if(fp.getBusinessObjectForPictogramElement(pe) == bo){
- IRemoveContext rc = new RemoveContext(pe);
- IRemoveFeature removeFeature = fp.getRemoveFeature(rc);
- if (removeFeature != null)
- removeFeature.remove(rc);
- break;
- }
- }
-
- private void updateTransitions(Map<Transition, Connection> transitions, IPositionProvider positionProvider, ContainerShape sgShape,
- IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
-
- for(Entry<Transition, Connection> e: transitions.entrySet()){
- Transition trans = e.getKey();
- Connection conn = e.getValue();
-
- String from = (trans instanceof InitialTransition)? INITIAL:getKey(((NonInitialTransition)trans).getFrom());
- String to = getKey(trans.getTo());
- Anchor newSrc = node2anchor.get(from);
- Anchor newDst = node2anchor.get(to);
-
- assert(newSrc!=null && newDst!=null): "transition endpoints must be present";
-
- if(conn.getStart()!=newSrc)
- conn.setStart(newSrc);
- if(conn.getEnd()!=newDst)
- conn.setEnd(newDst);
-
- List<Pos> points = positionProvider.getPoints(trans);
- Iterator<Pos> it = points.iterator();
- if (points==null || points.isEmpty())
- continue;
-
- // first is label position
- Pos pos = it.next();
- ConnectionDecorator cd = conn.getConnectionDecorators().get(1);
- Graphiti.getGaService().setLocation(cd.getGraphicsAlgorithm(), pos.getX(), pos.getY());
-
- if (conn instanceof FreeFormConnection) {
- FreeFormConnection fconn = (FreeFormConnection) conn;
-
- // remaining are bend points
- fconn.getBendpoints().clear();
- List<Point> bendpoints = new ArrayList<Point>();
- while (it.hasNext()) {
- pos = it.next();
- Point pt = Graphiti.getGaService().createPoint(pos.getX(), pos.getY());
- bendpoints.add(pt);
- }
- fconn.getBendpoints().addAll(bendpoints);
- }
- }
- }
-
- private void getAnchors(State state, PictogramElement stateShape, final HashMap<String, Anchor> node2anchor) {
-
- if (stateShape instanceof ContainerShape) {
- node2anchor.put(getKey(state), ((ContainerShape)stateShape).getAnchors().get(0));
- for (Shape child : ((ContainerShape) stateShape).getChildren()) {
- if (child instanceof ContainerShape) {
- ContainerShape childShape = (ContainerShape) child;
- if (!childShape.getAnchors().isEmpty()) {
- if (!childShape.getLink().getBusinessObjects().isEmpty()) {
- EObject obj = childShape.getLink().getBusinessObjects().get(0);
- if (obj instanceof EntryPoint || obj instanceof ExitPoint) {
- node2anchor.put(getKey(obj, true), childShape.getAnchors().get(0));
- }
- }
- }
- }
- }
- }
- }
-
- private String getKey(EObject obj) {
- return getKey(obj, false);
- }
-
- private String getKey(EObject obj, boolean subTp) {
- if (obj instanceof TrPoint) {
- TrPoint tp = (TrPoint) obj;
- if (!subTp)
- return TP+tp.getName();
- else {
- if (tp.eContainer().eContainer() instanceof State) {
- State s = (State) tp.eContainer().eContainer();
- return TP+tp.getName()+SEP+s.getName();
- }
- else {
- assert(false): "State expected";
- }
- }
- }
- else if (obj instanceof State) {
- return STATE+((State)obj).getName();
- }
- else if (obj instanceof ChoicePoint) {
- return CP+((ChoicePoint)obj).getName();
- }
- else if (obj instanceof TransitionTerminal) {
- TransitionTerminal tt = (TransitionTerminal) obj;
- if (tt instanceof ChoicepointTerminal) {
- return CP+((ChoicepointTerminal)tt).getCp().getName();
- }
- else if (tt instanceof StateTerminal) {
- return STATE+((StateTerminal)tt).getState().getName();
- }
- else if (tt instanceof SubStateTrPointTerminal) {
- SubStateTrPointTerminal sstt = (SubStateTrPointTerminal) tt;
- return TP+sstt.getTrPoint().getName()+SEP+sstt.getState().getName();
- }
- else if (tt instanceof TrPointTerminal) {
- return TP+((TrPointTerminal)tt).getTrPoint().getName();
- }
- else {
- assert(false): "unexpected sub type";
- }
- }
- assert(false): "unexpected type";
- return null;
- }
-
-}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/GenModelStateGraphContext.xtend b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/GenModelStateGraphContext.xtend
new file mode 100644
index 000000000..97ee76065
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/GenModelStateGraphContext.xtend
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.support
+
+import org.eclipse.etrice.core.fsm.fSM.ChoicePoint
+import org.eclipse.etrice.core.fsm.fSM.InitialTransition
+import org.eclipse.etrice.core.fsm.fSM.State
+import org.eclipse.etrice.core.fsm.fSM.TrPoint
+import org.eclipse.etrice.core.fsm.fSM.Transition
+import org.eclipse.etrice.core.genmodel.fsm.fsmgen.Graph
+import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMDiagramTypeProvider
+import org.eclipse.etrice.ui.behavior.fsm.provider.BaseDiagramProvider
+import org.eclipse.etrice.ui.behavior.fsm.provider.GenModelProvider
+import org.eclipse.etrice.core.fsm.fSM.RefinedTransition
+
+/**
+ * StateGraphContext based on newfsmgen.
+ */
+class GenModelStateGraphContext implements IStateGraphContext {
+
+ val GenModelProvider genModel
+ val BaseDiagramPositionProvider baseDiagram
+ val Graph graph
+
+ new(AbstractFSMDiagramTypeProvider diagramTypeProvider){
+ this.genModel = diagramTypeProvider.genModelProvider
+ this.baseDiagram = new BaseDiagramPositionProvider(new BaseDiagramProvider(diagramTypeProvider))
+ this.graph = genModel.model.graph
+ }
+
+ new(Graph graph, GenModelStateGraphContext other){
+ this.genModel = other.genModel
+ this.baseDiagram = other.baseDiagram
+ this.graph = graph
+ }
+
+ //
+ // IStateGraphContext
+ //
+
+ override getChPoints() {
+ graph.nodes.map[it.stateGraphNode].filter(ChoicePoint).toList
+ }
+
+ override getChildren() {
+ graph.nodes.filter[it.subgraph !== null].map[new GenModelStateGraphContext(it.subgraph, this) as IStateGraphContext].toList
+ }
+
+ override getInitialPoint() {
+ // return a Graph as initial point ?!?
+ if(!graph.links.map[transition].filter(InitialTransition).empty) graph.stateGraph
+ }
+
+ override getParentState() {
+ graph.node.stateGraphNode as State
+ }
+
+ override getPositionProvider() {
+ return baseDiagram
+ }
+
+ override getStateGraph() {
+ graph.stateGraph
+ }
+
+ override getStates() {
+ graph.nodes.map[it.stateGraphNode].filter(State).toList
+ }
+
+ override getTrPoints() {
+ graph.nodes.map[it.stateGraphNode].filter(TrPoint).toList
+ }
+
+ override getTransitions() {
+ val baseTransitions = graph.links.map[it.transition]
+
+ // we take the union of Transitions and targets of RefinedTransitions
+ (baseTransitions.filter(Transition) + baseTransitions.filter(RefinedTransition).map[target]).toList
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/IStateGraphContext.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/IStateGraphContext.java
new file mode 100644
index 000000000..5764c136d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/IStateGraphContext.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.support;
+
+import java.util.List;
+
+import org.eclipse.etrice.core.fsm.fSM.ChoicePoint;
+import org.eclipse.etrice.core.fsm.fSM.State;
+import org.eclipse.etrice.core.fsm.fSM.StateGraph;
+import org.eclipse.etrice.core.fsm.fSM.TrPoint;
+import org.eclipse.etrice.core.fsm.fSM.Transition;
+
+/**
+ * Interface to change implementation of StateGraphContext (newfsmgen)
+ */
+public interface IStateGraphContext {
+
+ public State getParentState();
+
+ public List<IStateGraphContext> getChildren();
+
+ public List<State> getStates();
+
+ public List<ChoicePoint> getChPoints();
+
+ public StateGraph getStateGraph();
+
+ public List<TrPoint> getTrPoints();
+
+ public List<Transition> getTransitions();
+
+ public IPositionProvider getPositionProvider();
+
+ public StateGraph getInitialPoint();
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/InitialPointSupport.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/InitialPointSupport.java
index aa55c2c6b..c38007be6 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/InitialPointSupport.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/InitialPointSupport.java
@@ -13,11 +13,14 @@
package org.eclipse.etrice.ui.behavior.fsm.support;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.etrice.core.fsm.fSM.InitialTransition;
import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
import org.eclipse.etrice.core.fsm.fSM.StateGraph;
import org.eclipse.etrice.core.fsm.fSM.Transition;
import org.eclipse.etrice.ui.behavior.fsm.provider.ImageProvider;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.ModelEditingUtil;
import org.eclipse.etrice.ui.common.base.support.CommonSupportUtil;
import org.eclipse.etrice.ui.common.base.support.DeleteWithoutConfirmFeature;
import org.eclipse.etrice.ui.common.base.support.NoResizeFeature;
@@ -28,8 +31,10 @@ import org.eclipse.graphiti.features.ICreateFeature;
import org.eclipse.graphiti.features.IDeleteFeature;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.IMoveShapeFeature;
+import org.eclipse.graphiti.features.IReason;
import org.eclipse.graphiti.features.IRemoveFeature;
import org.eclipse.graphiti.features.IResizeShapeFeature;
+import org.eclipse.graphiti.features.IUpdateFeature;
import org.eclipse.graphiti.features.context.IAddContext;
import org.eclipse.graphiti.features.context.ICreateContext;
import org.eclipse.graphiti.features.context.IDeleteContext;
@@ -37,11 +42,15 @@ import org.eclipse.graphiti.features.context.IMoveShapeContext;
import org.eclipse.graphiti.features.context.IPictogramElementContext;
import org.eclipse.graphiti.features.context.IRemoveContext;
import org.eclipse.graphiti.features.context.IResizeShapeContext;
+import org.eclipse.graphiti.features.context.IUpdateContext;
import org.eclipse.graphiti.features.context.impl.CreateConnectionContext;
+import org.eclipse.graphiti.features.context.impl.RemoveContext;
import org.eclipse.graphiti.features.impl.AbstractAddFeature;
import org.eclipse.graphiti.features.impl.AbstractCreateFeature;
+import org.eclipse.graphiti.features.impl.AbstractUpdateFeature;
import org.eclipse.graphiti.features.impl.DefaultMoveShapeFeature;
import org.eclipse.graphiti.features.impl.DefaultRemoveFeature;
+import org.eclipse.graphiti.features.impl.Reason;
import org.eclipse.graphiti.mm.algorithms.Ellipse;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.Rectangle;
@@ -93,10 +102,9 @@ public class InitialPointSupport {
ContainerShape targetContainer = context.getTargetContainer();
StateGraph sg = (StateGraph) targetContainer.getLink().getBusinessObjects().get(0);
- boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg);
- if (inherited) {
- ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
- sg = FSMSupportUtil.getInstance().insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
+ ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
+ if (!FSMSupportUtil.getInstance().isOwnedBy(mc, sg)) {
+ sg = ModelEditingUtil.insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
}
// We don't create anything here since in the model the initial point is
@@ -155,14 +163,15 @@ public class InitialPointSupport {
ContainerShape sgShape = context.getTargetContainer();
StateGraph sg = (StateGraph) context.getNewObject();
- boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg);
+ Transition initTransition = FSMSupportUtil.getInstance().getFSMHelpers().getInitTransition(sg);
+ boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), initTransition);
// CONTAINER SHAPE WITH RECTANGLE
IPeCreateService peCreateService = Graphiti.getPeCreateService();
ContainerShape containerShape =
peCreateService.createContainerShape(sgShape, true);
- Graphiti.getPeService().setPropertyValue(containerShape, Constants.TYPE_KEY, Constants.TRP_TYPE);
+ Graphiti.getPeService().setPropertyValue(containerShape, Constants.TYPE_KEY, Constants.INI_TYPE);
int x = context.getX()-ITEM_SIZE;
int y = context.getY()-ITEM_SIZE;
@@ -215,7 +224,8 @@ public class InitialPointSupport {
if (canMove) {
Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
if (bo instanceof StateGraph) {
- return !FSMSupportUtil.getInstance().isInherited(getDiagram(), (StateGraph)bo);
+ Transition initTransition = FSMSupportUtil.getInstance().getFSMHelpers().getInitTransition((StateGraph) bo);
+ return !FSMSupportUtil.getInstance().isInherited(getDiagram(), initTransition);
}
return false;
}
@@ -224,6 +234,58 @@ public class InitialPointSupport {
}
}
+ private class UpdateFeature extends AbstractUpdateFeature {
+
+ public UpdateFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canUpdate(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy())
+ return true;
+
+ return bo instanceof StateGraph;
+ }
+
+ @Override
+ public IReason updateNeeded(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ return Reason.createTrueReason("InitialPoint deleted from model");
+ }
+
+ return Reason.createFalseReason();
+ }
+
+ @Override
+ public boolean update(IUpdateContext context) {
+ ContainerShape containerShape = (ContainerShape)context.getPictogramElement();
+ Object bo = getBusinessObjectForPictogramElement(containerShape);
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ IRemoveContext rc = new RemoveContext(containerShape);
+ IFeatureProvider featureProvider = getFeatureProvider();
+ IRemoveFeature removeFeature = featureProvider.getRemoveFeature(rc);
+ if (removeFeature != null) {
+ removeFeature.remove(rc);
+ }
+ EcoreUtil.delete((EObject) bo);
+ return true;
+ }
+
+ if (bo instanceof StateGraph) {
+ Transition initTransition = FSMSupportUtil.getInstance().getFSMHelpers().getInitTransition((StateGraph) bo);
+ boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), initTransition);
+
+ Color dark = manageColor(inherited? INHERITED_COLOR:DARK_COLOR);
+ updateFigure(containerShape, dark, manageColor(BRIGHT_COLOR));
+ }
+ return true;
+ }
+
+ }
+
protected static class RemoveFeature extends DefaultRemoveFeature {
public RemoveFeature(IFeatureProvider fp) {
@@ -233,7 +295,8 @@ public class InitialPointSupport {
public boolean canRemove(IRemoveContext context) {
Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
if (bo instanceof StateGraph) {
- return !FSMSupportUtil.getInstance().isInherited(getDiagram(), (StateGraph) bo);
+ Transition initTransition = FSMSupportUtil.getInstance().getFSMHelpers().getInitTransition((StateGraph) bo);
+ return !FSMSupportUtil.getInstance().isInherited(getDiagram(), initTransition);
}
return false;
}
@@ -300,6 +363,11 @@ public class InitialPointSupport {
return new DeleteFeature(fp);
}
+ @Override
+ public IUpdateFeature getUpdateFeature(IUpdateContext context) {
+ return new UpdateFeature(fp);
+ }
+
protected static void createFigure(
ContainerShape containerShape,
GraphicsAlgorithm invisibleRectangle, Color darkColor, Color brightColor) {
@@ -325,7 +393,18 @@ public class InitialPointSupport {
//containerShape.getAnchors().get(0).setReferencedGraphicsAlgorithm(rect);
}
}
-
+
+ private static void updateFigure(PictogramElement pe, Color dark, Color bright) {
+ ContainerShape container = (ContainerShape)pe;
+
+ // we clear the figure and rebuild it
+ GraphicsAlgorithm borderRect = pe.getGraphicsAlgorithm();
+ while (!borderRect.getGraphicsAlgorithmChildren().isEmpty()) {
+ EcoreUtil.delete(borderRect.getGraphicsAlgorithmChildren().get(0), true);
+ }
+
+ createFigure(container, borderRect, dark, bright);
+ }
}
private class BehaviorProvider extends DefaultToolBehaviorProvider {
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphSupport.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphSupport.java
index e690751e6..16a1795b2 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphSupport.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphSupport.java
@@ -19,13 +19,16 @@ import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.etrice.core.fsm.fSM.ChoicePoint;
+import org.eclipse.etrice.core.fsm.fSM.RefinedState;
import org.eclipse.etrice.core.fsm.fSM.State;
import org.eclipse.etrice.core.fsm.fSM.StateGraph;
import org.eclipse.etrice.core.fsm.fSM.TrPoint;
import org.eclipse.etrice.core.fsm.fSM.Transition;
-import org.eclipse.etrice.ui.behavior.fsm.commands.StateGraphContext;
+import org.eclipse.etrice.core.fsm.util.FSMHelpers;
import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMEditor;
import org.eclipse.etrice.ui.behavior.fsm.editor.DecoratorUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.DiagramEditingUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
import org.eclipse.etrice.ui.common.base.support.DeleteWithoutConfirmFeature;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IAddFeature;
@@ -72,6 +75,8 @@ import org.eclipse.graphiti.tb.ImageDecorator;
import org.eclipse.graphiti.ui.features.DefaultFeatureProvider;
import org.eclipse.graphiti.util.ColorConstant;
import org.eclipse.graphiti.util.IColorConstant;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
import com.google.common.collect.Sets;
@@ -273,6 +278,22 @@ public class StateGraphSupport {
Object bo = getBusinessObjectForPictogramElement(container);
if (bo instanceof StateGraph) {
StateGraph sg = (StateGraph) bo;
+ if (sg.eContainer() instanceof RefinedState) {
+ RefinedState rs = (RefinedState) sg.eContainer();
+ FSMHelpers fsmHelpers = FSMSupportUtil.getInstance().getFSMHelpers();
+ if (fsmHelpers.isEmpty(sg)) {
+ // check action codes
+ boolean entryEmpty = fsmHelpers.getDetailCode(rs.getEntryCode()).trim().isEmpty();
+ boolean exitEmpty = fsmHelpers.getDetailCode(rs.getExitCode()).trim().isEmpty();
+ boolean doEmpty = fsmHelpers.getDetailCode(rs.getDoCode()).trim().isEmpty();
+ if (entryEmpty && exitEmpty && doEmpty) {
+ MessageDialog.openInformation(Display.getCurrent().getActiveShell(),
+ "Check of Refined State",
+ "A Refined State with empty action codes must have a non-empty sub state graph.");
+ return;
+ }
+ }
+ }
getDiagramBehavior().getDiagramContainer().selectPictogramElements(new PictogramElement[] {});
ContextSwitcher.goUp(getDiagram(), sg);
}
@@ -314,12 +335,12 @@ public class StateGraphSupport {
int obsolete = 0;
if (context instanceof StateGraphUpdateContext) {
- StateGraphContext ctx = ((StateGraphUpdateContext)context).getContext();
+ IStateGraphContext ctx = ((StateGraphUpdateContext)context).getContext();
// check for states added in model not present in diagram (including inherited)
{
Set<State> expected = Sets.newHashSet(ctx.getStates());
- Set<State> present = Sets.newHashSet(FSMSupportUtil.getInstance().getStates(shape, fp));
+ Set<State> present = Sets.newHashSet(DiagramEditingUtil.getInstance().getStates(shape, fp));
if((missing = Sets.difference(expected, present).size()) > 0)
reason += missing+" missing states\n";
@@ -331,7 +352,7 @@ public class StateGraphSupport {
{
missing = obsolete = 0;
Set<TrPoint> expected = Sets.newHashSet(ctx.getTrPoints());
- Set<TrPoint> present = Sets.newHashSet(FSMSupportUtil.getInstance().getTrPoints(sg, shape, fp));
+ Set<TrPoint> present = Sets.newHashSet(DiagramEditingUtil.getInstance().getTrPoints(sg, shape, fp));
if((missing = Sets.difference(expected, present).size()) > 0)
reason += missing+" missing transition points\n";
@@ -343,7 +364,7 @@ public class StateGraphSupport {
{
missing = obsolete = 0;
Set<ChoicePoint> expected = Sets.newHashSet(ctx.getChPoints());
- Set<ChoicePoint> present = Sets.newHashSet(FSMSupportUtil.getInstance().getChoicePoints(shape, fp));
+ Set<ChoicePoint> present = Sets.newHashSet(DiagramEditingUtil.getInstance().getChoicePoints(shape, fp));
if((missing = Sets.difference(expected, present).size()) > 0)
reason += missing+" missing choice points\n";
@@ -401,9 +422,9 @@ public class StateGraphSupport {
StateGraph sg = (StateGraph) bo;
if (context instanceof StateGraphUpdateContext) {
- StateGraphContext ctx = ((StateGraphUpdateContext)context).getContext();
+ IStateGraphContext ctx = ((StateGraphUpdateContext)context).getContext();
- FSMSupportUtil.getInstance().updateStateGraph(sg, ctx, sgShape, fp);
+ DiagramEditingUtil.getInstance().updateStateGraph(sg, ctx, sgShape, fp);
}
if (!sgShape.getChildren().isEmpty()) {
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphUpdateContext.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphUpdateContext.java
index 82c766c07..a1afa2204 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphUpdateContext.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateGraphUpdateContext.java
@@ -12,7 +12,6 @@
package org.eclipse.etrice.ui.behavior.fsm.support;
-import org.eclipse.etrice.ui.behavior.fsm.commands.StateGraphContext;
import org.eclipse.graphiti.features.context.impl.UpdateContext;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
@@ -22,12 +21,12 @@ import org.eclipse.graphiti.mm.pictograms.PictogramElement;
*/
public class StateGraphUpdateContext extends UpdateContext {
- private StateGraphContext context;
+ private IStateGraphContext context;
/**
* @param pictogramElement
*/
- public StateGraphUpdateContext(PictogramElement pe, StateGraphContext ctx) {
+ public StateGraphUpdateContext(PictogramElement pe, IStateGraphContext ctx) {
super(pe);
this.context = ctx;
@@ -36,7 +35,7 @@ public class StateGraphUpdateContext extends UpdateContext {
/**
* @return the context
*/
- public StateGraphContext getContext() {
+ public IStateGraphContext getContext() {
return context;
}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateSupport.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateSupport.java
index 2ca43aadf..43d846452 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateSupport.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateSupport.java
@@ -30,6 +30,9 @@ import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMEditor;
import org.eclipse.etrice.ui.behavior.fsm.editor.DecoratorUtil;
import org.eclipse.etrice.ui.behavior.fsm.provider.IInjectorProvider;
import org.eclipse.etrice.ui.behavior.fsm.provider.ImageProvider;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.DiagramEditingUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.ModelEditingUtil;
import org.eclipse.etrice.ui.common.base.support.ChangeAwareCreateFeature;
import org.eclipse.etrice.ui.common.base.support.ChangeAwareCustomFeature;
import org.eclipse.etrice.ui.common.base.support.CommonSupportUtil;
@@ -153,16 +156,12 @@ public class StateSupport {
public Object[] doCreate(ICreateContext context) {
ContainerShape targetContainer = context.getTargetContainer();
- ModelComponent ac = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
- StateGraph sg = (StateGraph) targetContainer.getLink().getBusinessObjects().get(0);
-
- // hrr: was boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg);
- // but if we are inside our own refined state it is treated as inherited which is wrong
- boolean inherited = !EcoreUtil.isAncestor(FSMSupportUtil.getInstance().getModelComponent(getDiagram()), sg);
- if (inherited) {
- sg = FSMSupportUtil.getInstance().insertRefinedState(sg, ac, targetContainer, getFeatureProvider());
- }
-
+ ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
+ StateGraph sg = (StateGraph) targetContainer.getLink().getBusinessObjects().get(0);
+ if (!FSMSupportUtil.getInstance().isOwnedBy(mc, sg)) {
+ sg = ModelEditingUtil.insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
+
+ }
// create new State and add it
SimpleState s = FSMFactory.eINSTANCE.createSimpleState();
s.setName(FSMSupportUtil.getInstance().getFSMNewNamingUtil().getUniqueName("state", sg));
@@ -171,7 +170,7 @@ public class StateSupport {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
Injector injector = ((IInjectorProvider) getFeatureProvider()).getInjector();
IFSMDialogFactory factory = injector.getInstance(IFSMDialogFactory.class);
- IStatePropertyDialog dlg = factory.createStatePropertyDialog(shell, ac, s, true);
+ IStatePropertyDialog dlg = factory.createStatePropertyDialog(shell, mc, s, true);
if (dlg.open()==Window.OK) {
addGraphicalRepresentation(context, s);
@@ -527,7 +526,7 @@ public class StateSupport {
boolean isBaseClassState = FSMSupportUtil.getInstance().getFSMHelpers().getModelComponent(s)!=FSMSupportUtil.getInstance().getModelComponent(getDiagram());
if (isBaseClassState) {
- newSG = FSMSupportUtil.getInstance().getSubGraphOfRefinedStateFor(s, FSMSupportUtil.getInstance().getModelComponent(getDiagram()));
+ newSG = ModelEditingUtil.getOrCreateSubGraphOfRefinedStateFor(s, FSMSupportUtil.getInstance().getModelComponent(getDiagram()));
s = (State) newSG.eContainer();
// replace old business object with new refined state
@@ -590,7 +589,7 @@ public class StateSupport {
ContainerShape container = (ContainerShape)context.getPictogramElements()[0];
Object bo = getBusinessObjectForPictogramElement(container);
State s = (State) bo;
- RefinedState rs = FSMSupportUtil.getInstance().getRefinedStateFor(s, FSMSupportUtil.getInstance().getModelComponent(getDiagram()));
+ RefinedState rs = ModelEditingUtil.getOrCreateRefinedStateFor(s, FSMSupportUtil.getInstance().getModelComponent(getDiagram()));
// replace old business object with new refined state
link(container, rs);
@@ -599,6 +598,11 @@ public class StateSupport {
for (ICustomFeature cf : features) {
if (cf instanceof PropertyFeature) {
cf.execute(context);
+ if (!cf.hasDoneChanges()) {
+ // roll back
+ link(container, s);
+ EcoreUtil.remove(rs);
+ }
break;
}
}
@@ -830,7 +834,7 @@ public class StateSupport {
IFeatureProvider fp = getFeatureProvider();
Diagram diagram = getDiagram();
ModelComponent mc = FSMSupportUtil.getInstance().getFSMHelpers().getModelComponent(s);
- FSMSupportUtil.getInstance().deleteSubStructureRecursive(s, mc, diagram, fp);
+ DiagramEditingUtil.getInstance().deleteSubStructureRecursive(s, mc, diagram, fp);
ContainerShape container = (ContainerShape) context.getPictogramElement();
CommonSupportUtil.deleteConnectionsRecursive(container, fp);
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TrPointSupport.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TrPointSupport.java
index cd2e86afb..bd07b6f83 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TrPointSupport.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TrPointSupport.java
@@ -32,6 +32,8 @@ import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMEditor;
import org.eclipse.etrice.ui.behavior.fsm.editor.DecoratorUtil;
import org.eclipse.etrice.ui.behavior.fsm.provider.IInjectorProvider;
import org.eclipse.etrice.ui.behavior.fsm.provider.ImageProvider;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.ModelEditingUtil;
import org.eclipse.etrice.ui.common.base.support.ChangeAwareCreateFeature;
import org.eclipse.etrice.ui.common.base.support.ChangeAwareCustomFeature;
import org.eclipse.etrice.ui.common.base.support.CommonSupportUtil;
@@ -145,9 +147,9 @@ public class TrPointSupport {
ContainerShape targetContainer = context.getTargetContainer();
ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram());
StateGraph sg = (StateGraph) targetContainer.getLink().getBusinessObjects().get(0);
- boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg);
- if (inherited) {
- sg = FSMSupportUtil.getInstance().insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
+
+ if (!FSMSupportUtil.getInstance().isOwnedBy(mc, sg)) {
+ sg = ModelEditingUtil.insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
}
// create transition point
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TransitionSupport.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TransitionSupport.java
index 6a7f9112d..f912cdfd7 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TransitionSupport.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/TransitionSupport.java
@@ -41,6 +41,8 @@ import org.eclipse.etrice.ui.behavior.fsm.editor.AbstractFSMEditor;
import org.eclipse.etrice.ui.behavior.fsm.editor.DecoratorUtil;
import org.eclipse.etrice.ui.behavior.fsm.provider.IInjectorProvider;
import org.eclipse.etrice.ui.behavior.fsm.provider.ImageProvider;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil;
+import org.eclipse.etrice.ui.behavior.fsm.support.util.ModelEditingUtil;
import org.eclipse.etrice.ui.common.base.UIBaseActivator;
import org.eclipse.etrice.ui.common.base.preferences.UIBasePreferenceConstants;
import org.eclipse.etrice.ui.common.base.support.CantRemoveFeature;
@@ -267,11 +269,8 @@ public class TransitionSupport {
}
ContainerShape targetContainer = FSMSupportUtil.getInstance().getStateGraphContainer((ContainerShape) context.getSourcePictogramElement().eContainer());
- // hrr: was boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg);
- // but if we are inside our own refined state it is treated as inherited which is wrong
- boolean inherited = !EcoreUtil.isAncestor(FSMSupportUtil.getInstance().getModelComponent(getDiagram()), sg);
- if (inherited) {
- sg = FSMSupportUtil.getInstance().insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
+ if (!FSMSupportUtil.getInstance().isOwnedBy(mc, sg)) {
+ sg = ModelEditingUtil.insertRefinedState(sg, mc, targetContainer, getFeatureProvider());
}
sg.getTransitions().add(trans);
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramEditingUtil.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramEditingUtil.java
new file mode 100644
index 000000000..c90cd2e26
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramEditingUtil.java
@@ -0,0 +1,743 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.support.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.etrice.core.fsm.fSM.ChoicePoint;
+import org.eclipse.etrice.core.fsm.fSM.ChoicepointTerminal;
+import org.eclipse.etrice.core.fsm.fSM.EntryPoint;
+import org.eclipse.etrice.core.fsm.fSM.ExitPoint;
+import org.eclipse.etrice.core.fsm.fSM.InitialTransition;
+import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
+import org.eclipse.etrice.core.fsm.fSM.NonInitialTransition;
+import org.eclipse.etrice.core.fsm.fSM.State;
+import org.eclipse.etrice.core.fsm.fSM.StateGraph;
+import org.eclipse.etrice.core.fsm.fSM.StateGraphItem;
+import org.eclipse.etrice.core.fsm.fSM.StateGraphNode;
+import org.eclipse.etrice.core.fsm.fSM.StateTerminal;
+import org.eclipse.etrice.core.fsm.fSM.SubStateTrPointTerminal;
+import org.eclipse.etrice.core.fsm.fSM.TrPoint;
+import org.eclipse.etrice.core.fsm.fSM.TrPointTerminal;
+import org.eclipse.etrice.core.fsm.fSM.Transition;
+import org.eclipse.etrice.core.fsm.fSM.TransitionTerminal;
+import org.eclipse.etrice.core.fsm.naming.FSMNameProvider;
+import org.eclipse.etrice.ui.behavior.fsm.support.ContextSwitcher;
+import org.eclipse.etrice.ui.behavior.fsm.support.IPositionProvider;
+import org.eclipse.etrice.ui.behavior.fsm.support.IPositionProvider.Pos;
+import org.eclipse.etrice.ui.behavior.fsm.support.IPositionProvider.PosAndSize;
+import org.eclipse.etrice.ui.behavior.fsm.support.IStateGraphContext;
+import org.eclipse.etrice.ui.behavior.fsm.support.StateGraphSupport;
+import org.eclipse.etrice.ui.behavior.fsm.support.StateSupport;
+import org.eclipse.etrice.ui.behavior.fsm.support.TrPointSupport;
+import org.eclipse.etrice.ui.common.base.support.CommonSupportUtil;
+import org.eclipse.graphiti.datatypes.ILocation;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IRemoveFeature;
+import org.eclipse.graphiti.features.context.IRemoveContext;
+import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
+import org.eclipse.graphiti.features.context.impl.AddContext;
+import org.eclipse.graphiti.features.context.impl.LayoutContext;
+import org.eclipse.graphiti.features.context.impl.RemoveContext;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.styles.Point;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+import org.eclipse.graphiti.mm.pictograms.Connection;
+import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.services.IGaService;
+import org.eclipse.graphiti.services.ILinkService;
+
+/**
+ * Shared logic to modify graphical diagram
+ */
+public class DiagramEditingUtil {
+
+ private static final String INITIAL = "init";
+ private static final String STATE = "state:";
+ private static final String TP = "tp:";
+ private static final String CP = "cp:";
+ private static final String SEP = ".";
+
+ private static DiagramEditingUtil instance = null;
+
+ public static DiagramEditingUtil getInstance() {
+ if(instance == null)
+ instance = new DiagramEditingUtil();
+
+ return instance;
+ }
+
+ public void updateStateGraph(StateGraph sg, IStateGraphContext ctx, ContainerShape sgShape,
+ IFeatureProvider fp) {
+
+ HashMap<String, Anchor> node2anchor = new HashMap<String, Anchor>();
+
+ GraphicsAlgorithm borderRect = sgShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0);
+ ctx.getPositionProvider().setScale(borderRect.getWidth(), borderRect.getHeight());
+ ctx.getPositionProvider().setPosition(sgShape.getGraphicsAlgorithm().getX(), sgShape.getGraphicsAlgorithm().getY());
+
+ // states
+ {
+ ArrayList<Shape> shapes = new ArrayList<Shape>();
+ List<State> present = getStates(sgShape, fp, node2anchor, shapes);
+ checkDuplicates(present);
+ List<State> expected = ctx.getStates();
+ List<State> toAdd = new ArrayList<State>();
+ List<State> toUpdate = new ArrayList<State>();
+ List<State> toRemove = new ArrayList<State>();
+ for (State item : expected) {
+ if (present.contains(item))
+ toUpdate.add(item);
+ else
+ toAdd.add(item);
+ }
+ for(State item : present){
+ if(!expected.contains(item))
+ toRemove.add(item);
+ }
+ addStateGraphNodes(toAdd, ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ updateStateGraphNodes(toUpdate, shapes, ctx.getPositionProvider(), fp);
+ removeGraphicalRepresentation(toRemove, shapes, fp);
+ }
+
+ // transition points
+ {
+ ArrayList<Shape> shapes = new ArrayList<Shape>();
+ List<TrPoint> present = getTrPoints(sg, sgShape, fp, node2anchor, shapes);
+ checkDuplicates(present);
+ List<TrPoint> expected = ctx.getTrPoints();
+ List<TrPoint> toAdd = new ArrayList<TrPoint>();
+ List<TrPoint> toUpdate = new ArrayList<TrPoint>();
+ List<TrPoint> toRemove = new ArrayList<TrPoint>();
+ for (TrPoint item : expected) {
+ if (present.contains(item))
+ toUpdate.add(item);
+ else
+ toAdd.add(item);
+ }
+ for(TrPoint item : present){
+ if(!expected.contains(item))
+ toRemove.add(item);
+ }
+ addStateGraphNodes(toAdd, ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ updateStateGraphNodes(toUpdate, shapes, ctx.getPositionProvider(), fp);
+ removeGraphicalRepresentation(toRemove, shapes, fp);
+ }
+
+ // choice points
+ {
+ ArrayList<Shape> shapes = new ArrayList<Shape>();
+ List<ChoicePoint> present = getChoicePoints(sgShape, fp, node2anchor, shapes);
+ checkDuplicates(present);
+ List<ChoicePoint> expected = ctx.getChPoints();
+ List<ChoicePoint> toAdd = new ArrayList<ChoicePoint>();
+ List<ChoicePoint> toUpdate = new ArrayList<ChoicePoint>();
+ List<ChoicePoint> toRemove = new ArrayList<ChoicePoint>();
+ for (ChoicePoint item : expected) {
+ if (present.contains(item))
+ toUpdate.add(item);
+ else
+ toAdd.add(item);
+ }
+ for(ChoicePoint item : present){
+ if(!expected.contains(item))
+ toRemove.add(item);
+ }
+ addStateGraphNodes(toAdd, ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ updateStateGraphNodes(toUpdate, shapes, ctx.getPositionProvider(), fp);
+ removeGraphicalRepresentation(toRemove, shapes, fp);
+ }
+
+ getSubTpAnchors(sgShape, node2anchor);
+
+ // initial point
+ {
+ // exists in this diagram ?
+ Shape present = null;
+ for (Shape ch : sgShape.getChildren()) {
+ Object bo = fp.getBusinessObjectForPictogramElement(ch);
+ if (bo instanceof StateGraph)
+ present = ch;
+ }
+ if(present != null) {
+ node2anchor.put(INITIAL, present.getAnchors().get(0));
+ }
+ // exists in model ?
+ StateGraph expected = ctx.getInitialPoint();
+ if(expected == null) {
+ // exists in (super class) diagram ?
+ expected = ctx.getPositionProvider().getInitialPoint(ctx.getStateGraph());
+ }
+ if(expected != null && present == null) {
+ addInitialPointIff(ctx, ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ }
+ else {
+ updateInitialPoint(present, ctx.getPositionProvider(), fp);
+ }
+ }
+
+ // transitions
+ {
+ // get transitions that belong to our state graph
+ // (for other connections we might not have the node anchors yet)
+ Map<Transition, Connection> present = getTransitionsMap(sgShape, fp);
+ List<Transition> expected = ctx.getTransitions();
+ List<Transition> toAdd = new ArrayList<Transition>();
+ List<Transition> toRemove = new ArrayList<Transition>();
+ for (Transition trans : expected)
+ if (!present.containsKey(trans))
+ toAdd.add(trans);
+ for(Transition item : present.keySet()){
+ if(!expected.contains(item))
+ toRemove.add(item);
+ }
+ addTransitions(toAdd, ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ updateTransitions(present, ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ removeGraphicalRepresentation(toRemove, present.values(), fp);
+ }
+ }
+
+
+ public void removeGraphicalRepresentation(Collection<? extends EObject> toRemove, Collection<? extends PictogramElement> pictograms, IFeatureProvider fp) {
+ for(EObject bo : toRemove)
+ for(PictogramElement pe : pictograms)
+ if(fp.getBusinessObjectForPictogramElement(pe) == bo){
+ IRemoveContext rc = new RemoveContext(pe);
+ IRemoveFeature removeFeature = fp.getRemoveFeature(rc);
+ if (removeFeature != null)
+ removeFeature.remove(rc);
+ break;
+ }
+ }
+
+
+ /**
+ * @param s the state whose sub structure should be deleted
+ * @param mc the ModelComponent
+ * @param diagram the current diagram
+ * @param fp the feature provider
+ */
+ public void deleteSubStructureRecursive(State s, ModelComponent mc, Diagram diagram, IFeatureProvider fp) {
+ if (FSMSupportUtil.getInstance().getFSMHelpers().hasSubStructure(s, mc)) {
+ StateGraph subgraph = s.getSubgraph();
+
+ // depth first
+ for (State st : subgraph.getStates()) {
+ deleteSubStructureRecursive(st, mc, diagram, fp);
+ }
+
+ ContainerShape subShape = ContextSwitcher.getContext(diagram, subgraph);
+ CommonSupportUtil.deleteConnectionsRecursive(subShape, fp);
+ EcoreUtil.delete(subShape, true);
+ }
+ }
+
+ public ContainerShape addStateGraph(IStateGraphContext ctx, Diagram diagram, IFeatureProvider fp) {
+ AddContext addContext = new AddContext();
+ addContext.setNewObject(ctx.getStateGraph());
+ addContext.setTargetContainer(diagram);
+ PosAndSize graphPosAndSize = ctx.getPositionProvider().getGraphPosAndSize(ctx.getStateGraph());
+ if (graphPosAndSize!=null) {
+ addContext.setX(graphPosAndSize.getX());
+ addContext.setY(graphPosAndSize.getY());
+ addContext.setWidth(graphPosAndSize.getWidth());
+ addContext.setHeight(graphPosAndSize.getHeight());
+ }
+ else {
+ addContext.setX(StateGraphSupport.MARGIN);
+ addContext.setY(StateGraphSupport.MARGIN);
+ }
+
+ ContainerShape sgShape = (ContainerShape) fp.addIfPossible(addContext);
+ if (sgShape==null)
+ return null;
+
+ final HashMap<String, Anchor> node2anchor = new HashMap<String, Anchor>();
+
+ GraphicsAlgorithm borderRect = sgShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0);
+ ctx.getPositionProvider().setScale(borderRect.getWidth(), borderRect.getHeight());
+ ctx.getPositionProvider().setPosition(sgShape.getGraphicsAlgorithm().getX(), sgShape.getGraphicsAlgorithm().getY());
+
+ addInitialPointIff(ctx, ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ addStateGraphNodes(ctx.getTrPoints(), ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ addStateGraphNodes(ctx.getStates(), ctx.getPositionProvider(), sgShape, fp, node2anchor);
+ addStateGraphNodes(ctx.getChPoints(), ctx.getPositionProvider(), sgShape, fp, node2anchor);
+
+ for (IStateGraphContext sub : ctx.getChildren()) {
+ addStateGraph(sub, diagram, fp);
+ }
+
+ getSubTpAnchors(sgShape, node2anchor);
+
+ addTransitions(ctx.getTransitions(), ctx.getPositionProvider(), sgShape, fp, node2anchor);
+
+ return sgShape;
+ }
+
+
+ public List<State> getStates(ContainerShape shape, IFeatureProvider fp) {
+ return getStates(shape, fp, null, null);
+ }
+
+ public List<ChoicePoint> getChoicePoints(ContainerShape shape, IFeatureProvider fp) {
+ return getChoicePoints(shape, fp, null, null);
+ }
+
+
+ public List<TrPoint> getTrPoints(StateGraph sg, ContainerShape shape, IFeatureProvider fp) {
+ return getTrPoints(sg, shape, fp, null, null);
+ }
+
+
+ private List<State> getStates(ContainerShape shape, IFeatureProvider fp, Map<String, Anchor> item2anchor, List<Shape> stateShapes) {
+ List<State> items = new ArrayList<State>();
+ for (Shape ch : shape.getChildren()) {
+ Object bo = fp.getBusinessObjectForPictogramElement(ch);
+ if (bo instanceof State) {
+ items.add((State)bo);
+ if (item2anchor!=null)
+ item2anchor.put(getKey((State)bo), ch.getAnchors().get(0));
+ if (stateShapes!=null)
+ stateShapes.add(ch);
+ }
+ }
+ return items;
+ }
+
+ private List<ChoicePoint> getChoicePoints(ContainerShape shape, IFeatureProvider fp, Map<String, Anchor> item2anchor,
+ List<Shape> cpShapes) {
+ List<ChoicePoint> items = new ArrayList<ChoicePoint>();
+ for (Shape ch : shape.getChildren()) {
+ Object bo = fp.getBusinessObjectForPictogramElement(ch);
+ if (bo instanceof ChoicePoint) {
+ items.add((ChoicePoint)bo);
+ if (item2anchor!=null)
+ item2anchor.put(getKey((ChoicePoint)bo), ch.getAnchors().get(0));
+ if (cpShapes!=null)
+ cpShapes.add(ch);
+ }
+ }
+ return items;
+ }
+
+ private List<TrPoint> getTrPoints(StateGraph sg, ContainerShape shape, IFeatureProvider fp,
+ Map<String, Anchor> item2anchor, List<Shape> tpShapes) {
+ List<TrPoint> items = new ArrayList<TrPoint>();
+ for (Shape ch : shape.getChildren()) {
+ Object bo = fp.getBusinessObjectForPictogramElement(ch);
+ if (bo instanceof TrPoint) {
+ items.add((TrPoint)bo);
+ if (item2anchor!=null)
+ item2anchor.put(getKey((TrPoint)bo), ch.getAnchors().get(0));
+ if (tpShapes!=null)
+ tpShapes.add(ch);
+ }
+ }
+ return items;
+ }
+
+ private Map<Transition, Connection> getTransitionsMap(ContainerShape sgShape, IFeatureProvider fp) {
+ Diagram diagram = (Diagram) sgShape.eContainer();
+ Map<Transition, Connection> transitions = new HashMap<Transition, Connection>();
+ for (Connection conn : diagram.getConnections()) {
+ Object bo = fp.getBusinessObjectForPictogramElement(conn);
+
+ // we only collect connections that have a starting point contained in our sgShape
+ if (bo instanceof Transition && EcoreUtil.isAncestor(sgShape, conn.getStart()))
+ transitions.put((Transition) bo, conn);
+ }
+ return transitions;
+ }
+
+ private void getSubTpAnchors(ContainerShape sgShape, HashMap<String, Anchor> node2anchor) {
+ for (Shape childShape : sgShape.getChildren()) {
+ EObject bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(childShape);
+ if (bo instanceof State)
+ getAnchors((State) bo, childShape, node2anchor);
+ }
+ }
+
+ private void addInitialPointIff(IStateGraphContext ctx, IPositionProvider positionProvider, ContainerShape sgShape,
+ IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
+
+ // model
+ StateGraph sg = ctx.getInitialPoint();
+ if(sg==null)
+ // (super class) diagram
+ sg = positionProvider.getInitialPoint(ctx.getStateGraph());
+ if(sg==null)
+ return;
+
+ PosAndSize pos = positionProvider.getPosition(sg);
+ AddContext addContext = new AddContext();
+ addContext.setNewObject(sg);
+ addContext.setTargetContainer(sgShape);
+ if(pos != null){
+ addContext.setX(pos.getX());
+ addContext.setY(pos.getY());
+ if (pos.getWidth()>0 && pos.getHeight()>0) {
+ addContext.setWidth(pos.getWidth());
+ addContext.setHeight(pos.getHeight());
+ }
+ } else {
+ addContext.setX(3*StateGraphSupport.MARGIN);
+ addContext.setY(3*StateGraphSupport.MARGIN);
+ }
+
+ ContainerShape pe = (ContainerShape) fp.addIfPossible(addContext);
+ assert(pe!=null): "initial point should have been created";
+ assert(!pe.getAnchors().isEmpty()): "initial point should have an anchor";
+ node2anchor.put(INITIAL, pe.getAnchors().get(0));
+ }
+
+ private void addTransitions(List<Transition> transitions, IPositionProvider positionProvider, ContainerShape sgShape,
+ IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
+
+ for (Transition trans : transitions) {
+ String from = (trans instanceof InitialTransition)? INITIAL:getKey(((NonInitialTransition)trans).getFrom());
+ String to = getKey(trans.getTo());
+ Anchor src = node2anchor.get(from);
+ Anchor dst = node2anchor.get(to);
+
+ assert(src!=null && dst!=null): "transition endpoints must be present";
+
+ AddConnectionContext context = new AddConnectionContext(src, dst);
+ context.setNewObject(trans);
+ PictogramElement pe = fp.addIfPossible(context);
+ if (pe instanceof FreeFormConnection) {
+ FreeFormConnection conn = (FreeFormConnection) pe;
+
+ // JH: workaround for correct bend points of inherited self transition
+ conn.getBendpoints().clear();
+
+ List<Pos> points = positionProvider.getPoints(trans);
+ if (points!=null && !points.isEmpty()) {
+ Iterator<Pos> it = points.iterator();
+
+ // first is label position
+ Pos pos = it.next();
+ ConnectionDecorator cd = conn.getConnectionDecorators().get(1);
+ Graphiti.getGaService().setLocation(cd.getGraphicsAlgorithm(), pos.getX(), pos.getY());
+
+ // remaining are bend points
+ while (it.hasNext()) {
+ pos = it.next();
+ Point pt = Graphiti.getGaService().createPoint(pos.getX(), pos.getY());
+ conn.getBendpoints().add(pt);
+ }
+ }
+ else if (src==dst) {
+ ILocation begin = Graphiti.getPeService().getLocationRelativeToDiagram(conn.getStart());
+ Point pt = Graphiti.getGaService().createPoint(begin.getX(), begin.getY()+StateGraphSupport.MARGIN*3);
+ conn.getBendpoints().add(pt);
+ }
+ }
+ }
+ }
+
+ private <T extends StateGraphNode> List<PosAndSize> getPositions(List<T> nodes, IPositionProvider positionProvider, double scaleX) {
+ ArrayList<PosAndSize> result = new ArrayList<PosAndSize>(nodes.size());
+
+ if (nodes.isEmpty())
+ return result;
+
+ int n = 0;
+ for (T node : nodes) {
+ PosAndSize pt = positionProvider.getPosition(node);
+ result.add(pt);
+ if (pt==null)
+ n++;
+ }
+
+ int delta = (int) (scaleX / (n+1));
+ int pos = delta;
+
+ int h = StateGraphSupport.MARGIN;
+ if (nodes.get(0) instanceof State)
+ h = StateGraphSupport.MARGIN + StateGraphSupport.DEFAULT_SIZE_Y/4;
+ else if (nodes.get(0) instanceof ChoicePoint)
+ h = StateGraphSupport.MARGIN + StateGraphSupport.DEFAULT_SIZE_Y/2;
+ else if (nodes.get(0) instanceof TrPoint)
+ h = StateGraphSupport.MARGIN;
+ else {
+ assert(false): "unexpected sub type";
+ }
+
+ for (int i=0; i<nodes.size(); ++i) {
+ if (result.get(i)==null) {
+ PosAndSize pt = new PosAndSize(
+ pos,
+ h,
+ 0,
+ 0
+ );
+ result.set(i, pt);
+
+ pos += delta;
+ }
+ }
+
+ return result;
+ }
+
+ private void addStateGraphNodes(List<? extends StateGraphNode> nodes, IPositionProvider positionProvider, ContainerShape sgShape,
+ IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
+
+ List<PosAndSize> positions = getPositions(nodes, positionProvider, sgShape.getGraphicsAlgorithm().getWidth());
+
+ int idx = 0;
+ for (StateGraphNode node : nodes) {
+ addStateGraphNode(node, sgShape, positions.get(idx), fp, node2anchor);
+ ++idx;
+ }
+ }
+
+ private void addStateGraphNode(StateGraphNode tp, ContainerShape sgShape, PosAndSize pos,
+ IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
+ AddContext addContext = new AddContext();
+ addContext.setNewObject(tp);
+ addContext.setTargetContainer(sgShape);
+ addContext.setX(pos.getX());
+ addContext.setY(pos.getY());
+ if (pos.getWidth()>0 && pos.getHeight()>0) {
+ addContext.setWidth(pos.getWidth());
+ addContext.setHeight(pos.getHeight());
+ }
+
+ ContainerShape pe = (ContainerShape) fp.addIfPossible(addContext);
+ assert(pe!=null): tp.eClass().getName()+" should have been created";
+ assert(!pe.getAnchors().isEmpty()): tp.eClass().getName()+" should have an anchor";
+ node2anchor.put(getKey(tp), pe.getAnchors().get(0));
+ }
+
+ private void updateInitialPoint(Shape shape, IPositionProvider positionProvider, IFeatureProvider fp) {
+ if (shape==null)
+ return;
+
+ StateGraph sg = (StateGraph) fp.getBusinessObjectForPictogramElement(shape);
+ PosAndSize ps = positionProvider.getPosition(sg);
+ if (ps==null)
+ return;
+
+ // relocate and resize the invisible rectangle
+ GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
+
+ Graphiti.getLayoutService().setLocationAndSize(
+ ga,
+ ps.getX(),
+ ps.getY(),
+ ps.getWidth(),
+ ps.getHeight()
+ );
+
+ // have to call the layout to adjust the visible border
+ LayoutContext lc = new LayoutContext(shape);
+ fp.layoutIfPossible(lc);
+ }
+
+ private void updateStateGraphNodes(List<? extends StateGraphNode> nodes, List<Shape> shapes, IPositionProvider positionProvider, IFeatureProvider fp) {
+
+ ILinkService linkService = Graphiti.getLinkService();
+ IGaService gaService = Graphiti.getGaService();
+
+ for (StateGraphNode node : nodes) {
+ PosAndSize ps = positionProvider.getPosition(node);
+ if (ps==null)
+ continue;
+
+ // TODO: sub-optimal since quadratic effort - use combined list for nodes and shapes or similar solution
+ for (Shape shape : shapes) {
+ EObject bo = linkService.getBusinessObjectForLinkedPictogramElement(shape);
+ if (bo==node) {
+ // relocate and resize the invisible rectangle
+ GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
+// System.out.println(node + ": "+ga.getX()+" "+ga.getY()+" "+ga.getWidth()+" "+ga.getHeight());
+// System.out.println(" -> "+ps.getX()+" "+ps.getY()+" "+ps.getWidth()+" "+ps.getHeight());
+
+ int margin = 0;
+ if (node instanceof State)
+ margin = StateSupport.MARGIN;
+ else if (node instanceof TrPoint)
+ margin = TrPointSupport.MARGIN;
+
+ gaService.setLocationAndSize(
+ ga,
+ ps.getX()-margin,
+ ps.getY()-margin,
+ ps.getWidth()+2*margin,
+ ps.getHeight()+2*margin
+ );
+
+ // have to call the layout to adjust the visible border
+ LayoutContext lc = new LayoutContext(shape);
+ fp.layoutIfPossible(lc);
+
+ // update position of sub items
+ if(shape instanceof ContainerShape){
+ ContainerShape container = (ContainerShape) shape;
+ for(Shape child : container.getChildren()){
+ EObject childBo = linkService.getBusinessObjectForLinkedPictogramElement(child);
+ if(!(childBo instanceof StateGraphNode))
+ continue;
+
+ double[] relPos = positionProvider.getSubPosition((StateGraphNode) childBo);
+ if(relPos != null)
+ gaService.setLocation(child.getGraphicsAlgorithm(), (int)(relPos[0] * ps.getWidth()), (int)(relPos[1]*ps.getHeight()));
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ private void updateTransitions(Map<Transition, Connection> transitions, IPositionProvider positionProvider, ContainerShape sgShape,
+ IFeatureProvider fp, HashMap<String, Anchor> node2anchor) {
+
+ for(Entry<Transition, Connection> e: transitions.entrySet()){
+ Transition trans = e.getKey();
+ Connection conn = e.getValue();
+
+ String from = (trans instanceof InitialTransition)? INITIAL:getKey(((NonInitialTransition)trans).getFrom());
+ String to = getKey(trans.getTo());
+ Anchor newSrc = node2anchor.get(from);
+ Anchor newDst = node2anchor.get(to);
+
+ assert(newSrc!=null && newDst!=null): "transition endpoints must be present";
+
+ if(conn.getStart()!=newSrc)
+ conn.setStart(newSrc);
+ if(conn.getEnd()!=newDst)
+ conn.setEnd(newDst);
+
+ List<Pos> points = positionProvider.getPoints(trans);
+ Iterator<Pos> it = points.iterator();
+ if (points==null || points.isEmpty())
+ continue;
+
+ // first is label position
+ Pos pos = it.next();
+ ConnectionDecorator cd = conn.getConnectionDecorators().get(1);
+ Graphiti.getGaService().setLocation(cd.getGraphicsAlgorithm(), pos.getX(), pos.getY());
+
+ if (conn instanceof FreeFormConnection) {
+ FreeFormConnection fconn = (FreeFormConnection) conn;
+
+ // remaining are bend points
+ fconn.getBendpoints().clear();
+ List<Point> bendpoints = new ArrayList<Point>();
+ while (it.hasNext()) {
+ pos = it.next();
+ Point pt = Graphiti.getGaService().createPoint(pos.getX(), pos.getY());
+ bendpoints.add(pt);
+ }
+ fconn.getBendpoints().addAll(bendpoints);
+ }
+ }
+ }
+
+ private void getAnchors(State state, PictogramElement stateShape, final HashMap<String, Anchor> node2anchor) {
+ if (stateShape instanceof ContainerShape) {
+ node2anchor.put(getKey(state), ((ContainerShape)stateShape).getAnchors().get(0));
+ for (Shape child : ((ContainerShape) stateShape).getChildren()) {
+ if (child instanceof ContainerShape) {
+ ContainerShape childShape = (ContainerShape) child;
+ if (!childShape.getAnchors().isEmpty()) {
+ if (!childShape.getLink().getBusinessObjects().isEmpty()) {
+ EObject obj = childShape.getLink().getBusinessObjects().get(0);
+ if (obj instanceof EntryPoint || obj instanceof ExitPoint) {
+ node2anchor.put(getKey(obj, true), childShape.getAnchors().get(0));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private String getKey(EObject obj) {
+ return getKey(obj, false);
+ }
+
+ private String getKey(EObject obj, boolean subTp) {
+ if (obj instanceof TrPoint) {
+ TrPoint tp = (TrPoint) obj;
+ if (!subTp)
+ return TP+tp.getName();
+ else {
+ if (tp.eContainer().eContainer() instanceof State) {
+ State s = (State) tp.eContainer().eContainer();
+ return TP+tp.getName()+SEP+s.getName();
+ }
+ else {
+ assert(false): "State expected";
+ }
+ }
+ }
+ else if (obj instanceof State) {
+ return STATE+((State)obj).getName();
+ }
+ else if (obj instanceof ChoicePoint) {
+ return CP+((ChoicePoint)obj).getName();
+ }
+ else if (obj instanceof TransitionTerminal) {
+ TransitionTerminal tt = (TransitionTerminal) obj;
+ if (tt instanceof ChoicepointTerminal) {
+ return CP+((ChoicepointTerminal)tt).getCp().getName();
+ }
+ else if (tt instanceof StateTerminal) {
+ return STATE+((StateTerminal)tt).getState().getName();
+ }
+ else if (tt instanceof SubStateTrPointTerminal) {
+ SubStateTrPointTerminal sstt = (SubStateTrPointTerminal) tt;
+ return TP+sstt.getTrPoint().getName()+SEP+sstt.getState().getName();
+ }
+ else if (tt instanceof TrPointTerminal) {
+ return TP+((TrPointTerminal)tt).getTrPoint().getName();
+ }
+ else {
+ assert(false): "unexpected sub type";
+ }
+ }
+ assert(false): "unexpected type";
+ return null;
+ }
+
+
+ private void checkDuplicates(List<? extends StateGraphItem> items) {
+ FSMNameProvider fsmNameProvider = FSMSupportUtil.getInstance().getFSMNameProvider();
+ for (StateGraphItem item : items) {
+ if (items.indexOf(item)!=items.lastIndexOf(item)) {
+ Assert.isTrue(
+ items.indexOf(item)==items.lastIndexOf(item),
+ "multiple occurrences of "+fsmNameProvider.getFullPath(item));
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramExtensions.xtend b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramExtensions.xtend
new file mode 100644
index 000000000..6905d6821
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramExtensions.xtend
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.support.util
+
+import org.eclipse.graphiti.mm.pictograms.PictogramElement
+import org.eclipse.graphiti.services.Graphiti
+import org.eclipse.graphiti.features.context.IPictogramElementContext
+import org.eclipse.emf.ecore.EObject
+
+class DiagramExtensions {
+
+ def static <T extends PictogramElement> getCastedPe(IPictogramElementContext ctx){
+ ctx.pictogramElement as T
+ }
+
+ def static <T extends EObject> getCastedBo(PictogramElement pe) {
+ Graphiti.linkService.getBusinessObjectForLinkedPictogramElement(pe) as T
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/FSMSupportUtil.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/FSMSupportUtil.java
new file mode 100644
index 000000000..d283a8b1a
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/FSMSupportUtil.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2014 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.support.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.etrice.core.fsm.fSM.ChoicePoint;
+import org.eclipse.etrice.core.fsm.fSM.ChoicepointTerminal;
+import org.eclipse.etrice.core.fsm.fSM.FSMFactory;
+import org.eclipse.etrice.core.fsm.fSM.ModelComponent;
+import org.eclipse.etrice.core.fsm.fSM.RefinedState;
+import org.eclipse.etrice.core.fsm.fSM.RefinedTransition;
+import org.eclipse.etrice.core.fsm.fSM.State;
+import org.eclipse.etrice.core.fsm.fSM.StateGraph;
+import org.eclipse.etrice.core.fsm.fSM.StateTerminal;
+import org.eclipse.etrice.core.fsm.fSM.SubStateTrPointTerminal;
+import org.eclipse.etrice.core.fsm.fSM.TrPoint;
+import org.eclipse.etrice.core.fsm.fSM.TrPointTerminal;
+import org.eclipse.etrice.core.fsm.fSM.Transition;
+import org.eclipse.etrice.core.fsm.fSM.TransitionTerminal;
+import org.eclipse.etrice.core.fsm.naming.FSMNameProvider;
+import org.eclipse.etrice.core.fsm.ui.FSMUiModule;
+import org.eclipse.etrice.core.fsm.util.FSMHelpers;
+import org.eclipse.etrice.core.fsm.util.FSMNewNamingUtil;
+import org.eclipse.etrice.core.fsm.validation.FSMValidationUtil;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+import org.eclipse.graphiti.mm.pictograms.Connection;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.services.Graphiti;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+/**
+ * Shared business logic, side-effect free util methods
+ */
+public class FSMSupportUtil {
+
+
+ private static FSMSupportUtil instance = null;
+
+ /**
+ * @return the instance
+ */
+ public static FSMSupportUtil getInstance() {
+ if (instance==null) {
+ // this class has members that have to be filled by the FSMUi injector
+ Injector injector = FSMUiModule.getInjector();
+ instance = injector.getInstance(FSMSupportUtil.class);
+ }
+ return instance;
+ }
+
+ @Inject
+ private FSMHelpers fsmHelpers;
+ @Inject
+ private FSMValidationUtil fsmValidationUtil;
+ @Inject
+ private FSMNameProvider fsmNameProvider;
+ @Inject
+ private FSMNewNamingUtil fsmNewNamingUtil;
+
+ /**
+ * @return the roomHelpers
+ */
+ public FSMHelpers getFSMHelpers() {
+ return fsmHelpers;
+ }
+
+ /**
+ * @return the validationUtil
+ */
+ public FSMValidationUtil getFSMValidationUtil() {
+ return fsmValidationUtil;
+ }
+
+ /**
+ * @return the roomUtil
+ */
+ public FSMNewNamingUtil getFSMNewNamingUtil() {
+ return fsmNewNamingUtil;
+ }
+
+ /**
+ * @return the roomNameProvider
+ */
+ public FSMNameProvider getFSMNameProvider() {
+ return fsmNameProvider;
+ }
+
+ public boolean isInherited(Diagram diag, EObject obj) {
+ return isInherited(getModelComponent(diag), obj);
+ }
+
+ public boolean isInherited(ModelComponent mc, EObject obj) {
+ if (obj instanceof StateGraph)
+ obj = obj.eContainer();
+ else if (obj instanceof ModelComponent)
+ // the next line states: if a ModelComponent has no base class, then it is not inherited.
+ // And vice versa: if it has a base class it is inherited
+ // QUESTION: is this correct?
+ // However, this method isn't called with an obj instanceof ModelComponent
+ return ((ModelComponent) obj).getBase() != null;
+
+ return obj instanceof RefinedState || obj instanceof RefinedTransition || !EcoreUtil.isAncestor(mc, obj);
+ }
+
+ public boolean isOwnedBy(Diagram diag, EObject obj) {
+ return isOwnedBy(getModelComponent(diag), obj);
+ }
+
+ public boolean isOwnedBy(ModelComponent mc, EObject obj) {
+ return EcoreUtil.isAncestor(mc, obj);
+ }
+
+ public boolean showAsInherited(Diagram diag, State obj) {
+
+ if (obj instanceof RefinedState)
+ return true;
+
+ return fsmHelpers.getModelComponent(obj)!=getModelComponent(diag);
+ }
+
+ public Diagram getDiagram(GraphicsAlgorithm ga) {
+ if (ga.eContainer() instanceof GraphicsAlgorithm)
+ return getDiagram((GraphicsAlgorithm)ga.eContainer());
+ return getDiagram(ga.getPictogramElement());
+ }
+
+ public Diagram getDiagram(PictogramElement pe) {
+ while (pe.eContainer()!=null) {
+ if (pe.eContainer() instanceof Diagram)
+ return (Diagram) pe.eContainer();
+ pe = (PictogramElement) pe.eContainer();
+ }
+ return null;
+ }
+
+ public ModelComponent getModelComponent(Diagram diag) {
+ EObject bo = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(diag);
+ if (bo instanceof ModelComponent)
+ return (ModelComponent) bo;
+ return null;
+ }
+
+ public State getTargettingState(State state, Diagram diagram) {
+ ModelComponent mc = getModelComponent(diagram);
+ return fsmHelpers.getTargettingState(state, mc);
+ }
+
+ /**
+ * This method exploits the fact that the immediate children of the diagram are
+ * associated with the state graphs.
+ *
+ * @param shape
+ * @return the container shape that is associated with the state graph of the diagram
+ */
+ public ContainerShape getStateGraphContainer(ContainerShape shape) {
+ while (shape!=null) {
+ ContainerShape parent = shape.getContainer();
+ if (parent instanceof Diagram)
+ return shape;
+ shape = parent;
+ }
+ return null;
+ }
+
+ public StateGraph getStateGraph(ContainerShape cs, IFeatureProvider fp) {
+ ContainerShape shape = getStateGraphContainer(cs);
+ Object bo = fp.getBusinessObjectForPictogramElement(shape);
+ if (bo instanceof StateGraph)
+ return (StateGraph) bo;
+ else
+ assert(false): "state graph expected";
+
+ return null;
+ }
+
+ public TransitionTerminal getTransitionTerminal(Anchor anchor, IFeatureProvider fp) {
+ if (anchor != null) {
+ Object obj = fp.getBusinessObjectForPictogramElement(anchor.getParent());
+ if (obj instanceof TrPoint) {
+ Object parent = fp.getBusinessObjectForPictogramElement((ContainerShape) anchor.getParent().eContainer());
+ if (parent instanceof State) {
+ State state = (parent instanceof RefinedState)? ((RefinedState)parent).getTarget() : (State)parent;
+ SubStateTrPointTerminal sstpt = FSMFactory.eINSTANCE.createSubStateTrPointTerminal();
+ sstpt.setState(state);
+ sstpt.setTrPoint((TrPoint) obj);
+ return sstpt;
+ }
+ else {
+ TrPointTerminal tpt = FSMFactory.eINSTANCE.createTrPointTerminal();
+ tpt.setTrPoint((TrPoint) obj);
+ return tpt;
+ }
+ }
+ else if (obj instanceof State) {
+ State state = (obj instanceof RefinedState)? ((RefinedState)obj).getTarget() : (State)obj;
+ StateTerminal st = FSMFactory.eINSTANCE.createStateTerminal();
+ st.setState(state);
+ return st;
+ }
+ else if (obj instanceof ChoicePoint) {
+ ChoicepointTerminal ct = FSMFactory.eINSTANCE.createChoicepointTerminal();
+ ct.setCp((ChoicePoint) obj);
+ return ct;
+ }
+ }
+ return null;
+ }
+
+ public boolean isInitialPoint(Anchor anchor, IFeatureProvider fp) {
+ if (anchor!=null) {
+ Object obj = fp.getBusinessObjectForPictogramElement(anchor.getParent());
+ if (obj instanceof StateGraph) {
+ Object parent = fp.getBusinessObjectForPictogramElement((ContainerShape) anchor.getParent().eContainer());
+ if (parent instanceof StateGraph)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean canConnect(Anchor asrc, Anchor atgt, ContainerShape cs, IFeatureProvider fp) {
+ return canConnect(asrc, atgt, null, cs, fp);
+ }
+
+ public boolean canConnect(Anchor asrc, Anchor atgt, Transition trans, ContainerShape cs, IFeatureProvider fp) {
+ TransitionTerminal src = getTransitionTerminal(asrc, fp);
+ TransitionTerminal tgt = getTransitionTerminal(atgt, fp);
+
+ if (src==null && !isInitialPoint(asrc, fp))
+ return false;
+ if (tgt==null)
+ return false;
+
+ StateGraph sg = getStateGraph(cs, fp);
+ if (sg==null)
+ return false;
+
+ return fsmValidationUtil.isConnectable(src, tgt, trans, sg).isOk();
+ }
+
+ public List<Transition> getTransitions(Diagram diagram, IFeatureProvider fp) {
+ List<Transition> transitions = new ArrayList<Transition>();
+ for (Connection conn : diagram.getConnections()) {
+ Object bo = fp.getBusinessObjectForPictogramElement(conn);
+ if (bo instanceof Transition)
+ transitions.add((Transition) bo);
+ }
+ return transitions;
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/ModelEditingUtil.xtend b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/ModelEditingUtil.xtend
new file mode 100644
index 000000000..357f254e6
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/ModelEditingUtil.xtend
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2017 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.fsm.support.util
+
+import java.util.HashMap
+import org.eclipse.etrice.core.fsm.fSM.FSMFactory
+import org.eclipse.etrice.core.fsm.fSM.ModelComponent
+import org.eclipse.etrice.core.fsm.fSM.RefinedState
+import org.eclipse.etrice.core.fsm.fSM.State
+import org.eclipse.etrice.core.fsm.fSM.StateGraph
+import org.eclipse.graphiti.features.IFeatureProvider
+import org.eclipse.graphiti.mm.pictograms.ContainerShape
+
+/**
+ * Shared model editing
+ */
+class ModelEditingUtil {
+
+ def static public RefinedState getOrCreateRefinedStateFor(State s, ModelComponent mc) {
+ val target2rs = new HashMap<State, RefinedState>();
+ for (State st : mc.getStateMachine().getStates()) {
+ if (st instanceof RefinedState)
+ target2rs.put((st as RefinedState).getTarget(), st as RefinedState);
+ }
+
+ var RefinedState rs = null;
+
+ // do we already have a RefinedState pointing to s?
+ if (target2rs.containsKey(s)) {
+ rs = target2rs.get(s);
+ }
+ else {
+ // we have to create one and place it in the best fitting context
+ var StateGraph sg = null;
+ var State parent = s;
+ var break = false;
+ while (parent.eContainer().eContainer() instanceof State && !break) {
+ parent = s.eContainer().eContainer() as State;
+ if (target2rs.containsKey(parent)) {
+ val bestFitting = target2rs.get(parent);
+ if (bestFitting.getSubgraph()===null)
+ bestFitting.setSubgraph(FSMFactory.eINSTANCE.createStateGraph());
+ sg = bestFitting.getSubgraph();
+ break = true;
+ }
+ }
+
+ if (sg===null)
+ sg = mc.getStateMachine();
+
+ rs = FSMFactory.eINSTANCE.createRefinedState();
+ rs.setTarget(s);
+ sg.getStates().add(rs);
+ }
+ return rs;
+ }
+
+
+
+ def static public StateGraph getOrCreateSubGraphOfRefinedStateFor(State s, ModelComponent mc) {
+ val rs = getOrCreateRefinedStateFor(s, mc);
+
+ if (rs.getSubgraph()===null)
+ rs.setSubgraph(FSMFactory.eINSTANCE.createStateGraph());
+
+ return rs.getSubgraph();
+ }
+
+ def static public StateGraph insertRefinedState(StateGraph sg, ModelComponent mc, ContainerShape targetContainer, IFeatureProvider fp) {
+ val sg2 = getOrCreateSubGraphOfRefinedStateFor(sg.eContainer() as State, mc);
+ fp.link(targetContainer, sg2);
+ return sg2;
+ }
+} \ No newline at end of file

Back to the top