blob: 19e85f3c87425cfb6f62e0b3bf439d3cf53bb326 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 CEA LIST
* 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:
* Imen BOUDHIBA (CEA LIST) imen.boudhiba@cea.fr - initial API and implementation
*******************************************************************************/
package org.eclipse.efm.modeling.codegen.xlia.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.efm.modeling.codegen.xlia.core.MainCodeGenerator;
import org.eclipse.efm.modeling.codegen.xlia.statemachine.StatemachineCodeGenerator;
import org.eclipse.efm.modeling.codegen.xlia.util.StatemachineContext.CONTEXT;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.BehavioredClassifier;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Expression;
import org.eclipse.uml2.uml.FinalState;
import org.eclipse.uml2.uml.Interaction;
import org.eclipse.uml2.uml.InteractionFragment;
import org.eclipse.uml2.uml.Lifeline;
import org.eclipse.uml2.uml.Message;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Pseudostate;
import org.eclipse.uml2.uml.Region;
import org.eclipse.uml2.uml.State;
import org.eclipse.uml2.uml.StateMachine;
import org.eclipse.uml2.uml.TimeObservation;
import org.eclipse.uml2.uml.Transition;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.Vertex;
public class StatemachineContext {
public enum CONTEXT { INTERACTION , LIFELINE };
public StatemachineContext parentContext;
public CONTEXT transfoCtx;
public Lifeline coveredLifeline;
protected InteractionFragment interactionFragment;
public StateMachine statemachine;
public ArrayList<Message> inputMessage;
public ArrayList<Message> outputMessage;
public Map<Element, List<Constraint>> constraintMap;
public Map<NamedElement, List<TimeObservation>> timeObservationMap;
public Region region;
public Pseudostate initialState;
public State currentState;
public FinalState finalState;
public boolean isLastFragmentTransformation;
public Transition intermediateTransition;
// public StatemachineContext() {
// coveredLifeline = null;
//
// parentContext = null;
//
// statemachine = UmlFactory.createStateMachine("System");
//
// region = statemachine.getRegions().get(0);
//
// initializeState(statemachine.getName());
//
//
// }
//
/**
* Create a StatemachineContext for the Interaction element which initializes the constraints map
* @param interaction
*/
public StatemachineContext(Interaction interaction, CONTEXT context) {
parentContext = null;
transfoCtx = context;
coveredLifeline = null;
interactionFragment = null;
inputMessage = new ArrayList<Message>();
outputMessage = new ArrayList<Message>();
constraintMap = new HashMap<Element, List<Constraint>>();
initializeConstraintMap(interaction);
timeObservationMap = new HashMap<NamedElement, List<TimeObservation>>();
statemachine = null;
region = null;
isLastFragmentTransformation = false;
intermediateTransition = null;
}
public StatemachineContext(StatemachineContext parentCtx, Lifeline lifeline) {
parentContext = parentCtx;
transfoCtx = parentCtx.transfoCtx;
coveredLifeline = lifeline;
interactionFragment = null;
inputMessage = parentCtx.inputMessage;
outputMessage = parentCtx.outputMessage;
constraintMap = parentCtx.constraintMap;
timeObservationMap = parentCtx.timeObservationMap;
statemachine = UmlFactory.createStateMachine(lifeline.getName());
region = statemachine.getRegions().get(0);
isLastFragmentTransformation = false;
initializeState(lifeline.getName());
// Transition transition = UmlFactory.createTransition(region, "t_" + name, initialState, finalState);
//
// Property varX = UmlFactory.createVariable(statemachine, "X", UmlFactory.fifoIntType(42));
// Property varX = UmlFactory.createVariable(statemachine, "size_" + lifeline.getName(), UmlFactory.integerType());
// Property varY = UmlFactory.createVariable(statemachine, "top_" + lifeline.getName(), UmlFactory.integerType());
}
public StatemachineContext(Lifeline lifeline) {
this(new StatemachineContext(lifeline.getInteraction(), CONTEXT.INTERACTION), lifeline);
}
public StatemachineContext(StatemachineContext parentCtx, InteractionFragment element) {
parentContext = parentCtx;
coveredLifeline = parentCtx.coveredLifeline;
interactionFragment = element;
inputMessage = parentCtx.inputMessage;
outputMessage = parentCtx.outputMessage;
constraintMap = parentCtx.constraintMap;
timeObservationMap = parentCtx.timeObservationMap;
statemachine = parentCtx.statemachine;
region = parentCtx.currentState.createRegion(element.getName());
initializeState(element.getName());
}
private void initializeState(String name) {
initialState = UmlFactory.createInitialState(region, "init_" + name);
currentState = createTargetState("start_" + name);
Transition transition = createTransition(
"t_init_" + name, initialState, currentState);
finalState = (FinalState) region.createSubvertex(
"final_" + name, UMLPackage.eINSTANCE.getFinalState());
}
public void performNoCoveredFragment() {
if( (interactionFragment != null)
&& (region.getTransitions().size() == 1)
&& (region.getSubvertices().size() == 3)
&& (region.getTransitions().get(0).getSource() == initialState)
&& (region.getTransitions().get(0).getTarget() == currentState) )
{
region.getTransitions().get(0).setTarget(finalState);
region.getSubvertices().remove(currentState);
currentState = finalState;
System.out.println("performNoCoveredFragment for lifeline <" +
coveredLifeline.getName() + "> covered by fragment : " + interactionFragment.getName() );
}
}
///////////////////////////////////////////////////////////////////////////
// [COMPOSITE] STATE
///////////////////////////////////////////////////////////////////////////
public static State createCompositeState(Region region, String name) {
State state = (State) region.createSubvertex(name, UMLPackage.eINSTANCE.getState());
state.createRegion(name);
return( state );
}
public State createTargetState(String name) {
if( isLastFragmentTransformation ) {
// finalState.setName(name);
return finalState;
}
else {
State state = (State) region.createSubvertex(name, UMLPackage.eINSTANCE.getState());
return( state );
}
}
public State createIntermediateState(String name) {
State state = (State) region.createSubvertex(name, UMLPackage.eINSTANCE.getState());
return( state );
}
public State createNewState(String name) {
State state = (State) region.createSubvertex(name, UMLPackage.eINSTANCE.getState());
return( state );
}
///////////////////////////////////////////////////////////////////////////
// TRANSITION
///////////////////////////////////////////////////////////////////////////
public Transition createTransition(
String name, Vertex source, Vertex target) {
Transition transition = region.createTransition(name);
transition.setSource(source);
transition.setTarget(target);
return( transition );
}
public Transition createElseTransition(
String name, Vertex source, Vertex target) {
Transition transition = region.createTransition(name);
transition.setSource(source);
transition.setTarget(target);
Constraint constraint = transition.createGuard("ElseGuardConstraint");
Expression guardExpression = UMLFactory.eINSTANCE.createExpression();
guardExpression.setSymbol(StatemachineCodeGenerator.TRANSITION_GUARD_ELSE);
constraint.setSpecification(guardExpression);
return( transition );
}
public Transition createFinalTransition(
String name, Vertex source, Vertex target) {
Transition transition = region.createTransition(name);
transition.setSource(source);
transition.setTarget(target);
transition.createTrigger(StatemachineCodeGenerator.TRANSITION_TRIGGER_FINAL);
return( transition );
}
public Transition createFinalElseTransition(
String name, Vertex source, Vertex target) {
Transition transition = region.createTransition(name);
transition.setSource(source);
transition.setTarget(target);
transition.createTrigger(StatemachineCodeGenerator.TRANSITION_TRIGGER_FINAL);
Constraint constraint = transition.createGuard("ElseGuardConstraint");
Expression guardExpression = UMLFactory.eINSTANCE.createExpression();
guardExpression.setSymbol(StatemachineCodeGenerator.TRANSITION_GUARD_ELSE);
constraint.setSpecification(guardExpression);
return( transition );
}
public void addInputMessage(Message message){
if( ! inputMessage.contains(message) ) {
inputMessage.add(message);
}
}
public void addOutputMessage(Message message){
if( ! outputMessage.contains(message) ) {
outputMessage.add(message);
}
}
//data constraints
public void addElementConstraint(Element element, Constraint constraint) {
List<Constraint> list = constraintMap.get(element);
if( list == null ) {
list = new ArrayList<Constraint>();
constraintMap.put(element, list);
}
list.add(constraint);
}
public List<Constraint> getElementConstraints(Element element) {
return constraintMap.get(element);
}
public void initializeConstraintMap(Interaction interaction) {
for (Constraint constraint : interaction.getOwnedRules()) {
for (Element element : constraint.getConstrainedElements()) {
addElementConstraint(element, constraint);
}
}
}
// TODO time constraints
public void addElementTimeConstraint(Element element, Constraint constraint) {
List<Constraint> list = constraintMap.get(element);
if( list == null ) {
list = new ArrayList<Constraint>();
constraintMap.put(element, list);
}
list.add(constraint);
}
public List<Constraint> getElementTimeConstraints(Element element) {
return constraintMap.get(element);
}
public void initializeTimeConstraintMap(Interaction interaction) {
for (Constraint constraint : interaction.getOwnedRules()) {
for (Element element : constraint.getConstrainedElements()) {
addElementTimeConstraint(element, constraint);
}
}
}
//TODO time observations
public void addTimeObservation(NamedElement element, TimeObservation timeObservation) {
List<TimeObservation> list = timeObservationMap.get(element);
if( list == null ) {
list = new ArrayList<TimeObservation>();
timeObservationMap.put(element, list);
}
list.add(timeObservation);
}
public List<TimeObservation> getTimeObservation(NamedElement element) {
return timeObservationMap.get(element);
}
public void initializeTimeObservationMap(Interaction interaction) {
EObject eobj = interaction.eContainer();
EList<PackageableElement> packElems = null;
Boolean obsFound = false;
for( ; !obsFound && eobj != null ; eobj = eobj.eContainer() ) {
if (eobj instanceof Package){
packElems = ((Package)eobj).getPackagedElements();
for (PackageableElement packElt : packElems) {
if (packElt instanceof TimeObservation) {
obsFound = true;
break;
}
}
}
}
if (packElems != null) {
for (PackageableElement packElt : packElems) {
if (packElt instanceof TimeObservation) {
TimeObservation tObs = (TimeObservation) packElt ;
//System.err.println("Ici : "+tObs.getName());
//System.err.println("Ici : "+((OccurrenceSpecification)tObs.getEvent()).getName());
//mapOfTObs.put(((OccurrenceSpecification)tObs.getEvent()).getName(), tObs);
addTimeObservation(tObs.getEvent(), tObs);
}
}
}
}
public void toWriter(MainCodeGenerator mainCodegen, PrettyPrintWriter writer) {
if( (coveredLifeline != null) && (interactionFragment == null) ) {
Type representsType = coveredLifeline.getRepresents().getType();
if( representsType instanceof org.eclipse.uml2.uml.Class ) {
org.eclipse.uml2.uml.Class representsTypeClass = (org.eclipse.uml2.uml.Class) representsType;
mainCodegen.fClassFactory.transformClassLifelineDefinition(
representsTypeClass, statemachine, writer);
return;
}
}
toWriter(mainCodegen.fStatemachineFactory, writer);
}
public void toWriter(StatemachineCodeGenerator statemachineCodegen, PrettyPrintWriter writer) {
statemachineCodegen.transformStatemachine(
statemachine, inputMessage, writer);
}
public void addLocalVariable(String varName, Type varType) {
UmlFactory.createVariable(statemachine, varName, varType);
}
}