diff options
24 files changed, 1179 insertions, 1026 deletions
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 9f28579e5..150202ee5 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 @@ -27,4 +27,5 @@ Export-Package: org.eclipse.etrice.ui.behavior.fsm.actioneditor, 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..e2ca9158b 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,7 +16,7 @@ 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.etrice.ui.behavior.fsm.support.util.DiagramEditingUtil; import org.eclipse.graphiti.dt.IDiagramTypeProvider; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.mm.pictograms.Diagram; @@ -51,7 +51,7 @@ public class PopulateDiagramCommand extends RecordingCommand { StateGraphContext tree = StateGraphContext.createContextTree(mc, injector); //System.out.println(tree); - FSMSupportUtil.getInstance().addStateGraph(tree, diagram, fp); + DiagramEditingUtil.getInstance().addStateGraph(tree, diagram, fp); 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 index 867ab3953..01b3a1a2f 100644 --- 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 @@ -16,8 +16,8 @@ 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 org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil; import com.google.inject.Injector; 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 b2f2d5373..bbf2f7a10 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.IActionCodeEditor; import org.eclipse.etrice.ui.behavior.fsm.actioneditor.preferences.PreferenceConstants; import org.eclipse.etrice.ui.behavior.fsm.detailcode.IDetailExpressionProvider; -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 7ff1866c3..dc333ed18 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/AbstractFSMEditor.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMEditor.java index 389a9ff45..1e268175f 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 @@ -28,7 +28,7 @@ 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.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; 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 26e08296e..39cc9655c 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 @@ -17,7 +17,7 @@ import java.io.File; 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.editor.DiagramExporter; import org.eclipse.etrice.ui.common.base.support.DiagramAccessBase; import org.eclipse.ui.PlatformUI; 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..66c445dc4 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; @@ -123,7 +125,7 @@ public class ChoicePointSupport { boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg); if (inherited) { - sg = FSMSupportUtil.getInstance().insertRefinedState(sg, mc, targetContainer, getFeatureProvider()); + sg = ModelEditingUtil.insertRefinedState(sg, mc, targetContainer, getFeatureProvider()); } // create choice point and add it 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 index 3be1be189..97b86b5d6 100644 --- 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 @@ -27,6 +27,7 @@ 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.behavior.fsm.support.util.FSMSupportUtil; import org.eclipse.etrice.ui.common.base.support.DiagramAccessBase; import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; import org.eclipse.graphiti.mm.algorithms.Text; 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..6d194add9 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 @@ -18,6 +18,8 @@ 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.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; @@ -216,7 +218,7 @@ public class DiagramUpdateFeature extends AbstractUpdateFeature { 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); } 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 406140db9..000000000 --- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/FSMSupportUtil.java +++ /dev/null @@ -1,1002 +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; - } - - // TODO: remove unused method - private 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) - // 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(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/InitialPointSupport.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/InitialPointSupport.java index aa55c2c6b..6717906c0 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 @@ -18,6 +18,8 @@ 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; @@ -96,7 +98,7 @@ public class InitialPointSupport { boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg); if (inherited) { ModelComponent mc = FSMSupportUtil.getInstance().getModelComponent(getDiagram()); - sg = FSMSupportUtil.getInstance().insertRefinedState(sg, mc, targetContainer, getFeatureProvider()); + sg = ModelEditingUtil.insertRefinedState(sg, mc, targetContainer, getFeatureProvider()); } // We don't create anything here since in the model the initial point is 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..1a8176418 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 @@ -26,6 +26,8 @@ import org.eclipse.etrice.core.fsm.fSM.Transition; import org.eclipse.etrice.ui.behavior.fsm.commands.StateGraphContext; 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; @@ -319,7 +321,7 @@ public class StateGraphSupport { // 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 +333,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 +345,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"; @@ -403,7 +405,7 @@ public class StateGraphSupport { if (context instanceof StateGraphUpdateContext) { StateGraphContext 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/StateSupport.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/StateSupport.java index 36502564f..bdb254a00 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; @@ -158,7 +161,7 @@ public class StateSupport { boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg); if (inherited) { - sg = FSMSupportUtil.getInstance().insertRefinedState(sg, ac, targetContainer, getFeatureProvider()); + sg = ModelEditingUtil.insertRefinedState(sg, ac, targetContainer, getFeatureProvider()); } // create new State and add it @@ -525,7 +528,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 @@ -588,7 +591,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); @@ -828,7 +831,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..aa1d8df9f 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; @@ -147,7 +149,7 @@ public class TrPointSupport { 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()); + 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 9f09d0234..cc917e15d 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; @@ -269,7 +271,7 @@ public class TransitionSupport { ContainerShape targetContainer = FSMSupportUtil.getInstance().getStateGraphContainer((ContainerShape) context.getSourcePictogramElement().eContainer()); boolean inherited = FSMSupportUtil.getInstance().isInherited(getDiagram(), sg); if (inherited) { - sg = FSMSupportUtil.getInstance().insertRefinedState(sg, mc, targetContainer, getFeatureProvider()); + 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..af43273a6 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/DiagramEditingUtil.java @@ -0,0 +1,694 @@ +/******************************************************************************* + * 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.commands.StateGraphContext; +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.StateGraphSupport; +import org.eclipse.etrice.ui.behavior.fsm.support.StateSupport; +import org.eclipse.etrice.ui.behavior.fsm.support.TrPointSupport; +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; + +/** + * 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, 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); + } + } + + + 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(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; + } + + + 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(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)); + } + + 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; + } + } + } + } + + 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/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..8ccf50015 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/support/util/FSMSupportUtil.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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) { + 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(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()); + } + + 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..003a040ef --- /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) 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.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 diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/xtend-gen/org/eclipse/etrice/ui/behavior/fsm/support/util/ModelEditingUtil.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/xtend-gen/org/eclipse/etrice/ui/behavior/fsm/support/util/ModelEditingUtil.java new file mode 100644 index 000000000..804a112f8 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/xtend-gen/org/eclipse/etrice/ui/behavior/fsm/support/util/ModelEditingUtil.java @@ -0,0 +1,100 @@ +/** + * 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 com.google.common.base.Objects; +import java.util.HashMap; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +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 + */ +@SuppressWarnings("all") +public class ModelEditingUtil { + public static RefinedState getOrCreateRefinedStateFor(final State s, final ModelComponent mc) { + final HashMap<State, RefinedState> target2rs = new HashMap<State, RefinedState>(); + StateGraph _stateMachine = mc.getStateMachine(); + EList<State> _states = _stateMachine.getStates(); + for (final State st : _states) { + if ((st instanceof RefinedState)) { + State _target = ((RefinedState) st).getTarget(); + target2rs.put(_target, ((RefinedState) st)); + } + } + RefinedState rs = null; + boolean _containsKey = target2rs.containsKey(s); + if (_containsKey) { + RefinedState _get = target2rs.get(s); + rs = _get; + } else { + StateGraph sg = null; + State parent = s; + boolean break_ = false; + while (((parent.eContainer().eContainer() instanceof State) && (!break_))) { + { + EObject _eContainer = s.eContainer(); + EObject _eContainer_1 = _eContainer.eContainer(); + parent = ((State) _eContainer_1); + boolean _containsKey_1 = target2rs.containsKey(parent); + if (_containsKey_1) { + final RefinedState bestFitting = target2rs.get(parent); + StateGraph _subgraph = bestFitting.getSubgraph(); + boolean _equals = Objects.equal(_subgraph, null); + if (_equals) { + StateGraph _createStateGraph = FSMFactory.eINSTANCE.createStateGraph(); + bestFitting.setSubgraph(_createStateGraph); + } + StateGraph _subgraph_1 = bestFitting.getSubgraph(); + sg = _subgraph_1; + break_ = true; + } + } + } + boolean _equals = Objects.equal(sg, null); + if (_equals) { + StateGraph _stateMachine_1 = mc.getStateMachine(); + sg = _stateMachine_1; + } + RefinedState _createRefinedState = FSMFactory.eINSTANCE.createRefinedState(); + rs = _createRefinedState; + rs.setTarget(s); + EList<State> _states_1 = sg.getStates(); + _states_1.add(rs); + } + return rs; + } + + public static StateGraph getOrCreateSubGraphOfRefinedStateFor(final State s, final ModelComponent mc) { + final RefinedState rs = ModelEditingUtil.getOrCreateRefinedStateFor(s, mc); + StateGraph _subgraph = rs.getSubgraph(); + boolean _equals = Objects.equal(_subgraph, null); + if (_equals) { + StateGraph _createStateGraph = FSMFactory.eINSTANCE.createStateGraph(); + rs.setSubgraph(_createStateGraph); + } + return rs.getSubgraph(); + } + + public static StateGraph insertRefinedState(final StateGraph sg, final ModelComponent mc, final ContainerShape targetContainer, final IFeatureProvider fp) { + EObject _eContainer = sg.eContainer(); + final StateGraph sg2 = ModelEditingUtil.getOrCreateSubGraphOfRefinedStateFor(((State) _eContainer), mc); + fp.link(targetContainer, sg2); + return sg2; + } +} diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/SupportUtil.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/SupportUtil.java index f4bea3ecb..d18fc5b9e 100644 --- a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/SupportUtil.java +++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/SupportUtil.java @@ -13,7 +13,7 @@ import org.eclipse.etrice.core.naming.RoomNameProvider; import org.eclipse.etrice.core.room.ActorClass; import org.eclipse.etrice.core.room.util.RoomHelpers; import org.eclipse.etrice.core.ui.RoomUiModule; -import org.eclipse.etrice.ui.behavior.fsm.support.FSMSupportUtil; +import org.eclipse.etrice.ui.behavior.fsm.support.util.FSMSupportUtil; import org.eclipse.graphiti.mm.pictograms.Diagram; import org.eclipse.graphiti.services.Graphiti; |