浏览代码

Added Xtend2 based java generator.

markus.muehlbrandt@gmail.com 13 年之前
父节点
当前提交
f74c5f5fb5
共有 24 个文件被更改,包括 2680 次插入89 次删除
  1. 8 7
      plugins/org.yakindu.sct.generator.java/.classpath
  2. 40 34
      plugins/org.yakindu.sct.generator.java/.project
  3. 31 27
      plugins/org.yakindu.sct.generator.java/META-INF/MANIFEST.MF
  4. 19 2
      plugins/org.yakindu.sct.generator.java/plugin.xml
  5. 36 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/Beautifier.java
  6. 226 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/ExpressionCode.xtend
  7. 160 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/FlowCode.xtend
  8. 114 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/GenmodelEntries.xtend
  9. 13 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/INaming.java
  10. 58 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/IStatemachine.xtend
  11. 64 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/ITimedStatemachine.xtend
  12. 72 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/ITimerService.xtend
  13. 23 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/JavaCodeGenerator.java
  14. 56 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/JavaGenerator.xtend
  15. 230 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/Naming.xtend
  16. 301 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/Navigation.xtend
  17. 241 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/RuntimeService.xtend
  18. 551 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/Statemachine.xtend
  19. 193 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/StatemachineInterface.xtend
  20. 92 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/TimeEventTemplate.xtend
  21. 91 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/TimerService.xtend
  22. 44 0
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/TypeModel.xtend
  23. 11 14
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/templates/Expression.ext
  24. 6 5
      plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/templates/Naming.ext

+ 8 - 7
plugins/org.yakindu.sct.generator.java/.classpath

@@ -1,7 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="xtend-gen"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 40 - 34
plugins/org.yakindu.sct.generator.java/.project

@@ -1,34 +1,40 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.yakindu.sct.generator.java</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.xtend.shared.ui.xtendBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.xtend.shared.ui.xtendXPandNature</nature>
-	</natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.yakindu.sct.generator.java</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.xtend.shared.ui.xtendBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.xtend.shared.ui.xtendXPandNature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+	</natures>
+</projectDescription>

+ 31 - 27
plugins/org.yakindu.sct.generator.java/META-INF/MANIFEST.MF

@@ -1,27 +1,31 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Java Generator PlugIn
-Bundle-SymbolicName: org.yakindu.sct.generator.java;singleton:=true
-Bundle-Version: 1.0.0.qualifier
-Require-Bundle: org.eclipse.jdt.core;bundle-version="3.5.0",
- org.apache.commons.logging,
- org.apache.log4j;resolution:=optional,
- com.ibm.icu;bundle-version="4.0.1",
- org.antlr.runtime;bundle-version="3.0.0",
- org.eclipse.core.runtime;bundle-version="3.5.0",
- org.eclipse.emf.mwe.utils;bundle-version="0.7.0",
- org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
- org.eclipse.jface.text;bundle-version="3.5.0",
- org.eclipse.xpand;bundle-version="0.7.0",
- org.eclipse.xtend;bundle-version="0.7.0",
- org.eclipse.xtend.typesystem.emf;bundle-version="0.7.0",
- org.yakindu.sct.model.stext;bundle-version="1.0.0",
- org.yakindu.sct.generator.core;bundle-version="1.0.0",
- org.eclipse.jdt.launching;bundle-version="3.6.0",
- org.yakindu.sct.generator.genmodel;bundle-version="1.0.0",
- org.eclipse.xtext.xbase;bundle-version="2.0.0",
- org.yakindu.sct.model.stext.resource;bundle-version="1.0.0"
-Bundle-Vendor: YAKINDU
-Export-Package: org.yakindu.sct.generator.java
-Bundle-ActivationPolicy: lazy
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Java Generator PlugIn
+Bundle-SymbolicName: org.yakindu.sct.generator.java;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.eclipse.jdt.core;bundle-version="3.5.0",
+ org.apache.commons.logging,
+ org.apache.log4j;resolution:=optional,
+ com.ibm.icu;bundle-version="4.0.1",
+ org.antlr.runtime;bundle-version="3.0.0",
+ org.eclipse.core.runtime;bundle-version="3.5.0",
+ org.eclipse.emf.mwe.utils;bundle-version="0.7.0",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.eclipse.jface.text;bundle-version="3.5.0",
+ org.eclipse.xpand;bundle-version="0.7.0",
+ org.eclipse.xtend;bundle-version="0.7.0",
+ org.eclipse.xtend.typesystem.emf;bundle-version="0.7.0",
+ org.yakindu.sct.model.stext;bundle-version="1.0.0",
+ org.yakindu.sct.generator.core;bundle-version="1.0.0",
+ org.eclipse.jdt.launching;bundle-version="3.6.0",
+ org.yakindu.sct.generator.genmodel;bundle-version="1.0.0",
+ org.eclipse.xtext.xbase;bundle-version="2.0.0",
+ org.yakindu.sct.model.stext.resource;bundle-version="1.0.0",
+ org.eclipse.xtend.lib,
+ com.google.guava,
+ org.eclipse.xtext.xbase.lib
+Bundle-Vendor: YAKINDU
+Export-Package: org.yakindu.sct.generator.java
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+

+ 19 - 2
plugins/org.yakindu.sct.generator.java/plugin.xml

@@ -6,14 +6,27 @@
       <SCTGenerator
             class="org.yakindu.sct.generator.java.JavaSCTGenerator"
             description="YAKINDU Java Code Generator"
+            id="yakindu::javadep"
+            contentType="statechart"
+            elementRefType="org.yakindu.sct.model.sgraph.Statechart"
+            name="YAKINDU Java Xpand Code Generator (deprecated)">
+      </SCTGenerator>
+       <SCTGenerator
+            class="org.yakindu.sct.generator.java.JavaCodeGenerator"
+            description="YAKINDU Java Xtend2 Code Generator"
             id="yakindu::java"
             contentType="statechart"
             elementRefType="org.yakindu.sct.model.sgraph.Statechart"
-            name="YAKINDU Java Code Generator">
+            name="YAKINDU Java Xtend2 Code Generator">
       </SCTGenerator>
    </extension>
    <extension
          point="org.yakindu.sct.generator.core.featuretypes">
+      <FeatureLibrary
+            defaultProvider="org.yakindu.sct.generator.java.features.JavaFeatureValueProvider"
+            generatorId="yakindu::javadep"
+            uri="platform:/plugin/org.yakindu.sct.generator.java/library/FeatureTypeLibrary.xmi">
+      </FeatureLibrary>
       <FeatureLibrary
             defaultProvider="org.yakindu.sct.generator.java.features.JavaFeatureValueProvider"
             generatorId="yakindu::java"
@@ -24,7 +37,11 @@
          point="org.yakindu.sct.generator.core.extensions">
       <ExtensionGeneratorMapping
             fileExtension="sct"
-            generatorId="yakindu::java"></ExtensionGeneratorMapping>
+            generatorId="yakindu::javadep"></ExtensionGeneratorMapping>
+      <ExtensionGeneratorMapping
+            fileExtension="sct"
+            generatorId="yakindu::java">
+      </ExtensionGeneratorMapping>
    </extension>
 
 </plugin>

+ 36 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/Beautifier.java

@@ -0,0 +1,36 @@
+package org.yakindu.sct.generator.java;
+
+import java.io.File;
+
+import org.eclipse.xpand2.output.FileHandle;
+import org.eclipse.xpand2.output.FileHandleImpl;
+import org.eclipse.xpand2.output.JavaBeautifier;
+import org.eclipse.xpand2.output.Outlet;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+public class Beautifier {
+
+	@Inject
+	JavaBeautifier javaBeautifier;
+
+	/**
+	 * Format code with PostProcessor (XPand style).
+	 */
+	public CharSequence format(String fileName, CharSequence code) {
+
+		// create fileHandle with dummy outlet.
+		File file = new File(fileName);
+		FileHandle fileHandle = new FileHandleImpl(new Outlet(), file);
+		fileHandle.setBuffer(code);
+
+		// call postProcessor for formatting the code.
+		javaBeautifier.beforeWriteAndClose(fileHandle);
+
+		// return formatted results.
+		return fileHandle.getBuffer();
+
+	}
+}

+ 226 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/ExpressionCode.xtend

@@ -0,0 +1,226 @@
+package org.yakindu.sct.generator.java
+
+import com.google.inject.Inject
+import org.eclipse.emf.ecore.EObject
+import org.yakindu.sct.generator.core.extensions.TypeAnalyzerExtensions
+import org.yakindu.sct.model.sexec.TimeEvent
+import org.yakindu.sct.model.sgraph.Event
+import org.yakindu.sct.model.sgraph.Variable
+import org.yakindu.sct.model.stext.stext.ActiveStateReferenceExpression
+import org.yakindu.sct.model.stext.stext.AdditiveOperator
+import org.yakindu.sct.model.stext.stext.AssignmentExpression
+import org.yakindu.sct.model.stext.stext.AssignmentOperator
+import org.yakindu.sct.model.stext.stext.BitwiseAndExpression
+import org.yakindu.sct.model.stext.stext.BitwiseOrExpression
+import org.yakindu.sct.model.stext.stext.BitwiseXorExpression
+import org.yakindu.sct.model.stext.stext.BoolLiteral
+import org.yakindu.sct.model.stext.stext.ElementReferenceExpression
+import org.yakindu.sct.model.stext.stext.EventRaisingExpression
+import org.yakindu.sct.model.stext.stext.EventValueReferenceExpression
+import org.yakindu.sct.model.stext.stext.FeatureCall
+import org.yakindu.sct.model.stext.stext.HexLiteral
+import org.yakindu.sct.model.stext.stext.IntLiteral
+import org.yakindu.sct.model.stext.stext.LogicalAndExpression
+import org.yakindu.sct.model.stext.stext.LogicalNotExpression
+import org.yakindu.sct.model.stext.stext.LogicalOrExpression
+import org.yakindu.sct.model.stext.stext.LogicalRelationExpression
+import org.yakindu.sct.model.stext.stext.MultiplicativeOperator
+import org.yakindu.sct.model.stext.stext.NumericalAddSubtractExpression
+import org.yakindu.sct.model.stext.stext.NumericalMultiplyDivideExpression
+import org.yakindu.sct.model.stext.stext.NumericalUnaryExpression
+import org.yakindu.sct.model.stext.stext.OperationDefinition
+import org.yakindu.sct.model.stext.stext.ParenthesizedExpression
+import org.yakindu.sct.model.stext.stext.PrimitiveValueExpression
+import org.yakindu.sct.model.stext.stext.RealLiteral
+import org.yakindu.sct.model.stext.stext.RelationalOperator
+import org.yakindu.sct.model.stext.stext.ShiftExpression
+import org.yakindu.sct.model.stext.stext.ShiftOperator
+import org.yakindu.sct.model.stext.stext.StringLiteral
+import org.yakindu.sct.model.stext.stext.UnaryOperator
+import org.yakindu.sct.model.sgraph.Declaration
+
+class ExpressionCode {
+	
+	@Inject extension Naming 
+	@Inject extension Navigation
+	@Inject extension TypeAnalyzerExtensions
+	
+	def dispatch String code(EObject it) '''
+		//ERROR: Template in ExpressionCode.xtend for class '«getClass().name»' not define.
+		//Container: «eContainer?.getClass().name»
+	'''
+	
+	def dispatch String code(OperationDefinition it) {
+		return context + "operationCallback." + name.asEscapedIdentifier;
+	}
+	
+	def dispatch String code(PrimitiveValueExpression primValue) {
+		primValue.value.code;		
+	}
+	
+	def dispatch String code(ParenthesizedExpression e) {
+		"(" + e.expression.code + ")";		
+	}
+	
+	/* Assignment */
+	def dispatch String code(AssignmentExpression it) {
+		varRef.code + operator.code + expression.code
+	}
+			
+	/* Literals */
+	def dispatch String code(BoolLiteral expression) {
+		expression.value.toString()
+	}
+	
+	def dispatch String code(IntLiteral expression) {
+		expression.value.toString();		
+	}
+	
+	def dispatch String code(HexLiteral expression) {		
+		expression.value.toString();
+	}
+	
+	def dispatch String code(RealLiteral expression) {
+		expression.value.toString();
+	}
+	
+	def dispatch String code(StringLiteral expression) {
+		"\"" + expression.value.toString() + "\""
+	}
+	
+	/* Logical Expressions */
+	def dispatch String code(LogicalOrExpression expression) {
+	  	expression.leftOperand.code + " || " + expression.rightOperand.code		
+	}
+	  	
+	def dispatch String code(LogicalAndExpression expression) {
+		expression.leftOperand.code + " && " + expression.rightOperand.code
+	}
+	
+	def dispatch String code(LogicalNotExpression expression) {
+		" !" + expression.operand.code
+	}
+	
+	def dispatch String code(LogicalRelationExpression expression) {
+		if (expression.leftOperand.type.isString) {
+			expression.logicalString
+		}
+		else
+			expression.leftOperand.code + expression.operator.code + expression.rightOperand.code;
+	}
+	
+	def String logicalString(LogicalRelationExpression expression) {
+		if (expression.operator == RelationalOperator::EQUALS) {
+			expression.leftOperand.code + "== null?" + expression.rightOperand.code + " ==null :" + expression.leftOperand.code+".equals("+expression.rightOperand.code+")"
+		}
+		else if(expression.operator == RelationalOperator::NOT_EQUALS) {
+			expression.leftOperand.code + "== null?" + expression.rightOperand.code + " ==null : !" + expression.leftOperand.code+".equals("+expression.rightOperand.code+")"
+		}
+	}
+	
+	def dispatch String code(BitwiseAndExpression expression) {
+		expression.leftOperand.code + " & " + expression.rightOperand.code
+	}
+	
+	def dispatch String code(BitwiseOrExpression expression) {
+		expression.leftOperand.code + " | " + expression.rightOperand.code
+	}
+	
+	def dispatch String code(BitwiseXorExpression expression) {
+		expression.leftOperand.code + " ^ " + expression.rightOperand.code		
+	}
+	
+	def dispatch String code(ShiftExpression expression) {
+		expression.leftOperand.code + expression.operator.code + expression.rightOperand.code		
+	}
+	
+	def dispatch String code(NumericalAddSubtractExpression expression) {
+		expression.leftOperand.code + expression.operator.code + expression.rightOperand.code	
+	}
+	  	
+	def dispatch String code(NumericalMultiplyDivideExpression expression) {
+		expression.leftOperand.code + expression.operator.code + expression.rightOperand.code
+		
+	}
+	
+	def dispatch String code(NumericalUnaryExpression expression) {
+		expression.operator.code + expression.operand.code
+	}
+	
+	def dispatch String code(ActiveStateReferenceExpression it) {
+		"isStateActive(State." + value.stateName.asEscapedIdentifier +")";
+	}
+	
+	def dispatch String code(AdditiveOperator operator) {
+		operator.literal
+	}
+	
+	def dispatch String code(ShiftOperator operator) {
+		operator.literal
+	}
+	
+	def dispatch String code(UnaryOperator operator) {
+		operator.literal
+	}
+	
+	def dispatch String code(MultiplicativeOperator operator) {
+		operator.literal
+	} 
+	
+	def dispatch String code(RelationalOperator operator) {
+		operator.literal
+	}
+	
+	def dispatch String code(AssignmentOperator operator) {
+		operator.literal
+	}
+	
+	def dispatch String code(EventRaisingExpression it) {
+		if (value != null) {
+			event.definition.context+"raise"+event.definition.name.toFirstUpper+"("+value.code+")"			
+		}
+		else {
+			event.definition.context+"raise"+event.definition.name.toFirstUpper+"()"
+		}
+	}
+	
+	def dispatch String code(EventValueReferenceExpression it) {
+		value.definition.context + value.definition.event.valueIdentifier
+	}
+	
+	def dispatch String code(ElementReferenceExpression it) {
+		'''
+		«IF operationCall»
+			«reference.code»(«FOR arg : args SEPARATOR ", "»«arg.code»«ENDFOR»)
+		«ELSE»
+			«definition.code»
+		«ENDIF»
+		'''
+	}
+	
+	def dispatch String code(FeatureCall it) {
+		definition.context + definition.name.asEscapedIdentifier
+	}
+	
+	def dispatch String code(Declaration it) {
+		context + name.asEscapedIdentifier
+	}
+	
+	def dispatch String code(TimeEvent it) {
+		"timeEvents[" + name.asEscapedIdentifier + ".getIndex()]"
+	}
+	
+	def dispatch String getContext(Variable it) {
+		if (scope != null) {
+			return scope.interfaceName.asEscapedIdentifier + "."
+		}
+		return ""
+	}
+	
+	def dispatch String getContext(Event it) {
+		if (scope != null) {
+			return scope.interfaceName.asEscapedIdentifier + "."
+		}
+		return ""		
+	}
+}

+ 160 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/FlowCode.xtend

@@ -0,0 +1,160 @@
+package org.yakindu.sct.generator.java
+
+import com.google.inject.Inject
+import org.yakindu.sct.model.sexec.Call
+import org.yakindu.sct.model.sexec.Check
+import org.yakindu.sct.model.sexec.CheckRef
+import org.yakindu.sct.model.sexec.EnterState
+import org.yakindu.sct.model.sexec.Execution
+import org.yakindu.sct.model.sexec.ExitState
+import org.yakindu.sct.model.sexec.HistoryEntry
+import org.yakindu.sct.model.sexec.If
+import org.yakindu.sct.model.sexec.Reaction
+import org.yakindu.sct.model.sexec.SaveHistory
+import org.yakindu.sct.model.sexec.ScheduleTimeEvent
+import org.yakindu.sct.model.sexec.Sequence
+import org.yakindu.sct.model.sexec.StateSwitch
+import org.yakindu.sct.model.sexec.Step
+import org.yakindu.sct.model.sexec.UnscheduleTimeEvent
+import org.yakindu.sct.model.stext.stext.VariableDefinition
+
+class FlowCode {
+	
+	@Inject extension Naming
+	@Inject extension ExpressionCode
+	
+	def stepComment(Step it) '''
+		«IF comment != null && ! comment.empty»
+			/* «comment» */
+		«ENDIF»
+	'''
+	
+	def dispatch code(Step it) '''
+		//ERROR: FlowCode for Step '«getClass().name»' not defined
+	'''
+	
+	def dispatch code(StateSwitch it) '''
+		«IF historyRegion != null»
+			switch(historyVector[«historyRegion.historyVector.offset»]) {
+		«ELSE»
+			switch(stateVector[«stateConfigurationIdx»]) {
+		«ENDIF»
+			«FOR stateCase : cases»
+				case «stateCase.state.stateName.asEscapedIdentifier» : 
+					«stateCase.step.code»
+					break;
+				
+			«ENDFOR»
+			default: 
+				break;
+		}
+	'''
+	
+	def dispatch code(ScheduleTimeEvent it) '''
+		«stepComment»
+		getTimerService().setTimer(«timeEvent.name.asEscapedIdentifier», «timeValue.code», cycleStartTime);
+	'''
+	
+	def dispatch code(UnscheduleTimeEvent it) '''
+		«stepComment»
+		getTimerService().resetTimer(«timeEvent.name.asEscapedIdentifier»);
+	'''
+	
+	def dispatch code(Execution it) {
+		'''
+		«statement.code»;
+		'''
+	}
+	
+	def dispatch code(Call it) {
+		'''
+		«step.functionName()»();
+		'''
+	}
+	
+	def dispatch code(Sequence it) {
+		steps.map[code].join('\n')
+	}
+	
+	def dispatch code(Check it) {
+		'''
+		«IF this != null»
+			«condition.code()»
+		«ELSE»
+			true
+ 		«ENDIF»
+		'''
+	}
+	
+	def dispatch code(CheckRef it) {
+		'''
+		«IF check != null»
+			«comment»
+			«check.functionName()»()
+		«ELSE»
+			true
+		«ENDIF»
+		'''
+	}
+	
+	def dispatch code(Reaction it) {
+		effect.code
+	}
+	
+	def dispatch code(If it) {
+		'''
+		«stepComment»
+		if («check.code») { 
+			«thenStep.code»
+		}
+		«IF elseStep != null»
+		else {
+			«elseStep.code»
+		}
+		«ENDIF»
+		'''
+	}
+	
+	def dispatch code(EnterState it) {
+		'''
+		«stepComment»
+		nextStateIndex = «state.stateVector.offset»;
+		stateVector[«state.stateVector.offset»] = State.«state.stateName.asEscapedIdentifier»;
+		'''
+	}
+	
+	def dispatch code(ExitState it) {
+		'''
+		«stepComment»
+		nextStateIndex = «state.stateVector.offset»;
+		stateVector[«state.stateVector.offset»] = State.«getNullStateName()»;
+		'''
+	}
+	
+	def dispatch code(HistoryEntry it) {
+		'''
+		«stepComment»
+		if (historyVector[«region.historyVector.offset»] != State.$NullState$) {
+			«historyStep.code»
+		} else {
+			«initialStep.code»
+		}
+		'''
+	}
+	
+	def dispatch code(SaveHistory it) {
+		'''
+		«stepComment»
+		historyVector[«region.historyVector.offset»] = stateVector[«region.stateVector.offset»];
+		'''
+	}
+	
+	def String getInitialValueAssignment(VariableDefinition it) {
+		if (initialValue != null) {
+			return " = " + initialValue.code
+		}
+		else {
+			return ""
+		}
+	}
+}

+ 114 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/GenmodelEntries.xtend

@@ -0,0 +1,114 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import com.google.inject.Inject
+import org.yakindu.sct.generator.core.features.ICoreFeatureConstants
+import org.yakindu.sct.generator.java.features.IJavaFeatureConstants
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.FeatureParameterValue
+import org.yakindu.sct.model.sgen.GeneratorEntry
+
+class GenmodelEntries {
+	
+	@Inject extension Naming
+	
+	def private getLicenseFeature(GeneratorEntry it) {
+		getFeatureConfiguration(ICoreFeatureConstants::LICENSE_HEADER)
+	}
+	
+	def private getNamingFeature(GeneratorEntry it) {
+		getFeatureConfiguration(IJavaFeatureConstants::NAMING_FEATURE)
+	}
+	
+	def private getGeneralFeatures(GeneratorEntry it) {
+		getFeatureConfiguration(IJavaFeatureConstants::GENERAL_FEATURES)
+	}
+	
+	def private FeatureParameterValue getBasePackageParameter(GeneratorEntry it) {
+		namingFeature?.getParameterValue(IJavaFeatureConstants::BASE_PACKAGE)
+	}
+	
+	def private FeatureParameterValue getImplementationSuffixParameter(GeneratorEntry it) {
+		namingFeature?.getParameterValue(IJavaFeatureConstants::IMPLEMENTATION_SUFFIX)
+	}
+	
+	def private FeatureParameterValue getLicenseTextParameter(GeneratorEntry it) {
+		licenseFeature?.getParameterValue(ICoreFeatureConstants::LICENSE_TEXT)
+	}
+	
+	def private FeatureParameterValue getTimerServiceParameter(GeneratorEntry it) {
+		generalFeatures?.getParameterValue(IJavaFeatureConstants::TIMER_SERVICE)
+	}
+	
+	def private FeatureParameterValue getRuntimeServiceParameter(GeneratorEntry it) {
+		generalFeatures?.getParameterValue(IJavaFeatureConstants::RUNTIME_SERVICE)
+	}
+	
+	def private FeatureParameterValue getInterfaceObserverSupportParameter(GeneratorEntry it) {
+		generalFeatures?.getParameterValue(IJavaFeatureConstants::INTERFACE_OBSERVER_SUPPORT)
+	}
+	
+	def getLicenseText(GeneratorEntry it) {
+		if (licenseTextParameter != null) {
+			return "/**"+licenseTextParameter.stringValue+"*/"
+		}
+		return null
+	}
+	
+	def getBasePackageName(GeneratorEntry it) {
+		if (basePackageParameter != null) {
+			return basePackageParameter.stringValue
+		}
+		return "org.yakindu.scr"
+	}
+	
+	def getImplementationSuffix(GeneratorEntry it, ExecutionFlow flow) {
+		if (implementationSuffixParameter != null) {
+			return flow.statemachineName + implementationSuffixParameter.stringValue
+		}
+		return flow.statemachineName
+	}
+	
+	def getImplementationPackageName(ExecutionFlow it, GeneratorEntry entry) {
+		entry.basePackageName + "." + entry.getImplementationSuffix(it).toLowerCase();
+	}
+	
+	def getBasePackagePath(GeneratorEntry it) {
+		return basePackageName.replace('.', '/')
+	}
+	
+	def getImplementationPackagePath(ExecutionFlow it, GeneratorEntry entry) {
+		getImplementationPackageName(entry).replace('.', '/')
+		//entry.basePackagePath+"/"+entry.getImplementationSuffix(it).toLowerCase
+	}
+	
+	
+	def createTimerService(GeneratorEntry it) {
+		if (timerServiceParameter != null) {
+			return timerServiceParameter.booleanValue
+		}
+		return false
+	}
+	
+	def createRuntimeService(GeneratorEntry it) {
+		if (runtimeServiceParameter != null) {
+			return runtimeServiceParameter.booleanValue
+		}
+		return false
+	}
+	
+	def createInterfaceObserver(GeneratorEntry it) {
+		if (interfaceObserverSupportParameter != null) {
+			return interfaceObserverSupportParameter.booleanValue
+		}
+		return false
+	} 
+}

+ 13 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/INaming.java

@@ -0,0 +1,13 @@
+package org.yakindu.sct.generator.java;
+
+public interface INaming {
+	public static final String[] JAVA_KEYWORDS = { "abstract", "assert",
+		"boolean", "break", "byte", "case", "catch", "char", "class",
+		"const", "continue", "default", "do", "double", "else", "enum",
+		"extends", "false", "final", "finally", "float", "for", "goto", "if",
+		"implements", "import", "instanceof", "int", "interface", "long",
+		"native", "new", "null", "package", "private", "protected", "public",
+		"return", "short", "static", "strictfp", "super", "switch",
+		"synchronized", "this", "throw", "throws", "transient", "true" , "try",
+		"void", "volatile", "while" };
+}

+ 58 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/IStatemachine.xtend

@@ -0,0 +1,58 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.eclipse.xtext.generator.IFileSystemAccess
+import com.google.inject.Inject
+
+class IStatemachine {
+	
+	@Inject
+	extension Naming 
+	
+	@Inject
+	extension GenmodelEntries
+	
+	def generateIStatemachine(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+		fsa.generateFile(entry.basePackagePath + '/' + iStatemachineClass.java, content(entry))
+	}
+	
+	def private content(GeneratorEntry entry) {
+		'''
+		«entry.licenseText»
+		package «entry.getBasePackageName()»;
+
+		/**
+		 * Basic interface for statemachines.
+		 * 
+		 * 
+		 */
+		public interface IStatemachine {
+		
+			/**
+			* Initializes the statemachine. Use to init internal variables etc.
+			*/
+			public void init();
+		
+			/**
+			* Enters the statemachine. Sets the statemachine in a defined state.
+			*/
+			public void enter();
+		
+			/**
+			* Start a run-to-completion cycle.
+			*/
+			public void runCycle();
+		}
+		'''
+	}
+}

+ 64 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/ITimedStatemachine.xtend

@@ -0,0 +1,64 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.eclipse.xtext.generator.IFileSystemAccess
+import com.google.inject.Inject
+
+class ITimedStatemachine {
+	
+	@Inject
+	extension Naming 
+	
+	@Inject
+	extension GenmodelEntries
+	
+	def generateITimedStatemachine(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+		fsa.generateFile(entry.basePackagePath + '/' + iTimedStatemachineClass.java, content(entry))
+	}
+	
+	def private content(GeneratorEntry entry) {
+		'''
+		«entry.licenseText»
+		package «entry.getBasePackageName()»;
+
+		/**
+		* Interface for state machines which use timed event triggers.
+		*/
+		public interface ITimedStatemachine {
+		
+			/**
+			* Set the {@link ITimerService} for the state machine. It must be set
+			* externally on a timed state machine before a run cycle can be correct
+			* executed.
+			* 
+			* @param timerService
+			*/
+			public void setTimerService(ITimerService timerService);
+		
+			/**
+			* Returns the currently used timer service.
+			* 
+			* @return {@link ITimerService}
+			*/
+			public ITimerService getTimerService();
+		
+			/**
+			* Callback method if a {@link TimeEvent} occurred.
+			* 
+			* @param timeEvent
+			*/
+			public void onTimeEventRaised(TimeEvent timeEvent);
+		}
+		'''
+	}
+}

+ 72 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/ITimerService.xtend

@@ -0,0 +1,72 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.eclipse.xtext.generator.IFileSystemAccess
+import com.google.inject.Inject
+
+class ITimerService {
+	
+	@Inject
+	extension Naming 
+	
+	@Inject
+	extension GenmodelEntries
+	
+	def generateITimerService(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+		fsa.generateFile(entry.basePackagePath + '/' + iTimerServiceClass.java, content(entry))
+	}
+	
+	def private content(GeneratorEntry entry) {
+		'''
+		«entry.licenseText»
+		package «entry.getBasePackageName()»;
+
+		/**
+		 * Interface a timer service has to implement. Use to implement your own timer
+		 * service. A timer service has to be added to a timed state machine.
+		 * 
+		 */
+		public interface ITimerService {
+		
+			/**
+			 * Starts the timing for a given {@link TimeEvent}.
+			 * 
+			 * @param event
+			 *            : The TimeEvent the timer service should throw if timed out.
+			 * @param time
+			 *            : Time in milliseconds after the given time event should be
+			 *            triggered
+			 * @param cycleStartTime
+			 *            : The absolute start time in milliseconds at which the last
+			 *            run cycle was called. Can be used to produce a more accurate
+			 *            timing behavior.
+			 */
+			public void setTimer(TimeEvent event, long time, long cycleStartTime);
+		
+			/**
+			 * Unset the given {@link TimeEvent}. Use to unset cyclic repeated time
+			 * events.
+			 * 
+			 * @param event
+			 */
+			public void resetTimer(TimeEvent event);
+		
+			/**
+			 * Cancel timer service. Use this to end possible timing threads and free
+			 * memory resources.
+			 */
+			public void cancel();
+		}
+		'''
+	}
+}

+ 23 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/JavaCodeGenerator.java

@@ -0,0 +1,23 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java;
+
+import org.yakindu.sct.generator.core.impl.GenericJavaBasedGenerator;
+import org.yakindu.sct.model.sgen.GeneratorEntry;
+import org.yakindu.sct.model.sgraph.Statechart;
+
+public class JavaCodeGenerator extends GenericJavaBasedGenerator {
+
+	@Override
+	public void runGenerator(Statechart flow, GeneratorEntry entry) {
+		JavaGenerator delegate = getInjector(entry).getInstance(JavaGenerator.class);		
+		delegate.generate(createExecutionFlow(flow, entry), entry, getFileSystemAccess(entry));
+	}
+}

+ 56 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/JavaGenerator.xtend

@@ -0,0 +1,56 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import com.google.inject.Inject
+import org.eclipse.xtext.generator.IFileSystemAccess
+import org.yakindu.sct.generator.core.impl.IExecutionFlowGenerator
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+
+/**
+ * This is the Java code generators main class. 
+ * 
+ * @author Markus Mühlbrandt
+ */
+class JavaGenerator implements IExecutionFlowGenerator {
+
+	@Inject extension Navigation
+	@Inject extension IStatemachine
+	@Inject extension ITimedStatemachine
+	@Inject extension ITimerService
+	@Inject extension TimeEventTemplate
+	@Inject extension TimerService
+	@Inject extension GenmodelEntries
+	@Inject extension RuntimeService
+	@Inject extension StatemachineInterface
+	@Inject extension Statemachine
+ 	
+	override generate(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+
+		flow.generateIStatemachine(entry, fsa)
+		
+		if (flow.timed) {
+			flow.generateITimedStatemachine(entry, fsa)
+			flow.generateITimerService(entry, fsa)
+			flow.generateTimeEvent(entry, fsa)
+			if (entry.createTimerService) {
+				flow.generateTimerService(entry, fsa);
+			}
+		}
+		
+		if (entry.createRuntimeService) {
+			flow.generateRuntimeService(entry, fsa)
+		}
+		
+		flow.generateStatemachineInterface(entry, fsa)
+		flow.generateStatemachine(entry, fsa)
+	}
+}

+ 230 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/Naming.xtend

@@ -0,0 +1,230 @@
+package org.yakindu.sct.generator.java
+
+import com.google.inject.Inject
+import java.util.Arrays
+import java.util.List
+import java.util.regex.Matcher
+import java.util.regex.Pattern
+import org.eclipse.emf.ecore.EObject
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sexec.ExecutionNode
+import org.yakindu.sct.model.sexec.ExecutionScope
+import org.yakindu.sct.model.sexec.ExecutionState
+import org.yakindu.sct.model.sexec.Step
+import org.yakindu.sct.model.sgraph.Event
+import org.yakindu.sct.model.sgraph.State
+import org.yakindu.sct.model.sgraph.Variable
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import org.yakindu.sct.model.stext.stext.InternalScope
+
+import static org.yakindu.sct.generator.java.INaming.*
+import org.yakindu.sct.model.stext.naming.StextNameProvider
+
+class Naming implements INaming {
+	
+	@Inject extension Navigation
+	
+	@Inject StextNameProvider provider;
+	
+	def iStatemachineClass() {
+		"IStatemachine"
+	}
+	
+	def iTimedStatemachineClass() {
+		"ITimedStatemachine"
+	}
+	
+	def iTimerServiceClass() {
+		"I" + timerServiceClass
+	}
+	
+	def timerServiceClass() {
+		"TimerService"
+	}
+	
+	def timeEventClass() {
+		"TimeEvent"
+	}
+	
+	def runtimeServiceClass() {
+		"RuntimeService"
+	}
+	
+	def java(String it) {
+		it + ".java"
+	}
+	
+	def asPrivate(String it) {
+		"private " + it
+	}
+	
+	def asPublic(String it) {
+		"public " + it
+	}
+	
+	def String getInternalOperationCallbackName(InternalScope it) {
+		"InternalOperationCallback"
+	}
+	
+	def boolean isJavaKeyword(String name) {
+		var String lowName = name.toLowerCase();
+		for (String keyword : Arrays::asList(JAVA_KEYWORDS)) {
+			var Pattern pattern = Pattern::compile("^" + keyword + "$");
+			var Matcher matcher = pattern.matcher(lowName);
+			if (matcher.find()) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	def dispatch String statemachineName(String name) {
+		// remove whitespaces;
+		var String newName = name.replace(" ", "")
+		if (isJavaKeyword(name)) {
+			return newName + "SM"
+		}
+		return newName
+	}
+	
+	def dispatch String statemachineName(ExecutionFlow it) {
+		return name.statemachineName.toFirstUpper()
+	}
+	
+	def statemachineClassName(ExecutionFlow it) {
+		statemachineName + "Statemachine"
+	}
+	
+	def statemachineInterfaceName(ExecutionFlow it) {
+		"I" + statemachineClassName
+	}
+	
+	def String getInterfaceName(InterfaceScope it) {  
+		if (name != null && !name.toLowerCase().matches("default")) {
+			return "SCI" + name.toFirstUpper()
+		}
+		else {
+			return "SCIDefault";
+		}
+	}
+	
+	def String getInterfaceImplName(InterfaceScope it) {
+		getInterfaceName() + "Impl";
+	}
+	
+	def String getInterfaceListenerName(InterfaceScope it) {
+		interfaceName + "Listener";
+	}
+	
+	def String getInterfaceOperationCallbackName(InterfaceScope it) {
+		interfaceName + "OperationCallback"
+	}
+	
+	def private String fullQualifiedStateName(String name) {
+		name.substring(name.indexOf(".") + 1).replace(".", "_")
+	}
+	
+	def dispatch String stateName(State state) {
+		val String name = provider.getFullyQualifiedName(state).toString();
+		name.fullQualifiedStateName
+	}
+	
+	def dispatch String stateName(ExecutionState it) {
+		name.fullQualifiedStateName
+	}
+	
+	def asIdentifier(String it) {
+		replaceAll('[^a-z&&[^A-Z&&[^0-9]]]', '_').toFirstLower
+	}
+	
+	def asName(String it) {
+		asIdentifier.toFirstUpper
+	}
+	
+	def asEscapedIdentifier(String it) {
+		var s = it
+		if (s.isJavaKeyword) {
+			s = s + '_ID'
+		}
+		return s.asIdentifier
+	}
+	
+	def asEscapedName(String it) {
+		asEscapedIdentifier.toFirstUpper
+	}
+	
+	def String getValueIdentifier(Event it){
+		name.asIdentifier+"Value"
+	}
+	
+	def private varName(Variable it) {
+		if (name.equalsIgnoreCase("class")) {
+			name.asEscapedName
+		}
+		else {
+			name.asName
+		}
+	}
+	
+	def String getter(Variable it) {
+		return "get" + varName + "()"
+	}
+	
+	def String setter(Variable it) {
+		"set" + varName
+	}
+	
+	def String getNullStateName() {
+		"$NullState$";
+	}
+	
+	def functionName(Step it) {
+		switch (it) {
+			case isCheckFunction : asCheckFunction
+			case isEntryAction: asEntryActionFunction
+			case isExitAction : asExitActionFunction
+			case isEffect : asEffectFunction
+			case isEnterSequence : asEnterSequenceFunction
+			case isDeepEnterSequence : asDeepEnterSequenceFunction
+			case isShallowEnterSequence : asShallowEnterSequenceFunction
+			case isExitSequence : asExitSequenceFunction
+			case isReactSequence : asReactFunction
+			default : ""
+		} 
+	}
+	
+	def asCheckFunction(Step it) { functionName(newArrayList('check', elementName, reaction.name)) }
+	 
+	def asEffectFunction(Step it) { functionName(newArrayList('effect', elementName, reaction.name)) }
+	 
+	def asEntryActionFunction(Step it) { functionName('entryAction') }
+	
+	def asExitActionFunction(Step it) { functionName('exitAction') }
+	 
+	def asEnterSequenceFunction(Step it) { functionName('enterSequence') }
+		 
+	def asDeepEnterSequenceFunction(Step it) { functionName('deepEnterSequence') }
+	 
+	def asShallowEnterSequenceFunction(Step it) { functionName('shallowEnterSequence') }
+	 
+	def asExitSequenceFunction(Step it) { functionName('exitSequence') }
+	 
+	def asReactFunction(Step it) { functionName('react') }
+	
+	def functionName(Step it, String fName) { functionName(newArrayList(fName, elementName)) }
+	
+	//Changed compared to c
+	def functionName(EObject it, List<String> segments) {
+		segments.fold("", [s, seg | s + if (seg.empty) "" else seg.toFirstUpper]).asIdentifier
+	}
+	
+	def dispatch String elementName(EObject it) { eContainer.elementName }
+	
+	def dispatch String elementName(ExecutionScope it) { (if (superScope != null && ! superScope.elementName.empty) superScope.elementName + "_" else "") + name }	
+	
+	def dispatch String elementName(ExecutionState it) { (if (superScope != null && ! superScope.elementName.empty) superScope.elementName + "_" else "") + simpleName }	
+	
+	def dispatch String elementName(ExecutionNode it) { name }	
+	
+	def dispatch String elementName(ExecutionFlow it) { "" }
+}

+ 301 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/Navigation.xtend

@@ -0,0 +1,301 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Commiters of Yakindu - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgraph.Scope
+import org.yakindu.sct.model.stext.stext.EventDefinition
+import java.util.List
+import java.util.ArrayList
+import org.yakindu.sct.model.stext.stext.InternalScope
+import org.yakindu.sct.model.stext.stext.Direction
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import org.yakindu.sct.model.stext.stext.VariableDefinition
+import org.yakindu.sct.model.stext.stext.OperationDefinition
+import org.yakindu.sct.model.sexec.TimeEvent
+import org.yakindu.sct.model.sexec.ExecutionState
+import org.yakindu.sct.model.sexec.ExecutionRegion
+import org.yakindu.sct.model.sexec.ExecutionScope
+import org.yakindu.sct.model.sgraph.Variable
+import org.yakindu.sct.model.sgraph.Event
+import org.yakindu.sct.model.sexec.Step
+import org.yakindu.sct.model.sexec.ExecutionNode
+import org.yakindu.sct.model.sexec.Reaction
+import org.yakindu.sct.model.sexec.Check
+import org.eclipse.emf.ecore.EObject
+import org.yakindu.sct.model.stext.stext.ElementReferenceExpression
+import org.yakindu.sct.model.sgraph.Declaration
+import org.yakindu.sct.model.stext.stext.FeatureCall
+import org.yakindu.sct.model.stext.stext.Expression
+
+class Navigation {
+	
+	def isTimed (ExecutionFlow it) {
+		scopes.filter[declarations.filter( typeof(TimeEvent) ).size > 0].size > 0
+	}
+	
+	def dispatch List<EventDefinition> getOutgoingEvents(ExecutionFlow flow) {
+		val events = new ArrayList<EventDefinition>()
+		for (scope: flow.scopes) {
+			events.addAll(scope.outgoingEvents)
+		}
+		return events
+	}
+	
+	def boolean hasHistory(ExecutionFlow it) {
+		historyVector != null && historyVector.size > 0;		
+	}
+	
+	def dispatch boolean hasOutgoingEvents(ExecutionFlow it) {
+		return !outgoingEvents.empty
+	}
+	
+	def getTimeEvents(ExecutionFlow flow) {
+		val timeEvents = new ArrayList<TimeEvent>
+		flow.scopes.forEach[timeEvents.addAll(declarations.filter(typeof(TimeEvent)))]
+		return timeEvents
+	} 
+	
+	def getInternalScopeEvents(ExecutionFlow flow) {
+		val events = new ArrayList<EventDefinition>
+		flow.internalScopes.forEach[events.addAll(eventDefinitions)]
+		return events
+	}
+	
+	def getInternalScopeVariables(ExecutionFlow flow) {
+		val variables = new ArrayList<VariableDefinition>
+		flow.internalScopes.forEach[variables.addAll(variableDefinitions)]
+		return variables
+	}
+	
+	def InternalScope getInternalScope(ExecutionFlow it) {
+		return it.scopes.filter(typeof(InternalScope)).head
+	}
+	
+	def getDefaultScope(ExecutionFlow it) {
+		interfaceScopes.filter[name == null || name.empty].head
+	}
+	
+	def Iterable<InternalScope> getInternalScopes(ExecutionFlow it) {
+		return scopes.filter(typeof(InternalScope))
+	}
+	
+	def Iterable<InterfaceScope> getInterfaceScopes(ExecutionFlow it) {
+		return scopes.filter(typeof(InterfaceScope))
+	}
+	
+	def List<EventDefinition> getIncomingEvents(Scope it) {
+		val events = new ArrayList<EventDefinition>()
+		declarations.filter(typeof(EventDefinition)).forEach(ev | if (ev.direction == Direction::IN) events += ev)
+		return events
+	}
+	
+	def boolean hasIncomingEvents(Scope it) {
+		return !incomingEvents.empty
+	}
+	
+	def boolean hasEvents(Scope it) {
+		return !eventDefinitions.empty
+	}
+	
+	def dispatch List<EventDefinition> getOutgoingEvents(Scope scope) {
+		val events = new ArrayList<EventDefinition>()
+		scope.declarations.filter(typeof(EventDefinition)).forEach(ev | if (ev.direction == Direction::OUT) events += ev)
+		return events
+	}
+	
+	def dispatch boolean hasOutgoingEvents(Scope it) {
+		return !outgoingEvents.empty
+	}
+	
+	def getVariableDefinitions(Scope it) {
+		return declarations.filter(typeof(VariableDefinition))
+	} 
+	
+	def getEventDefinitions(Scope scope) {
+		scope.declarations.filter(typeof(EventDefinition))
+	}
+	
+	def getOperations(Scope it) {
+		declarations.filter(typeof(OperationDefinition));
+	}
+	
+	def hasOperations(Scope it) {
+		!operations.isEmpty;
+	}
+	
+	def dispatch List<ExecutionState> subStates(ExecutionState it) {
+		subScopes.fold(new ArrayList<ExecutionState>, 
+			[a, s | 
+				a.addAll(s.subStates)
+				a
+			]
+		)
+	} 
+	
+	def dispatch List<ExecutionState> subStates(ExecutionRegion it) {
+		subScopes.fold(new ArrayList<ExecutionState>, 
+			[a, s | 
+				a.add(s as ExecutionState)
+				a.addAll(s.subStates)
+				a
+			]
+		)
+	} 
+	
+	def dispatch List<ExecutionState> subStates(ExecutionScope it) {
+		return new ArrayList<ExecutionState>()
+	}
+	
+	def referencedChecks(ExecutionNode it) {
+		reactions.filter( r | r.check != null && r.check.refs.size > 0).map[it.check]
+	}
+
+	def referencedEffects(ExecutionNode it) {
+		reactions.filter( r | r.effect != null && r.effect.caller.size > 0).map( r | r.effect )
+	}
+	
+	def List<Step> checkFunctions(ExecutionFlow it) {
+		val funcs = new ArrayList<Step>()
+		funcs += referencedChecks
+		states.forEach( s | funcs += s.referencedChecks )
+		nodes.forEach( n | funcs += n.referencedChecks )
+		return funcs
+	}
+	 
+	def List<Step> effectFunctions(ExecutionFlow it) {
+		val funcs = new ArrayList<Step>()
+		funcs += referencedEffects
+		states.forEach( s | funcs += s.referencedEffects )
+		nodes.forEach( n | funcs += n.referencedEffects )
+		return funcs
+	}
+	 
+	def List<Step> entryActionFunctions(ExecutionFlow it) {
+		val funcs = new ArrayList<Step>()
+		if (entryAction.called) funcs.add(entryAction) 
+		states.forEach( s | if (s.entryAction.called) funcs += s.entryAction )
+		return funcs
+	}
+	
+	def List<Step> exitActionFunctions(ExecutionFlow it) {
+		val funcs = new ArrayList<Step>()
+		if (exitAction.called) funcs.add(exitAction) 
+		states.forEach( s | if (s.exitAction.called) funcs += s.exitAction )
+		return funcs
+	}
+	 
+	def List<Step> enterSequenceFunctions(ExecutionFlow it) {
+		val funcs = new ArrayList<Step>()
+		if (enterSequence.called) funcs.add(enterSequence) 
+		states.forEach( s | if (s.enterSequence.called) funcs += s.enterSequence )
+		regions.forEach( s | {
+			if (s.enterSequence.called) funcs += s.enterSequence
+			if (s.deepEnterSequence.called) funcs += s.deepEnterSequence
+			if (s.shallowEnterSequence.called) funcs += s.shallowEnterSequence
+		})
+		return funcs
+	}
+	 
+	def List<Step> exitSequenceFunctions(ExecutionFlow it) {
+		val funcs = new ArrayList<Step>()
+		if (exitSequence.called) funcs.add(exitSequence) 
+		states.forEach( s | if (s.exitSequence.called) funcs += s.exitSequence )
+		regions.forEach( s | if (s.exitSequence.called) funcs += s.exitSequence )
+		return funcs
+	}
+	 
+	def List<Step> reactFunctions(ExecutionFlow it) {
+		val funcs = new ArrayList<Step>()
+		if (reactSequence.called) funcs.add(reactSequence) 
+		states.forEach( s | if (s.reactSequence.called) funcs += s.reactSequence )
+		nodes.forEach( s | if (s.reactSequence.called) funcs += s.reactSequence )
+		return funcs
+	}
+	
+	def isCalled(Step it) { it != null && caller.size > 0 }
+	
+	def dispatch Reaction reaction(Check it) { eContainer as Reaction }
+	def dispatch Reaction reaction(EObject it) { eContainer?.reaction }
+	def dispatch Reaction reaction(Reaction it) { it }
+	
+	def isEntryAction(Step it) { eContainer.isEntryAction(it) }
+	def dispatch isEntryAction(ExecutionFlow it, Step s) { entryAction == s }
+	def dispatch isEntryAction(ExecutionState it, Step s) { entryAction == s }
+	def dispatch isEntryAction(EObject it, Step s) { false }
+	
+	def isExitAction(Step it) { eContainer.isExitAction(it) }
+	def dispatch isExitAction(ExecutionFlow it, Step s) { exitAction == s }
+	def dispatch isExitAction(ExecutionState it, Step s) { exitAction == s }
+	def dispatch isExitAction(EObject it, Step s) { false }
+	
+	def isEffect(Step it) { eContainer.isEffect(it) }
+	def dispatch isEffect(Reaction it, Step s) { effect == s }
+	def dispatch isEffect(EObject it, Step s) { false }
+	
+	def isEnterSequence(Step it) { eContainer.isEnterSequence(it) }
+	def dispatch isEnterSequence(ExecutionScope it, Step s) { enterSequence == s }
+	def dispatch isEnterSequence(EObject it, Step s) { false }
+	
+	def isDeepEnterSequence(Step it) { eContainer.isDeepEnterSequence(it) }
+	def dispatch isDeepEnterSequence(ExecutionRegion it, Step s) { deepEnterSequence == s }
+	def dispatch isDeepEnterSequence(EObject it, Step s) { false }
+	
+	def isShallowEnterSequence(Step it) { eContainer.isShallowEnterSequence(it) }
+	def dispatch isShallowEnterSequence(ExecutionRegion it, Step s) { shallowEnterSequence == s }
+	def dispatch isShallowEnterSequence(EObject it, Step s) { false }
+
+	def isExitSequence(Step it) { eContainer.isExitSequence(it) }
+	def dispatch isExitSequence(ExecutionScope it, Step s) { exitSequence == s }
+	def dispatch isExitSequence(EObject it, Step s) { false }
+	
+	def isReactSequence(Step it) { eContainer.isReactSequence(it) }
+	def dispatch isReactSequence(ExecutionNode it, Step s) { reactSequence == s }
+	def dispatch isReactSequence(EObject it, Step s) { false }
+	
+	def isCheckFunction(Step it) { it instanceof Check }
+	
+	def dispatch scope(Variable it) {
+		if (eContainer instanceof InterfaceScope)
+			eContainer as InterfaceScope
+		else
+			null
+	}
+	
+	def dispatch scope(Event it) {
+		if (eContainer instanceof InterfaceScope)
+			eContainer as InterfaceScope
+		else
+			null
+	}
+	
+	def dispatch scope(OperationDefinition it) {
+		if (eContainer instanceof InterfaceScope)
+			eContainer as InterfaceScope
+		else
+			null
+	}
+	
+	def dispatch Declaration definition(ElementReferenceExpression it) {
+		if (reference instanceof Declaration) reference as Declaration
+	}
+	
+	def dispatch Declaration definition(FeatureCall it) {
+		if (feature instanceof Declaration) feature as Declaration
+	}
+	
+	def dispatch Declaration definition(Expression it) {
+		null
+	}
+	
+	def Event event(Declaration it) {
+		if ( it instanceof Event ) it as Event else null 	
+	} 
+}

+ 241 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/RuntimeService.xtend

@@ -0,0 +1,241 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.eclipse.xtext.generator.IFileSystemAccess
+import com.google.inject.Inject
+
+class RuntimeService {
+	
+	@Inject
+	extension Naming 
+	
+	@Inject
+	extension GenmodelEntries
+	
+	def generateRuntimeService(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+		fsa.generateFile(entry.basePackagePath + '/' + runtimeServiceClass.java, content(entry))
+	}
+	
+	def private content(GeneratorEntry entry) {
+		'''
+		«entry.licenseText»
+		package «entry.getBasePackageName()»;
+		
+		import java.util.HashMap;
+		import java.util.LinkedList;
+		import java.util.List;
+		import java.util.Map;
+		import java.util.Timer;
+		import java.util.TimerTask;
+		import java.util.concurrent.locks.ReentrantReadWriteLock;
+		
+		/**
+		 * Runtime service for state machines to execute a run to completion step
+		 * periodically.
+		 * 
+		 */
+		public class RuntimeService {
+
+			private static RuntimeService runtimeService;
+
+			private Timer timer = null;
+
+			private Map<Long, StatemachineTimerTask> timerTasks = new HashMap<Long, StatemachineTimerTask>();
+
+			private class StatemachineTimerTask extends TimerTask {
+
+				private List<IStatemachine> statemachineList = new LinkedList<IStatemachine>();
+
+				private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+				private boolean isPaused = false;
+
+				@Override
+				public void run() {
+					lock.readLock().lock();
+					if (!isPaused) {
+						for (IStatemachine statemachine : statemachineList) {
+							statemachine.runCycle();
+						}
+					}
+					lock.readLock().unlock();
+				}
+
+				/**
+				 * Adds the given state machine to the TimerTask.
+				 * 
+				 * @param statemachine
+				 * @return {@code true} if state machine is added properly.
+				 */
+				public boolean addStatemachine(IStatemachine statemachine) {
+					lock.writeLock().lock();
+					boolean ret = statemachineList.add(statemachine);
+					lock.writeLock().unlock();
+					return ret;
+				}
+
+				/**
+				 * Removes the given state machine from the TimerTask.
+				 * 
+				 * @param statemachine
+				 * @return {@code true} if state machine is removed properly.
+				 */
+				public boolean removeStatemachine(IStatemachine statemachine) {
+					lock.writeLock().lock();
+					boolean ret = statemachineList.remove(statemachine);
+					lock.writeLock().unlock();
+					return ret;
+				}
+
+				public void pause() {
+					isPaused = true;
+				}
+
+				public void resume() {
+					isPaused = false;
+				}
+			}
+
+			private RuntimeService() {
+				// Not intended to be instantiated.
+			}
+
+			/**
+			 * Returns the {@code RuntimeService} instance as singleton.
+			 * 
+			 * @return The singleton {@code RuntimeService} instance
+			 */
+			public static RuntimeService getInstance() {
+				if (runtimeService == null) {
+					runtimeService = new RuntimeService();
+				}
+				return runtimeService;
+			}
+
+			/**
+			 * Registers an {@link IStatemachine} for scheduled fixed rate execution
+			 * 
+			 * @param statemachine
+			 *            - The statemachine to execute
+			 * @param cyclePeriod
+			 *            - the fixed rate cycle period for scheduling
+			 * @return {@code true} if state machine is added properly.
+			 */
+			public boolean registerStatemachine(IStatemachine statemachine,
+					long cyclePeriod) {
+		
+				if (timerTasks.containsKey(cyclePeriod)) {
+					// TimerTask for cycle time already existing -> add statemachine
+					return timerTasks.get(cyclePeriod).addStatemachine(statemachine);
+				} else {
+					// Create new TimerTask for cycle period and add statemachine
+					StatemachineTimerTask timerTask = new StatemachineTimerTask();
+					timerTasks.put(cyclePeriod, timerTask);
+					boolean ret = timerTask.addStatemachine(statemachine);
+					// Create a new Timer instance if runtime service was cancelled
+					// before
+					if (timer == null) {
+						timer = new Timer();
+					}
+					timer.scheduleAtFixedRate(timerTask, 0, cyclePeriod);
+					return ret;
+				}
+			}
+
+			/**
+			 * Removes the given state machine from runtime service.
+			 * 
+			 * @param statemachine
+			 *            - the statemachine which should be removed
+			 * @param cyclePeriod
+			 *            - the scheduling cycle period of the statemachine
+			 * @return {@code true} if state machine is removed properly.
+			 */
+			public boolean unregisterStatemachine(IStatemachine statemachine,
+					long cyclePeriod) {
+				if (timerTasks.containsKey(cyclePeriod)) {
+					boolean ret = timerTasks.get(cyclePeriod).removeStatemachine(
+							statemachine);
+		
+					return ret;
+				}
+				return false;
+			}
+
+			/**
+			 * Cancels the execution of statemachines for the given cycle period. This
+			 * stops the execution of statemachines which are registered for the given
+			 * cycle period and cancels the executing {@link TimerTask}.
+			 * 
+			 * @return {@code true} if poperly cancelled
+			 */
+			public boolean cancelAll(long cyclePeriod) {
+				if (timer != null && timerTasks.containsKey(cyclePeriod)) {
+					TimerTask task = timerTasks.get(cyclePeriod);
+					task.cancel();
+					timer.purge();
+					timerTasks.remove(cyclePeriod);
+					return true;
+				}
+				return false;
+			}
+
+			/**
+			 * Pauses the execution of all statemachine which are registered for the
+			 * given cyclePeriod.
+			 * 
+			 * @param cyclePeriod
+			 * @return {@code true} if poperly paused
+			 * 
+			 */
+			public boolean pauseAll(long cyclePeriod) {
+				if (timerTasks.containsKey(cyclePeriod)) {
+					timerTasks.get(cyclePeriod).pause();
+					return true;
+				}
+				return false;
+			}
+
+			/**
+			 * Resumes the execution of all statemachine which are registered for the
+			 * given cyclePeriod.
+			 * 
+			 * @param cyclePeriod
+			 * @return {@code true} if poperly resumed
+			 * 
+			 */
+			public boolean resumeAll(long cyclePeriod) {
+				if (timerTasks.containsKey(cyclePeriod)) {
+					timerTasks.get(cyclePeriod).resume();
+					return true;
+				}
+				return false;
+			}
+
+			/**
+			 * Cancels the execution of all registered statemachines. This cancels the
+			 * executing {@link Timer} freeing all allocated resources and terminates
+			 * all existing execution threads.
+			 */
+			public void cancelTimer() {
+				if (timer != null) {
+					timer.cancel();
+					timer.purge();
+					timerTasks.clear();
+					timer = null;
+				}
+			}
+		}
+		'''
+	}
+}

+ 551 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/Statemachine.xtend

@@ -0,0 +1,551 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+*/
+package org.yakindu.sct.generator.java
+
+import com.google.inject.Inject
+import org.eclipse.xtext.generator.IFileSystemAccess
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import org.yakindu.sct.model.stext.stext.Direction
+import org.yakindu.sct.model.stext.stext.EventDefinition
+import java.util.List
+import org.yakindu.sct.model.sexec.Step
+import org.yakindu.sct.model.sexec.Check
+
+class Statemachine {
+	
+	@Inject extension Naming
+	@Inject extension GenmodelEntries
+	@Inject extension Navigation
+	@Inject extension TypeModel
+	@Inject extension FlowCode
+	@Inject Beautifier beautifier
+	
+	def generateStatemachine(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+		var filename = flow.getImplementationPackagePath(entry) + '/' + flow.statemachineClassName.java
+		var content = beautifier.format(filename, content(flow, entry))
+		fsa.generateFile(filename, content)
+	}
+	
+	def private content(ExecutionFlow flow, GeneratorEntry entry) '''
+		«entry.licenseText»
+		package «flow.getImplementationPackageName(entry)»;
+		«flow.createImports(entry)»
+		
+		public class «flow.statemachineClassName» implements «flow.statemachineInterfaceName» {
+			
+			«flow.createFieldDeclarations(entry)»
+			
+			«flow.createConstructor»
+			
+			«flow.initFunction»
+			
+			«flow.enterFunction»
+			
+			«flow.exitFunction»
+			
+			«flow.clearInEventsFunction»
+			
+			«flow.clearOutEventsFunction»
+			
+			«flow.activeFunction»
+			
+			«flow.timingFunctions»
+			
+			«flow.interfaceAccessors»
+			
+			«flow.internalScopeFunctions»
+			
+			«flow.defaultInterfaceFunctions(entry)»
+			
+			«flow.functionImplementations»
+			
+			«flow.runCycleFunction»
+		}
+	'''
+	
+	def private createImports(ExecutionFlow flow, GeneratorEntry entry) {
+		'''
+		«IF entry.createInterfaceObserver && flow.hasOutgoingEvents»
+		import java.util.LinkedList;
+		import java.util.List;
+		«ENDIF»
+		«IF flow.timed»
+			import «entry.getBasePackageName()».TimeEvent;
+			import «entry.getBasePackageName()».ITimerService;
+		«ENDIF»
+		'''
+	}
+	
+	def private createFieldDeclarations(ExecutionFlow flow, GeneratorEntry entry) {
+		'''
+		«FOR event : flow.internalScopeEvents»
+		private boolean «event.name.asEscapedIdentifier»;
+		
+		«IF !event.type.isVoid()»
+			private «event.type.javaType» «event.valueIdentifier»;
+		«ENDIF»
+		«ENDFOR»
+		«var timeEvents = flow.timeEvents»
+		«FOR timeEvent: timeEvents»
+			private final TimeEvent «timeEvent.name.asEscapedIdentifier» = new TimeEvent(«timeEvent.periodic», «timeEvents.indexOf(timeEvent)»); 
+		«ENDFOR»
+	
+		«IF flow.timed»
+			private final boolean[] timeEvents = new boolean[«timeEvents.size»];
+		«ENDIF»
+	
+		«FOR scope : flow.interfaceScopes»
+			«scope.toImplementation(entry)»
+			
+			private «scope.interfaceImplName» «scope.interfaceName.asEscapedIdentifier»;
+		«ENDFOR»
+	
+		public enum State {
+			«FOR state : flow.states»
+				«state.stateName.asEscapedIdentifier»,
+			«ENDFOR»
+			«getNullStateName()»
+		};
+		
+		«FOR variable : flow.internalScopeVariables»
+		private «variable.type.getJavaType()» «variable.name.asEscapedIdentifier»«variable.getInitialValueAssignment()»;
+		«ENDFOR»
+		
+		«IF flow.hasHistory»
+		private State[] historyVector = new State[«flow.historyVector.size»];
+		«ENDIF»
+		private final State[] stateVector = new State[«flow.stateVector.size»];
+		
+		private int nextStateIndex;
+		
+		«IF flow.timed»
+		private ITimerService timerService;
+		
+		private long cycleStartTime;
+		«ENDIF»
+		
+		«FOR internal : flow.internalScopes»
+		«IF internal.hasOperations()»
+			private «internal.getInternalOperationCallbackName()» operationCallback;
+		«ENDIF»
+		«ENDFOR»
+		'''
+	}
+	
+	def private createConstructor(ExecutionFlow flow) {
+		'''
+		public «flow.statemachineClassName»() {
+			
+			«FOR scope : flow.interfaceScopes»
+			«scope.interfaceName.asEscapedIdentifier» = new «scope.getInterfaceImplName()»();
+			«ENDFOR»
+			
+			«FOR timeEvent : flow.timeEvents»
+				«timeEvent.name.asEscapedIdentifier».setStatemachine(this);
+			«ENDFOR»
+			}
+		'''
+	}
+	
+	def private initFunction(ExecutionFlow flow) {
+		'''
+		public void init() {
+			«IF flow.timed»
+			if (timerService == null) {
+				throw new IllegalStateException("TimerService not set.");
+			}
+			«ENDIF»
+			for (int i = 0; i < «flow.stateVector.size»; i++) {
+				stateVector[i] = State.$NullState$;
+			}
+			
+			«IF flow.hasHistory»
+			for (int i = 0; i < «flow.historyVector.size»; i++) {
+				historyVector[i] = State.$NullState$;
+			}
+			«ENDIF»
+			clearEvents();
+			clearOutEvents();
+		}
+		'''
+	}
+	
+	def private clearInEventsFunction(ExecutionFlow flow) {
+		'''
+		protected void clearEvents() {
+			«FOR scope : flow.interfaceScopes»
+				«IF scope.hasEvents»
+					«scope.interfaceName.asEscapedIdentifier».clearEvents();
+				«ENDIF»
+			«ENDFOR»
+			«FOR scope : flow.internalScopes»
+				«FOR event : scope.eventDefinitions»
+					«event.name.asEscapedIdentifier» = false;
+				«ENDFOR»
+			«ENDFOR»
+			
+			«IF flow.timed»
+			for (int i=0; i<timeEvents.length; i++) {
+				timeEvents[i] = false;
+			}
+			«ENDIF»
+		}
+		'''
+	}
+	
+	def private clearOutEventsFunction(ExecutionFlow flow) {
+		'''
+		protected void clearOutEvents() {
+			«FOR scope : flow.interfaceScopes»
+				«IF scope.hasOutgoingEvents»
+					«scope.interfaceName.asEscapedIdentifier».clearOutEvents();
+				«ENDIF»
+			«ENDFOR»
+		}
+		'''
+	}
+	
+	def private isActiveFunction(ExecutionFlow flow) {
+		'''
+		public boolean isStateActive(State state){
+			switch (state) {
+				«FOR s : flow.states»
+				case «s.stateName.asEscapedIdentifier» : 
+					return «IF s.leaf»stateVector[«s.stateVector.offset»] == State.«s.stateName.asEscapedIdentifier»
+					«ELSE»stateVector[«s.stateVector.offset»].ordinal() >= State.«s.stateName.asEscapedIdentifier».ordinal()
+						&& stateVector[«s.stateVector.offset»].ordinal() <= State.«s.subStates.last.stateName.asEscapedIdentifier».ordinal()«ENDIF»;
+				«ENDFOR»
+				default: return false;
+			}
+		}
+		'''
+	}
+	
+	def private timingFunctions(ExecutionFlow flow) {
+		'''
+		«IF flow.timed»
+			public void setTimerService(ITimerService timerService) {
+				this.timerService = timerService;
+			}
+			
+			public ITimerService getTimerService() {
+				return timerService;
+			}
+			
+			public void onTimeEventRaised(TimeEvent timeEvent) {
+				timeEvents[timeEvent.getIndex()] = true;
+			}
+		«ENDIF»
+		'''
+	}
+	
+	def private interfaceAccessors(ExecutionFlow flow) {
+		'''
+		«FOR scope : flow.interfaceScopes»
+			public «scope.interfaceName» get«scope.interfaceName»() {
+				return «scope.interfaceName.toFirstLower()»;
+			}
+		«ENDFOR»
+		'''
+	}
+	
+	def private toImplementation(InterfaceScope scope, GeneratorEntry entry) {
+		'''
+		private final class «scope.getInterfaceImplName» implements «scope.getInterfaceName» {
+		
+		«IF entry.createInterfaceObserver && scope.hasOutgoingEvents»
+			private List<«scope.getInterfaceListenerName»> listeners = new LinkedList<«scope.getInterfaceListenerName»>();
+			
+			public List<«scope.getInterfaceListenerName»> getListeners() {
+				return listeners;
+			}
+		«ENDIF»
+		
+		«IF scope.hasOperations»
+			private «scope.getInterfaceOperationCallbackName()» operationCallback;
+			
+			public void set«scope.getInterfaceOperationCallbackName»(
+					«scope.getInterfaceOperationCallbackName» operationCallback) {
+				this.operationCallback = operationCallback;
+			}
+		«ENDIF»
+		
+		«FOR event : scope.eventDefinitions»
+			
+			private boolean «event.name.asEscapedIdentifier»;
+			
+			«IF !event.type.isVoid()»
+				private «event.type.getJavaType()» «event.valueIdentifier»;
+			«ENDIF»
+			
+			«IF event.direction == Direction::IN»
+				«IF !event.type.void»
+					public void raise«event.name.asName»(«event.type.getJavaType()» value) {
+						«event.name.asEscapedIdentifier» = true;
+						«event.valueIdentifier» = value;
+					}
+					
+					private «event.type.getJavaType()» get«event.name.asName»Value() {
+						«event.getIllegalAccessValidation()»
+						return «event.valueIdentifier»;
+					}
+					
+				«ELSE»
+					public void raise«event.name.asName»() {
+						«event.name.asEscapedIdentifier» = true;
+					}
+					
+				«ENDIF»
+			«ENDIF»
+			
+			«IF event.direction == Direction::OUT»
+				
+				public boolean isRaised«event.name.asName»() {
+					return «event.name.asEscapedIdentifier»;
+				}
+				
+				«IF !event.type.isVoid()»
+					private void raise«event.name.asName»(«event.type.getJavaType()» value) {
+						«event.name.asEscapedIdentifier» = true;
+						«event.valueIdentifier» = value;
+						«IF entry.createInterfaceObserver»
+						for («scope.interfaceListenerName» listener : listeners) {
+							listener.on«event.name.asEscapedName»Raised(value);
+						}
+						«ENDIF»
+					}
+					
+					public «event.type.getJavaType()» get«event.name.asName»Value() {
+						«event.getIllegalAccessValidation()»
+						return «event.valueIdentifier»;
+					}
+				«ELSE»
+					private void raise«event.name.asName»() {
+						«event.name.asEscapedIdentifier» = true;
+						«IF entry.createInterfaceObserver»
+							for («scope.interfaceListenerName» listener : listeners) {
+								listener.on«event.name.asEscapedName»Raised();
+							}
+						«ENDIF»
+					}
+				«ENDIF»
+			«ENDIF»
+		«ENDFOR»
+		
+		«FOR variable : scope.variableDefinitions»
+				
+				private «variable.type.getJavaType()» «variable.name.asEscapedIdentifier»«variable.initialValueAssignment»;
+				
+				public «variable.type.getJavaType()» «variable.getter» {
+					return «variable.name.asEscapedIdentifier»;
+				}
+				
+				«IF  !variable.readonly»
+					public void «variable.setter»(«variable.type.getJavaType()» value) {
+						this.«variable.name.asEscapedIdentifier» = value;
+					}
+				«ENDIF»
+		«ENDFOR»
+		
+		«IF scope.hasEvents»
+			public void clearEvents() {
+			«FOR event : scope.eventDefinitions»
+				«IF event.direction != Direction::OUT»
+				«event.name.asEscapedIdentifier» = false;
+				«ENDIF»
+			«ENDFOR»
+			}
+			
+		«ENDIF»
+		
+		«IF scope.hasOutgoingEvents()»
+			public void clearOutEvents() {
+			«FOR event : scope.eventDefinitions»
+				«IF event.direction == Direction::OUT»
+					«event.name.asEscapedIdentifier» = false;
+				«ENDIF»
+			«ENDFOR»
+			}
+		«ENDIF»
+		}
+		'''
+	}
+	
+	def private getIllegalAccessValidation(EventDefinition it) '''
+		if (! «name.asEscapedIdentifier» ) 
+			throw new IllegalStateException("Illegal event value acces. Event «name.asEscapedName» is not raised!");
+	'''
+	
+	def private internalScopeFunctions (ExecutionFlow flow) {
+		'''
+		«FOR event : flow.internalScopeEvents»
+			«IF !event.type.void»
+				private void raise«event.name.asEscapedName»(«event.type.getJavaType()» value) {
+					«event.valueIdentifier» = value;
+					«event.name.asEscapedIdentifier» = true;
+				}
+				
+				private «event.type.getJavaType()» get«event.name.asEscapedName»Value() {
+					«event.getIllegalAccessValidation()»
+					return «event.valueIdentifier»;
+				}
+			«ELSE»
+			
+				private void raise«event.name.asEscapedName»() {
+					«event.name.asEscapedIdentifier» = true;
+				}
+				
+			«ENDIF»
+		«ENDFOR»
+		«FOR variable : flow.internalScopeVariables»
+		private «variable.type.javaType» «variable.getter» {
+			return «variable.name.asEscapedName»;
+		}
+		
+		private void «variable.setter»(«variable.type.javaType» value) {
+			«variable.name.asEscapedIdentifier» = value;
+		}	
+		«ENDFOR»
+		
+		«FOR internal : flow.internalScopes»
+			«IF internal.hasOperations»
+				public void set«internal.internalOperationCallbackName»(
+						«internal.internalOperationCallbackName» operationCallback) {
+					this.operationCallback = operationCallback;
+				}
+			«ENDIF»
+		«ENDFOR»
+	'''
+	}
+	
+	def private defaultInterfaceFunctions(ExecutionFlow flow, GeneratorEntry entry) {
+		'''
+		«IF flow.defaultScope != null»
+			«var InterfaceScope scope = flow.defaultScope»
+			«FOR event : scope.eventDefinitions»
+				«IF event.direction == Direction::IN»
+					«IF !event.type.void»
+					public void raise«event.name.asName»(«event.type.javaType» value) {
+						«scope.interfaceName.asEscapedIdentifier».raise«event.name.asName»(value);
+					}
+					«ELSE»
+					public void raise«event.name.asName»() {
+						«scope.interfaceName.asEscapedIdentifier».raise«event.name.asName»();
+					}
+					«ENDIF»
+				«ENDIF»
+				«IF event.direction ==  Direction::OUT»
+					public boolean isRaised«event.name.asName»() {
+						return «scope.interfaceName.asEscapedIdentifier».isRaised«event.name.asName»();
+					}
+					«IF !event.type.isVoid()»
+						public «event.type.getJavaType()» get«event.name.asName»Value() {
+							return «scope.interfaceName.asEscapedIdentifier».get«event.name.asName»Value();
+						}
+					«ENDIF»
+				«ENDIF»
+			«ENDFOR»
+			
+			«FOR variable : scope.variableDefinitions»
+			public «variable.type.javaType» «variable.getter()» {
+				return «scope.interfaceName.asEscapedIdentifier».«variable.getter()»;
+			}
+			
+			public void «variable.setter»(«variable.type.javaType» value) {
+				«scope.interfaceName.asEscapedIdentifier».«variable.setter»(value);
+			}	
+			«ENDFOR»
+		«ENDIF»
+		
+		'''
+	}
+	
+	def private runCycleFunction(ExecutionFlow flow) {
+		'''
+		public void runCycle() {
+			
+			«IF flow.timed»
+			cycleStartTime = System.currentTimeMillis();
+			
+			«ENDIF»
+			clearOutEvents();
+			
+			for (nextStateIndex = 0; nextStateIndex < stateVector.length; nextStateIndex++) {
+				
+				switch (stateVector[nextStateIndex]) {
+				«FOR state : flow.states»
+					«IF state.reactSequence!=null»
+						case «state.stateName.asEscapedIdentifier»:
+							«state.reactSequence.functionName»();
+							break;
+					«ENDIF»
+				«ENDFOR»
+				default:
+					// «getNullStateName()»
+				}
+			}
+			
+			clearEvents();
+		}
+		'''
+	}
+	
+	def private enterFunction(ExecutionFlow it) '''
+		public void enter() {
+			«IF timed»
+			if (timerService == null) {
+				throw new IllegalStateException("TimerService not set.");
+			}
+			cycleStartTime = System.currentTimeMillis();
+			«ENDIF»
+			«enterSequence.code»
+		}
+	'''
+	
+	def private exitFunction(ExecutionFlow it) '''
+		public void exit(){
+			«exitSequence.code»
+		}
+	'''
+	
+	def private functionImplementations(ExecutionFlow it) '''
+		«checkFunctions.toImplementation»
+		«effectFunctions.toImplementation»
+		«entryActionFunctions.toImplementation»
+		«exitActionFunctions.toImplementation»
+		«enterSequenceFunctions.toImplementation»
+		«exitSequenceFunctions.toImplementation»
+		«reactFunctions.toImplementation»
+	'''
+	
+	def toImplementation(List<Step> steps) '''
+		«FOR s : steps»
+			«s.functionImplementation»
+		«ENDFOR»
+	'''
+	
+	def dispatch functionImplementation(Check it) '''
+		«stepComment»
+		private boolean «asCheckFunction»() {
+			return «code»;
+		}
+		
+	'''
+	
+	def dispatch functionImplementation(Step it) '''
+		«stepComment»
+		private void «functionName»() {
+			«code»
+		}
+		
+	'''
+}

+ 193 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/StatemachineInterface.xtend

@@ -0,0 +1,193 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+*/
+package org.yakindu.sct.generator.java
+
+import com.google.inject.Inject
+import org.eclipse.xtext.generator.IFileSystemAccess
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.yakindu.sct.model.stext.stext.Direction
+import org.yakindu.sct.model.stext.stext.OperationDefinition
+import org.yakindu.base.types.Parameter
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import org.yakindu.sct.model.stext.stext.InternalScope
+import org.yakindu.sct.model.sgraph.Scope
+
+class StatemachineInterface {
+	
+	@Inject extension Naming 
+	@Inject extension GenmodelEntries
+	@Inject extension Navigation
+	@Inject extension TypeModel
+	@Inject Beautifier beautifier
+	
+	def generateStatemachineInterface(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+		var filename = flow.getImplementationPackagePath(entry) + '/' + flow.statemachineInterfaceName.java
+		var content = beautifier.format(filename, content(flow, entry))
+		fsa.generateFile(filename, content)
+	}
+	
+	def private content(ExecutionFlow flow, GeneratorEntry entry) {
+		'''
+		«entry.licenseText»
+		package «flow.getImplementationPackageName(entry)»;
+		«IF entry.createInterfaceObserver && flow.hasOutgoingEvents»
+		import java.util.List;
+		«ENDIF»
+		import «entry.basePackageName».IStatemachine;
+		«IF flow.timed»
+		import «entry.basePackageName».ITimedStatemachine;
+		«ENDIF»
+		
+		public interface «flow.statemachineInterfaceName» extends «flow.statemachineInterfaceExtensions» {
+			
+			«FOR scope: flow.scopes»
+				«scope.createScope(entry)»
+			«ENDFOR»
+		}
+		'''
+	}
+	
+	def private createScope(Scope scope, GeneratorEntry entry) {
+		switch scope {
+			InterfaceScope: scope.createScope(entry)
+			InternalScope: scope.createScope
+		}
+	}
+	
+	def private createScope(InterfaceScope scope, GeneratorEntry entry) {
+		'''
+		«scope.createInterface(entry)»
+		«scope.createListenerInterface(entry)»
+		«scope.createOperationCallbackInterface»
+		
+		public «scope.interfaceName» get«scope.interfaceName»();
+		
+		'''
+	}
+	
+	def private createScope(InternalScope scope) {
+		'''
+		«IF scope.hasOperations()»
+			public interface «scope.internalOperationCallbackName» {
+				«FOR operation : scope.operations»
+					«operation.operationSignature»
+				«ENDFOR»
+			}
+			
+			public void set«scope.internalOperationCallbackName»(«scope.internalOperationCallbackName» operationCallback);
+		«ENDIF»
+		'''
+	}
+	
+	def private createInterface(InterfaceScope scope, GeneratorEntry entry) {
+		'''
+		public interface «scope.interfaceName» {
+			«scope.eventAccessors»
+			«scope.variableAccessors»
+			«IF entry.createInterfaceObserver && scope.hasOutgoingEvents»
+				public List<«scope.getInterfaceListenerName()»> getListeners();
+			«ENDIF»
+	
+			«IF scope.hasOperations()»
+				public void set«scope.getInterfaceOperationCallbackName()»(«scope.getInterfaceOperationCallbackName()» operationCallback);
+			«ENDIF»
+		}
+		'''
+	}
+	
+	def private createListenerInterface(InterfaceScope scope, GeneratorEntry entry) {
+		'''
+		«IF entry.createInterfaceObserver && scope.hasOutgoingEvents»
+			
+			public interface «scope.getInterfaceListenerName()» {
+				«FOR event : scope.eventDefinitions»
+					«IF event.direction ==  Direction::OUT»
+						«IF !event.type.isVoid()»
+							public void on«event.name.toFirstUpper()»Raised(«event.type.getJavaType()» value);
+						«ELSE»
+							public void on«event.name.toFirstUpper()»Raised();
+						«ENDIF»	
+					«ENDIF»
+				«ENDFOR»
+				}
+		«ENDIF»
+		'''
+	}
+	
+	def private createOperationCallbackInterface(InterfaceScope scope) {
+		'''
+		«IF scope.hasOperations»
+			
+			public interface «scope.getInterfaceOperationCallbackName()» {
+			«FOR operation : scope.operations»
+				«operation.operationSignature»
+			«ENDFOR»
+			}
+		«ENDIF»
+		'''
+	}
+	
+	def private eventAccessors(InterfaceScope scope) {
+		'''
+		«FOR event : scope.eventDefinitions»
+			«IF  event.direction ==  Direction::IN»
+				«IF !event.type.void»
+					public void raise«event.name.asName»(«event.type.getJavaType()» value);
+				«ELSE»
+					public void raise«event.name.asName»();
+				«ENDIF»
+			«ELSEIF event.direction ==  Direction::OUT»
+				public boolean isRaised«event.name.asName»();
+				«IF !event.type.void»
+					public «event.type.getJavaType()» get«event.name.asName»Value();
+				«ENDIF»	
+			«ENDIF»
+		«ENDFOR»
+		'''
+	}
+	
+	def private variableAccessors(InterfaceScope scope) '''
+		«FOR variable : scope.variableDefinitions»
+					public «variable.type.getJavaType()» «variable.getter»;
+					«IF  !variable.readonly»
+						public void «variable.setter»(«variable.type.getJavaType()» value);	
+					«ENDIF»
+		«ENDFOR»
+	'''
+	
+	def private String getStatemachineInterfaceExtensions(ExecutionFlow flow) {
+
+		var String interfaces = "";
+
+		if (flow.timed) {
+			interfaces = interfaces + "ITimedStatemachine,"
+		}
+
+		interfaces = interfaces + "IStatemachine"
+		
+		return interfaces;
+	}
+	
+	def private operationSignature(OperationDefinition it) {
+		'''
+		public «type.getJavaType()» «name.asEscapedIdentifier»(«FOR parameter : parameters SEPARATOR ', '»«parameter.identifier»«ENDFOR»);
+		'''
+	}
+	
+	def private identifier(Parameter parameter) {
+		if (parameter.name.isJavaKeyword()) {
+			return parameter.name + "Arg"
+		}
+		else {
+			parameter.name
+		}
+	}
+}

+ 92 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/TimeEventTemplate.xtend

@@ -0,0 +1,92 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.eclipse.xtext.generator.IFileSystemAccess
+import com.google.inject.Inject
+
+class TimeEventTemplate {
+	
+	@Inject
+	extension Naming 
+	
+	@Inject
+	extension GenmodelEntries
+	
+	def generateTimeEvent(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+		fsa.generateFile(entry.basePackagePath + '/' + timeEventClass.java, content(entry))
+	}
+	
+	def private content(GeneratorEntry entry) {
+		'''
+		«entry.licenseText»
+		package «entry.getBasePackageName()»;
+
+		/**
+		 * Event that reflects a time event. It's internally used by
+		 * {@link ITimedStatemachine}.
+		 * 
+		 * @author muehlbrandt
+		 * 
+		 * @param <T>
+		 */
+		public class TimeEvent {
+		
+			private boolean periodic;
+		
+			private ITimedStatemachine statemachine;
+			
+			int index;
+		
+			/**
+			 * Constructor for a time event.
+			 * 
+			 * @param periodic
+			 *            : Set to {@code true} if event should be repeated
+			 *            periodically.
+			 * 
+			 * @param index
+			 *            : Index position within the state machine's timeEvent array.
+			 */
+			public TimeEvent(boolean periodic, int index) {
+				this.periodic = periodic;
+				this.index = index;
+			}
+		
+			/**
+			 * Returns the state machine reference of the event.
+			 * 
+			 */
+			public ITimedStatemachine getStatemachine() {
+				return statemachine;
+			}
+		
+			/**
+			 * Sets the state machine reference of the event.
+			 * 
+			 * @param statemachine
+			 */
+			public void setStatemachine(ITimedStatemachine statemachine) {
+				this.statemachine = statemachine;
+			}
+		
+			public boolean isPeriodic() {
+				return periodic;
+			}
+		
+			public int getIndex() {
+				return index;
+			}
+		}
+		'''
+	}
+}

+ 91 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/TimerService.xtend

@@ -0,0 +1,91 @@
+/**
+  Copyright (c) 2012 committers of YAKINDU and others.
+  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:
+  	Markus Muehlbrandt - Initial contribution and API
+ */
+package org.yakindu.sct.generator.java
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.eclipse.xtext.generator.IFileSystemAccess
+import com.google.inject.Inject
+
+class TimerService {
+	
+	@Inject
+	extension Naming 
+	
+	@Inject
+	extension GenmodelEntries
+	
+	def generateTimerService(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+		fsa.generateFile(entry.basePackagePath + '/' + timerServiceClass.java, content(entry))
+	}
+	
+	def private content(GeneratorEntry entry) '''
+		«entry.licenseText»
+		package «entry.getBasePackageName()»;
+		
+		import java.util.HashMap;
+		import java.util.Map;
+		import java.util.Timer;
+		import java.util.TimerTask;
+		
+		/**
+		 * Default timer service implementation.
+		 * 
+		 */
+		public class TimerService implements ITimerService {
+		
+			private final Timer timer = new Timer();
+		
+			private final Map<TimeEvent, TimerTask> timerTaskMap = new HashMap<TimeEvent, TimerTask>();
+		
+			public void setTimer(final TimeEvent event, long time,
+					long cycleStartTime) {
+				// Reset existing TimerTask for event. This step isn't necessary if
+				// timer tasks are properly reset by sexec model.
+				if (timerTaskMap.containsKey(event)) {
+					resetTimer(event);
+				}
+		
+				// Create a new TimerTask for given event.
+				timerTaskMap.put(event, new TimerTask() {
+					@Override
+					public void run() {
+						event.getStatemachine().onTimeEventRaised(event);
+					}
+				});
+		
+				// start scheduling the timer
+				if (event.isPeriodic()) {
+					timer.scheduleAtFixedRate(timerTaskMap.get(event),
+							time - (System.currentTimeMillis() - cycleStartTime), time);
+				} else {
+					timer.schedule(timerTaskMap.get(event),
+							time - (System.currentTimeMillis() - cycleStartTime));
+				}
+			}
+		
+			public void resetTimer(TimeEvent event) {
+				if (timerTaskMap.containsKey(event) && timerTaskMap.get(event) != null) {
+					timerTaskMap.get(event).cancel();
+					timer.purge();
+				}
+				timerTaskMap.remove(event);
+			}
+		
+			/**
+			 * Cancels all running TimersTasks
+			 */
+			public void cancel() {
+				timer.cancel();
+				timer.purge();
+			}
+		}
+	'''
+}

+ 44 - 0
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/TypeModel.xtend

@@ -0,0 +1,44 @@
+package org.yakindu.sct.generator.java
+
+import org.yakindu.base.types.Type
+
+class TypeModel {
+	
+	def boolean isVoid(Type type) {
+		type == null || type.name == null || type.name == "void"
+	}
+	
+	def String getJavaType(Type type) {
+		switch (type.name) {
+		case "real" : "double"
+		case "integer" : "int"
+		case "boolean" : "boolean"
+		case "string" : "String"
+		case "void" : "void"
+		default : "//"+this
+		};
+	}
+		
+def String getJavaClassType(Type type) {
+		switch (type.name) {
+		case "real" : "Double"
+		case "integer" : "Integer"
+		case "boolean" : "Boolean"
+		case "string" : "String"
+		case "void" : "Void"
+		case null : "Void"
+		default : "//"+type
+		};
+	}
+		
+def String getInitialValue(Type type) {
+		switch (type.name) {
+		case "real" : "0D"
+		case "integer" : "0"
+		case "boolean" : "false"
+		case "string" : "\"\""
+		case "void" : "null"
+		default : ""
+		};
+	}
+}

+ 11 - 14
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/templates/Expression.ext

@@ -57,24 +57,21 @@ String toCode(PrimitiveValueExpression primValue) :
 	
 String toCode(ParenthesizedExpression e) :
 	"(" + e.expression.toCode() + ")";
-	
-String getVariableIdentifier(AssignmentExpression this) :
-	getContext(varRef).toFirstLower() + varRef.getVarName().toFirstLower();
 
 /* Assignment */
 String toCode(AssignmentExpression this) :
 	switch (operator) {
-		case AssignmentOperator::assign : getVariableIdentifier() + " = " + expression.toCode()
-		case AssignmentOperator::multAssign : getVariableIdentifier() + " *= " + expression.toCode()
-		case AssignmentOperator::divAssign : getVariableIdentifier() + " /= " + expression.toCode()
-		case AssignmentOperator::modAssign : getVariableIdentifier() + " %= " + expression.toCode()
-		case AssignmentOperator::addAssign : getVariableIdentifier() + " += " + expression.toCode()
-		case AssignmentOperator::subAssign : getVariableIdentifier() + " -= " + expression.toCode()
-		case AssignmentOperator::andAssign : getVariableIdentifier() + " &= " + expression.toCode()
-		case AssignmentOperator::xorAssign : getVariableIdentifier() + " ^= " + expression.toCode()
-		case AssignmentOperator::orAssign : getVariableIdentifier() + " != " + expression.toCode()
-		case AssignmentOperator::leftShiftAssign : getVariableIdentifier() + " <<= "+ expression.toCode()
-		case AssignmentOperator::rightShiftAssign : getVariableIdentifier() + " >>= " + expression.toCode()
+		case AssignmentOperator::assign : varRef.toCode() + " = " + expression.toCode()
+		case AssignmentOperator::multAssign : varRef.toCode() + " *= " + expression.toCode()
+		case AssignmentOperator::divAssign : varRef.toCode() + " /= " + expression.toCode()
+		case AssignmentOperator::modAssign : varRef.toCode() + " %= " + expression.toCode()
+		case AssignmentOperator::addAssign : varRef.toCode() + " += " + expression.toCode()
+		case AssignmentOperator::subAssign : varRef.toCode() + " -= " + expression.toCode()
+		case AssignmentOperator::andAssign : varRef.toCode() + " &= " + expression.toCode()
+		case AssignmentOperator::xorAssign : varRef.toCode() + " ^= " + expression.toCode()
+		case AssignmentOperator::orAssign : varRef.toCode() + " != " + expression.toCode()
+		case AssignmentOperator::leftShiftAssign : varRef.toCode() + " <<= "+ expression.toCode()
+		case AssignmentOperator::rightShiftAssign : varRef.toCode() + " >>= " + expression.toCode()
 		default : ""
 };
 		

+ 6 - 5
plugins/org.yakindu.sct.generator.java/src/org/yakindu/sct/generator/java/templates/Naming.ext

@@ -110,7 +110,7 @@ String getName(ExecutionState this):
 	getExecutionStateName().toFirstUpper();
 
 String getStateName(State state):
-	JAVA org.yakindu.sct.generator.java.extensions.JavaExtensions. getFullQualifiedStateName(org.yakindu.sct.model.sgraph.State);
+	JAVA org.yakindu.sct.generator.java.extensions.JavaExtensions.getFullQualifiedStateName(org.yakindu.sct.model.sgraph.State);
 
 String getName(State this) :
 	getStateName().toFirstUpper();
@@ -219,23 +219,24 @@ String statemachineEntryFunctionName(EnterState this):
 
 String actionFunctionName(Step this) : "actions" + getName(reaction().state()) + this.reaction().name.toFirstUpper(); 
 String checkFunctionName(Step this) : "condition" + getName(reaction().state()) + this.reaction().name.toFirstUpper(); 
+String enterSequenceName(Step this) : "enterSequence"+getName(state()); 
+String deepEnterSequenceName(Step this) : ((ExecutionRegion)this.eContainer).deepEnterSequenceName();
+String exitSequenceName(Step this) : "exitSequence"+getName(state()); 
+String reactSequenceName(Step this) : "react"+getName(state()); 
+
 String statechartEntryActionFunctionName(Step this) : "entryAction" + getName(parentStatechart());
 String statechartExitActionFunctionName(Step this) : "exitAction" + getName(parentStatechart());
 String entryActionFunctionName(Step this) : "entryAction" + getName(state()); 
 String exitActionFunctionName(Step this) : "exitAction" + getName(state());
-String enterSequenceName(Step this) : "enterSequence"+getName(state()); 
 String enterSequenceName(ExecutionState this) : "enterSequence"+getName();
 String enterSequenceName(ExecutionRegion this) : "enterSequence"+getName();
-String deepEnterSequenceName(Step this) : ((ExecutionRegion)this.eContainer).deepEnterSequenceName();
 String deepEnterSequenceName(ExecutionRegion this) : "deepEnterSequence"+getName();
 String shallowEnterSequenceName(Step this) : ((ExecutionRegion)this.eContainer).shallowEnterSequenceName();
 String shallowEnterSequenceName(ExecutionRegion this) : "shallowEnterSequence"+getName();
 String enterSequenceName(ExecutionFlow this) : "enter";
-String exitSequenceName(Step this) : "exitSequence"+getName(state()); 
 String exitSequenceName(ExecutionState this) : "exitSequence"+getName();
 String exitSequenceName(ExecutionRegion this) : "exitSequence"+getName();
 String exitSequenceName(ExecutionFlow this) : "exit";
-String reactSequenceName(Step this) : "react"+getName(state()); 
 
 isEffect(Step step) : (! Check.isInstance(step)) && Reaction.isInstance(step.eContainer) ;
 isReactionCheck(Step step) : Reaction.isInstance(step.eContainer) && Check.isInstance(step);