Bug 520516 [codegen] xlia code generation from Sequence Diagrams (via
StateMachines)
- Adding new component translation: Final transitions from composite
states (for combined fragments) ...
Change-Id: I63bf4de9d7b53b6f07f300289825beb8237709a8
Signed-off-by: Imen Boudhiba <imen.boudhiba@cea.fr>
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/InteractionCodeGenerator.java b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/InteractionCodeGenerator.java
index ad427d9..2b02d40 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/InteractionCodeGenerator.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/InteractionCodeGenerator.java
@@ -26,6 +26,7 @@
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ExecutionOccurrenceSpecification;
+import org.eclipse.uml2.uml.Expression;
import org.eclipse.uml2.uml.Gate;
import org.eclipse.uml2.uml.Interaction;
import org.eclipse.uml2.uml.InteractionConstraint;
@@ -37,11 +38,13 @@
import org.eclipse.uml2.uml.MessageOccurrenceSpecification;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.OpaqueBehavior;
+import org.eclipse.uml2.uml.OpaqueExpression;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Signal;
import org.eclipse.uml2.uml.State;
import org.eclipse.uml2.uml.TimeObservation;
import org.eclipse.uml2.uml.Transition;
+import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.ValueSpecification;
import org.eclipse.uml2.uml.internal.impl.BehaviorExecutionSpecificationImpl;
@@ -117,9 +120,32 @@
.appendEol(";");
}
- writer.appendTab2Eol("};");
+ writer.appendTab2Eol("}");
}
+
+ /**
+ * Lifeline Projection of dedicated Fragment Util
+ * @param lifeline
+ * @param fragments
+ * @return
+ */
+ private ArrayList<InteractionFragment> coveredFragments(
+ Lifeline lifeline, List<InteractionFragment> fragments) {
+ ArrayList<InteractionFragment> coveredFragmentList = new ArrayList<InteractionFragment>();
+
+ for( InteractionFragment iFragment : fragments ) {
+ if (iFragment.getCovereds().contains(lifeline)) {
+ if( !( iFragment instanceof ExecutionOccurrenceSpecification) ) {
+ coveredFragmentList.add(iFragment);
+ }
+ }
+ }
+
+ return coveredFragmentList;
+ }
+
+
/**
* performTransform an Interaction element to a writer
* @param element
@@ -148,7 +174,8 @@
}
}
// declare message
- writer.appendTab2("message ")
+ //writer.appendTab2("message ") // TODO modif until Diversity support
+ writer.appendTab2("signal ")
.append(message.getName());
if( (signature instanceof Signal)
@@ -170,6 +197,14 @@
}
writer.appendTabEol("// end message");
+ //function calls vectors
+ writer.appendTab2Eol("// function calls vectors");
+ writer.appendTab2Eol("public var vector globalProgramCallset;");
+ writer.appendTab2Eol("public var vector globalProgramTrace;");
+ writer.appendTab2Eol("public var vector globalTypeParamCalls;");
+ writer.appendTabEol("// end function calls vectors");
+
+
// Extra element needed to respect model semantic
// for( Lifeline lifeline : element.getLifelines() ) {
// writer.appendTab2("var fifo<integer , 30> " )
@@ -225,18 +260,26 @@
.append(lfContext.coveredLifeline.getName())
.appendEol(" //////////////////////////////////////////////////////////////////////////////");
- for( InteractionFragment iFragment : element.getFragments() ) {
-
- if( iFragment.getCovereds().contains(lfContext.coveredLifeline)) {
- // TODO lfContext.isLastFragmentTransformation ???
- lfContext.isLastFragmentTransformation = false;
- transformFragment(iFragment, lfContext, writer2);
+ ArrayList<InteractionFragment> coveredFragmentList =
+ coveredFragments(lfContext.coveredLifeline, element.getFragments());
+
+ lfContext.isLastFragmentTransformation = false;
+ int coveredFragmentListCount = coveredFragmentList.size()-1;
+ for( InteractionFragment iFragment : coveredFragmentList ) {
+ if(coveredFragmentList.indexOf(iFragment) == coveredFragmentListCount){
+ //Transition tr_final = lfContext.createTransition(
+ //"tr_final", lfContext.currentState, lfContext.finalState);
+ lfContext.isLastFragmentTransformation = true;
+
+// lfContext.currentState = lfContext.finalState;
}
+
+ transformFragment(iFragment, lfContext, writer2);
}
//TODO DELETE Transition tr_final
- Transition tr_final = lfContext.createTransition(
- "tr_final", lfContext.currentState, lfContext.finalState);
+// Transition tr_final = lfContext.createTransition(
+// "tr_final", lfContext.currentState, lfContext.finalState);
}
@@ -297,10 +340,10 @@
(BehaviorExecutionSpecification)iFragment, lfContext);
}
- //else if( iFragment instanceof ExecutionOccurrenceSpecification ) {
- // transformExecutionOccurrenceSpecification(
- // (ExecutionOccurrenceSpecification)iFragment, lfContext);
- //}
+ else if( iFragment instanceof ExecutionOccurrenceSpecification ) {
+ transformExecutionOccurrenceSpecification(
+ (ExecutionOccurrenceSpecification)iFragment, lfContext);
+ }
else {
performTransformError(this, iFragment);
@@ -353,31 +396,31 @@
private void transformInteractionOperand(InteractionOperand element,
StatemachineContext lfContext) {
- ArrayList<InteractionFragment> fragmentList = new ArrayList<InteractionFragment>();
+ lfContext.initialState.setName("init_" + element.getName());
+ lfContext.finalState.setName("final_" + element.getName());
- for( InteractionFragment iFragment : element.getFragments() ) {
- if (iFragment.getCovereds().contains(lfContext.coveredLifeline)) {
- fragmentList.add(iFragment);
- }
- }
-
- if( fragmentList.isEmpty() ) {
+ ArrayList<InteractionFragment> coveredFragmentList =
+ coveredFragments(lfContext.coveredLifeline, element.getFragments());
+
+ if( coveredFragmentList.isEmpty() ) {
lfContext.performNoCoveredFragment();
}
else {
lfContext.isLastFragmentTransformation = false;
- for( InteractionFragment iFragment : fragmentList ){ //element.getFragments() ) {
-
- if (fragmentList.indexOf(iFragment) == fragmentList.size()-1 ) {
+ int coveredFragmentListCount = coveredFragmentList.size()-1;
+ for( InteractionFragment iFragment : coveredFragmentList ) {
+ if (coveredFragmentList.indexOf(iFragment) == coveredFragmentListCount ) {
// lfContext.isLastFragmentTransformation
lfContext.isLastFragmentTransformation = true;
+
+// lfContext.currentState = lfContext.finalState;
}
transformFragment(iFragment, lfContext);
}
- //Transition tr_final = lfContext.createTransition(
- // "tr_final", lfContext.currentState, lfContext.finalState);
+// Transition tr_final = lfContext.createTransition(
+// "tr_final", lfContext.currentState, lfContext.finalState);
}
}
@@ -425,6 +468,7 @@
public void transformCombinedFragmentLoop(CombinedFragment element,
StatemachineContext lfContext) {
+
lfContext.currentState.setName("LoopFragment#" + element.getName());
Constraint loopGuard = element.getOperands().get(0).getGuard();
@@ -433,21 +477,26 @@
Transition entryLoop = lfContext.createTransition(
"tr_loop_first", lfContext.currentState, loopState);
UmlFactory.setGuard(entryLoop, loopGuard);
- // TODO Add effect behavior
entryLoop= lfContext.createTransition(
"tr_loop_not_first", lfContext.currentState, loopState);
UmlFactory.setGuard(entryLoop, loopGuard);
- // TODO Add effect behavior
-
+
+
lfContext.currentState = loopState;
// loop boucle with min/max index constraint
- Transition trLoop = lfContext.createTransition(
+ Transition trLoop = lfContext.createFinalTransition(
"tr_loop", loopState, loopState);
+ Property loopIndex = UmlFactory.createVariable(lfContext.statemachine,
+ "loopIndex_" + element.getName(), UmlFactory.integerType());
+
+ // Add effect behavior
+ //increment loopIndex
+ UmlFactory.addOpaqueBehaviorEffect(trLoop, loopIndex.getName()+" +=1 ;");
+
+
if( loopGuard instanceof InteractionConstraint ) {
- Property loopIndex = UmlFactory.createVariable(lfContext.statemachine,
- "loopIndex_" + element.getName(), UmlFactory.integerType());
UmlFactory.setGuard(trLoop, (InteractionConstraint) loopGuard, loopIndex);
}
@@ -455,17 +504,22 @@
UmlFactory.setGuard(trLoop, loopGuard);
}
- // quit loop transition
- State quitloopState = lfContext.createTargetState("quit_loop_" + element.getName());
- Transition quitLoop = lfContext.createElseTransition(
- "tr_quit_loop", loopState, quitloopState);
- lfContext.currentState = quitloopState;
+
StatemachineContext loopContext = new StatemachineContext(lfContext, element);
for( InteractionOperand iFragment : element.getOperands()) {
transformInteractionOperand(iFragment, loopContext);
}
+
+ // quit loop transition
+ State quitloopState = lfContext.createTargetState("quit_loop_" + element.getName());
+ Transition quitLoop = lfContext.createFinalElseTransition(
+ "final#tr_quit_loop", loopState, quitloopState);
+
+ lfContext.currentState = quitloopState;
+
+
}
@@ -499,7 +553,7 @@
transformInteractionOperand(iFragment, altContext);
- Transition exitRegionAlt = lfContext.createTransition(
+ Transition exitRegionAlt = lfContext.createFinalTransition(
"tr_alt_quit#" + iFragment.getName(), regionAltState, exitAltState);
}
@@ -533,7 +587,7 @@
}
- Transition exitSeq = lfContext.createTransition(
+ Transition exitSeq = lfContext.createFinalTransition(
"tr_seq_quit#" + element.getName(), lfContext.currentState, exitSeqState);
lfContext.currentState = exitSeqState;
}
@@ -655,7 +709,6 @@
for( InteractionOperand iFragment : element.getOperands()) {
transformInteractionOperand(iFragment, optContext);
}
-
}
@@ -665,10 +718,17 @@
* performTransform a ExecutionOccurrence element to a writer
* @param element
*/
-// public void transformExecutionOccurrenceSpecification(
-// ExecutionOccurrenceSpecification element, StatemachineContext lfContext) {
- //
-// }
+ public void transformExecutionOccurrenceSpecification(
+ ExecutionOccurrenceSpecification element, StatemachineContext lfContext) {
+
+ State execOccState = lfContext.createTargetState("execOcc#" + element.getName());
+
+ Transition execOccTrqns = lfContext.createTransition(
+ "tr_execOcc", lfContext.currentState, execOccState);
+
+
+ lfContext.currentState = execOccState;
+ }
/**
@@ -698,12 +758,22 @@
Interaction interaction = element.getInteraction();
if( interaction != null ) {
- for (InteractionFragment itFrag : interaction.getFragments()) {
- if( itFrag.getCovereds().contains(element) ) {
- // TODO lfContext.isLastFragmentTransformation ???
- lfContext.isLastFragmentTransformation = false;
- transformFragment(itFrag, lfContext);
+ ArrayList<InteractionFragment> coveredFragmentList =
+ coveredFragments(element, interaction.getFragments());
+
+ lfContext.isLastFragmentTransformation = false;
+ int coveredFragmentListCount = coveredFragmentList.size()-1;
+ for (InteractionFragment itFragment : coveredFragmentList) {
+ // TODO lfContext.isLastFragmentTransformation ???
+ if(coveredFragmentList.indexOf(itFragment) == coveredFragmentListCount){
+ //Transition tr_final = lfContext.createTransition(
+ //"tr_final", lfContext.currentState, lfContext.finalState);
+ lfContext.isLastFragmentTransformation = true;
+
+// lfContext.currentState = lfContext.finalState;
}
+
+ transformFragment(itFragment, lfContext);
}
}
}
@@ -720,17 +790,40 @@
BehaviorExecutionSpecification element,
StatemachineContext lfContext) {
if(element.getStart() instanceof ExecutionOccurrenceSpecification){
- BehaviorExecutionSpecification act = (BehaviorExecutionSpecification) element;
- State targetState = lfContext.createTargetState("targetBhExec#" + element.getName());
- lfContext.currentState.setName("BhExec#" + element.getName());
- Transition BH_tr= lfContext.createTransition(
- act.getName(), lfContext.currentState, targetState);
- lfContext.currentState = targetState;
- //String effect = act.getBehavior().toString().concat(";");
-
- UmlFactory.addOpaqueBehaviorEffect(BH_tr, act.getBehavior());
-
- transformElementConstraints(element.getStart(), BH_tr, lfContext);
+ BehaviorExecutionSpecification act = (BehaviorExecutionSpecification) element;
+
+ //StringBuffer valueBuffer = new StringBuffer(act.getBehavior().toString());
+
+ State targetState = lfContext.createTargetState("targetBhExec#" + element.getName());
+ lfContext.currentState.setName("BhExec#" + element.getName());
+ Transition BH_tr= lfContext.createTransition(
+ act.getName(), lfContext.currentState, targetState);
+
+ //String effect = act.getBehavior().toString().concat(";");
+
+ transformElementConstraints(element.getStart(), BH_tr, lfContext);
+
+ UmlFactory.addOpaqueBehaviorEffect(BH_tr, act.getBehavior());
+
+ //add constraint of finishOccurrence to the transition
+ if(element.getFinish() instanceof ExecutionOccurrenceSpecification ){
+
+ List<Constraint> constraints = lfContext.getElementConstraints(element.getFinish());
+ if( constraints != null ){
+// State targetState2 = lfContext.createTargetState("targetBhExec2#" + element.getName());
+// lfContext.currentState.setName("BhExec#2" + element.getName());
+// Transition BH_tr2= lfContext.createTransition(
+// act.getName()+"2", lfContext.currentState, targetState2);
+// lfContext.currentState = targetState2;
+//
+// transformElementConstraints(element.getFinish(), BH_tr2, lfContext);
+
+ for (Constraint constraint : constraints) {
+ UmlFactory.addEffectGuard(BH_tr, constraint);
+ }
+ }
+ }
+ lfContext.currentState = targetState;
}
}
@@ -799,8 +892,7 @@
Boolean isStartExecBehavExecution = false;
BehaviorExecutionSpecification behavExecSpecOfComAct = null;
for (Iterator<InteractionFragment> iterator = fragments.iterator(); iterator.hasNext();) {
- InteractionFragment interactionFragment = iterator
- .next();
+ InteractionFragment interactionFragment = iterator.next();
if (interactionFragment instanceof BehaviorExecutionSpecification){
behavExecSpecOfComAct = (BehaviorExecutionSpecification) interactionFragment;
@@ -811,45 +903,42 @@
}
}
+ MsgReceiveAction.append("( ")
+ .append(message.getName()).append( "#params );\n" );
+
if (isStartExecBehavExecution){
- MsgReceiveAction.append("( { ")
- .append(message.getName() )
- .append( "#in" )
- .append(".signature, ");
-
-
Behavior behavior = behavExecSpecOfComAct.getBehavior();
if (behavior instanceof OpaqueBehavior){
OpaqueBehavior opaqueBehavior = (OpaqueBehavior) behavior;
if (opaqueBehavior.getBodies().size() > 0){
- String strinBehavior = opaqueBehavior.getBodies().get(0);
- strinBehavior = strinBehavior.replaceAll("\\s","");
- strinBehavior = strinBehavior.substring(2);
- MsgReceiveAction.append(strinBehavior);
- MsgReceiveAction.append(" } );");
+ String strinBehavior = opaqueBehavior.getBodies().get(0).trim();
+ if( strinBehavior.startsWith("in ") ) {
+ strinBehavior = strinBehavior.substring(3, strinBehavior.length()-1);
+ String[] inVars = strinBehavior.split(" *, *");
+
+ Signal signal = (Signal) message.getSignature();
+ for (int i = 0; i < inVars.length; i++) {
+ MsgReceiveAction.append(inVars[i])
+ .append(" = ")
+ .append(message.getName()).append( "#params.")
+ .append(signal.getAllAttributes().get(i).getName())
+ .append(";\n");
+ }
+ }
+ else {
+ //TO DO error message
+ }
}
}
-
- UmlFactory.addOpaqueBehaviorEffect(MsgOcc_tr, MsgReceiveAction.toString());
}
//ancien
NamedElement signature = message.getSignature();
- if( ! isStartExecBehavExecution ) {
if( signature instanceof Signal ) {
lfContext.addLocalVariable(message.getName() + "#params", (Signal) signature);
}
- MsgReceiveAction.append("( ")
- .append( message.getName() )
- .append( "#params" );
-
- MsgReceiveAction.append(" )");
-
-
- MsgReceiveAction.append(";");
UmlFactory.addOpaqueBehaviorEffect(MsgOcc_tr, MsgReceiveAction.toString());
- }
// }
}
else if( element.isSend() ) {
@@ -858,13 +947,13 @@
lfContext.outputMessage.add(message);
MsgReceiveAction.append( message.getName() )
- .append("( ")
+ .append("( { ")
.append("\"")
.append(message.getSignature().getName())
.append("\"");
if (! (message.getArguments().isEmpty()) ){
- MsgReceiveAction.append(", { ");
+ MsgReceiveAction.append(", ");
boolean isnotFirst = false;
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/MainCodeGenerator.java b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/MainCodeGenerator.java
index edb518e..0c38fb7 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/MainCodeGenerator.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/MainCodeGenerator.java
@@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr - initial API and implementation
+ * Imen Boudhiba (CEA LIST) imen.boudhiba@cea.fr - initial API and implementation
+ * Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr - initial API and implementation
*******************************************************************************/
package org.eclipse.efm.modeling.codegen.xlia.core;
@@ -592,19 +593,24 @@
}
}
}
- writer.append(")");
-
+//old writer.append(")");
+//new
+ if(! firstParam ) {
+ writer.append(", ");
+ }
+//
firstParam = true;
for( Parameter itParameter : parameters ) {
if( itParameter.getDirection() == ParameterDirectionKind.RETURN_LITERAL ) {
if( firstParam ) {
- writer.append(" --> (");
+//old writer.append(" --> (");
firstParam = false;
}
else {
writer.append(", ");
- }
- writer.append( fDataTypeFactory.typeName(itParameter) )
+ }//new next line
+ writer.append("return ")
+ .append( fDataTypeFactory.typeName(itParameter) )
.append(' ')
.append(itParameter.getName());
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/StatemachineCodeGenerator.java b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/StatemachineCodeGenerator.java
index e2db7bb..0d4e38e 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/StatemachineCodeGenerator.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/core/StatemachineCodeGenerator.java
@@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr - initial API and implementation
+ * Imen Boudhiba (CEA LIST) imen.boudhiba@cea.fr - initial API and implementation
*******************************************************************************/
package org.eclipse.efm.modeling.codegen.xlia.core;
@@ -40,7 +40,8 @@
public class StatemachineCodeGenerator extends AbstractCodeGenerator {
public static final String TRANSITION_GUARD_ELSE = "else";
-
+
+ public static final String TRANSITION_TRIGGER_FINAL = "final";
/**
* Constructor
@@ -300,17 +301,24 @@
.append(element.getName())
.appendEol(" {");
- transformStateActivity(element, writer);
+ if( ! element.isComposite() ) {
+ transformStateActivity(element, writer);
+ }
transformConnectionPoint(element, writer);
transformRegion(element.getRegions(), writer);
- if( ! element.getRegions().isEmpty() ) {
- writer.appendTab2Eol("@transition:");
+ if( element.isComposite() ) {
+ writer.appendTabEol("@transition:");
}
transformVertexTransition(element, writer);
-
+
+ if( element.isComposite() ) {
+ writer.appendTabEol("@moe:");
+ transformStateActivity(element, writer);
+ }
+
writer.appendTab("} // end state ")
.appendEol2(element.getName());
}
@@ -404,16 +412,30 @@
TimedTransition timedTransition =
StereotypeUtil.getTimedTransition(element);
- boolean isElseGuard =
- fSupervisor.isConstraintSymbol(element.getGuard(), TRANSITION_GUARD_ELSE);
+ //completion transition
+ boolean isFinalTrigger = ( element.getTrigger(
+ TRANSITION_TRIGGER_FINAL) != null );
+
+ boolean isElseGuard = fSupervisor.isConstraintSymbol(
+ element.getGuard(), TRANSITION_GUARD_ELSE);
boolean isElseTransition = isElseGuard && (timedTransition == null);
writer.appendTab("transition");
- if( isElseTransition ) {
+ if( isFinalTrigger ) {
+ writer.append("< final ");
+ if( isElseTransition ) {
+ writer.append("& else >");
+ }
+ else {
+ writer.append(">");
+ }
+ }
+ else if( isElseTransition ) {
writer.append("< else >");
}
-
+
+
if( element.getName() != null ) {
writer.append(' ')
.append(element.getName());
@@ -506,6 +528,9 @@
* @param writer
*/
public void transformTrigger(Trigger trigger, PrettyPrintWriter writer) {
+ if( TRANSITION_TRIGGER_FINAL.equals(trigger.getName()) ) {
+ return;
+ }
writer.appendTab2("input ");
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/util/StatemachineContext.java b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/util/StatemachineContext.java
index 8c8132d..40aa3ff 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/util/StatemachineContext.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/util/StatemachineContext.java
@@ -246,6 +246,8 @@
return( transition );
}
+
+
public Transition createElseTransition(
String name, Vertex source, Vertex target) {
Transition transition = region.createTransition(name);
@@ -262,6 +264,37 @@
}
+
+ 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);
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/util/UmlFactory.java b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/util/UmlFactory.java
index fd560b0..cb151b6 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/util/UmlFactory.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia/src/org/eclipse/efm/modeling/codegen/xlia/util/UmlFactory.java
@@ -10,10 +10,17 @@
*******************************************************************************/
package org.eclipse.efm.modeling.codegen.xlia.util;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Expression;
+import org.eclipse.uml2.uml.Interaction;
import org.eclipse.uml2.uml.InteractionConstraint;
+import org.eclipse.uml2.uml.InteractionFragment;
+import org.eclipse.uml2.uml.Lifeline;
import org.eclipse.uml2.uml.LiteralBoolean;
import org.eclipse.uml2.uml.LiteralInteger;
import org.eclipse.uml2.uml.LiteralReal;
@@ -33,7 +40,7 @@
import org.eclipse.uml2.uml.ValueSpecification;
public class UmlFactory {
- private static final String LANGUAGE_X_LIA = "xLIA";
+ public static final String LANGUAGE_X_LIA = "xLIA";
///////////////////////////////////////////////////////////////////////////
@@ -176,12 +183,21 @@
}
public static void addOpaqueBehaviorEffect(Transition transition, String opaqBehavior) {
- OpaqueBehavior effectBehavior = UMLFactory.eINSTANCE.createOpaqueBehavior();
+ Behavior behavior = transition.getEffect();
+
+ OpaqueBehavior effectBehavior = null;
+ if(behavior instanceof OpaqueBehavior) {
+ effectBehavior = (OpaqueBehavior) behavior;
+ }
+
+ if( effectBehavior == null ) {
+ effectBehavior = UMLFactory.eINSTANCE.createOpaqueBehavior();
+ effectBehavior.setName("effect");
+ transition.setEffect(effectBehavior);
+ }
+
effectBehavior.getLanguages().add(LANGUAGE_X_LIA);
effectBehavior.getBodies().add(opaqBehavior);
- effectBehavior.setName("effect");
-
- transition.setEffect(effectBehavior);
}
public static void setGuard(Transition transition, Constraint guard) {
@@ -220,6 +236,31 @@
}
+ public static void addEffectGuard(Transition transition, Constraint guard) {
+ StringBuffer valueBuffer = new StringBuffer("guard( ");
+
+
+ if( guard != null ) {
+ ValueSpecification valueSpec = guard.getSpecification();
+ if( valueSpec instanceof OpaqueExpression ) {
+ for (String body : ((OpaqueExpression)valueSpec).getBodies()) {
+ valueBuffer.append(body);
+ }
+ valueBuffer.append(" );");
+ }
+ else if( valueSpec instanceof Expression ) {
+ Expression valueExpr = (Expression) valueSpec;
+ valueBuffer.append(valueExpr); //TODO expression to string
+ }
+ else {
+ valueSpecificationToString(valueSpec, valueBuffer);
+ }
+ }
+
+ addOpaqueBehaviorEffect(transition, valueBuffer.toString());
+ }
+
+
public static void valueSpecificationToString(
ValueSpecification value, StringBuffer stringVar) {
if( value instanceof LiteralBoolean ) {
@@ -252,6 +293,12 @@
stringVar.append(")");
}
+
+ else if( value instanceof OpaqueExpression ) {
+ OpaqueExpression expr = (OpaqueExpression) value;
+ stringVar.append(expr.getBodies().get(0).toString());
+ }
+
else if( value != null ) {
final String name = value.getName();
if( name != null ) {
@@ -270,20 +317,8 @@
Constraint constraint = transition.createGuard("guardConstraint");
ValueSpecification valueSpec = interactionGuard.getSpecification();
- StringBuffer loopIndexConstraint = new StringBuffer();
- if( interactionGuard.getMinint() != null ) {
- loopIndexConstraint.append(indexVar.getName()).append(" >= ");
- valueSpecificationToString(interactionGuard.getMinint(), loopIndexConstraint);
+ String loopIndexConstraint = toIndexConstraint(interactionGuard, indexVar);
- }
- if( interactionGuard.getMaxint() != null ) {
- if( loopIndexConstraint.length() > 0 ) {
- loopIndexConstraint.append(" && ");
- }
- loopIndexConstraint.append(indexVar.getName()).append(" <= ");
- valueSpecificationToString(interactionGuard.getMaxint(), loopIndexConstraint);
- }
-
if( valueSpec instanceof OpaqueExpression ) {
OpaqueExpression guardSpecification = UMLFactory.eINSTANCE.createOpaqueExpression();
guardSpecification.getLanguages().addAll(((OpaqueExpression)valueSpec).getLanguages());
@@ -311,5 +346,26 @@
}
}
+ public static String toIndexConstraint(InteractionConstraint interactionGuard, Property indexVar) {
+ if( interactionGuard != null ) {
+ StringBuffer loopIndexConstraint = new StringBuffer();
+ if( interactionGuard.getMinint() != null ) {
+ loopIndexConstraint.append(indexVar.getName()).append(" >= ");
+ valueSpecificationToString(interactionGuard.getMinint(), loopIndexConstraint);
+
+ }
+ if( interactionGuard.getMaxint() != null ) {
+ if( loopIndexConstraint.length() > 0 ) {
+ loopIndexConstraint.append(" && ");
+ }
+ loopIndexConstraint.append(indexVar.getName()).append(" <= ");
+ valueSpecificationToString(interactionGuard.getMaxint(), loopIndexConstraint);
+ }
+
+ return loopIndexConstraint.toString();
+ }
+
+ return "true";
+ }
}
diff --git a/gui/org.eclipse.efm.modeling.ui.views.property.tab.xlia/src/org/eclipse/efm/papyrus/view/property/concretesyntax/sheet/EditingPropertyCodeGenerator.java b/gui/org.eclipse.efm.modeling.ui.views.property.tab.xlia/src/org/eclipse/efm/papyrus/view/property/concretesyntax/sheet/EditingPropertyCodeGenerator.java
index 8e73af5..cc55bfe 100644
--- a/gui/org.eclipse.efm.modeling.ui.views.property.tab.xlia/src/org/eclipse/efm/papyrus/view/property/concretesyntax/sheet/EditingPropertyCodeGenerator.java
+++ b/gui/org.eclipse.efm.modeling.ui.views.property.tab.xlia/src/org/eclipse/efm/papyrus/view/property/concretesyntax/sheet/EditingPropertyCodeGenerator.java
@@ -11,6 +11,7 @@
import java.io.StringWriter;
import org.eclipse.efm.modeling.codegen.xlia.core.MainCodeGenerator;
+import org.eclipse.efm.modeling.codegen.xlia.core.StatemachineCodeGenerator;
import org.eclipse.efm.modeling.codegen.xlia.util.PrettyPrintWriter;
import org.eclipse.efm.modeling.formalml.TimedTransition;
import org.eclipse.efm.modeling.formalml.helpers.StereotypeUtil;
@@ -225,16 +226,29 @@
TimedTransition timedTransition =
StereotypeUtil.getTimedTransition(element);
- boolean isElseGuard =
- super.isConstraintSymbol(element.getGuard(), "else");
+ boolean isFinalTrigger = ( element.getTrigger(
+ StatemachineCodeGenerator.TRANSITION_TRIGGER_FINAL) != null );
+
+ boolean isElseGuard = fSupervisor.isConstraintSymbol(
+ element.getGuard(), StatemachineCodeGenerator.TRANSITION_GUARD_ELSE);
boolean isElseTransition = isElseGuard && (timedTransition == null);
writer.appendTab("transition");
- if( isElseTransition ) {
+ if( isFinalTrigger ) {
+ writer.append("< final ");
+ if( isElseTransition ) {
+ writer.append("& else >");
+ }
+ else {
+ writer.append(">");
+ }
+ }
+ else if( isElseTransition ) {
writer.append("< else >");
}
+
if( element.getName() != null ) {
writer.append(" ")
.append(element.getName());