From ca046f3ce43eda9b5691fcfe4218a2569f8f771e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Sun, 27 Feb 2022 15:29:44 +0100 Subject: [PATCH 01/30] Initialize SCXML transformation projects --- .../.classpath | 7 +++ .../.gitignore | 1 + .../.project | 28 ++++++++++++ .../.settings/org.eclipse.jdt.core.prefs | 9 ++++ .../META-INF/MANIFEST.MF | 11 +++++ .../build.properties | 5 +++ .../icons/gamma-icon-16.png | Bin 0 -> 625 bytes .../plugin.xml | 42 ++++++++++++++++++ .../commandhandler/CommandHandler.java | 15 +++++++ .../.classpath | 8 ++++ .../.gitignore | 1 + .../.project | 34 ++++++++++++++ .../.settings/org.eclipse.jdt.core.prefs | 9 ++++ .../META-INF/MANIFEST.MF | 14 ++++++ .../build.properties | 5 +++ .../ScxmlToGammaTransformer.xtend | 5 +++ .../scxml/transformation/Traceability.xtend | 5 +++ .../.ScxmlToGammaTransformer.java._trace | Bin 0 -> 113 bytes .../.ScxmlToGammaTransformer.xtendbin | Bin 0 -> 1511 bytes .../transformation/.Traceability.java._trace | Bin 0 -> 101 bytes .../transformation/.Traceability.xtendbin | Bin 0 -> 1494 bytes .../ScxmlToGammaTransformer.java | 5 +++ .../scxml/transformation/Traceability.java | 5 +++ 23 files changed, 209 insertions(+) create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.classpath create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.gitignore create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.project create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/build.properties create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/icons/gamma-icon-16.png create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.classpath create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.gitignore create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.project create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.settings/org.eclipse.jdt.core.prefs create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/build.properties create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.java._trace create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.xtendbin create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.java._trace create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.xtendbin create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.java create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.classpath b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.classpath new file mode 100644 index 000000000..e801ebfb4 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.gitignore b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.project b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.project new file mode 100644 index 000000000..7f5a510b2 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.project @@ -0,0 +1,28 @@ + + + hu.bme.mit.gamma.scxml.transformation.commandhandler + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.settings/org.eclipse.jdt.core.prefs b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..c9545f06a --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF new file mode 100644 index 000000000..97eb5a6cd --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: SCXML To Gamma Transformer Commandhandler +Bundle-SymbolicName: hu.bme.mit.gamma.scxml.transformation.commandhandler;singleton:=true +Bundle-Version: 1.0.0.qualifier +Automatic-Module-Name: hu.bme.mit.gamma.scxml.transformation.commandhandler +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.core.commands, + ac.soton.scxml, + hu.bme.mit.gamma.scxml.transformation +Export-Package: hu.bme.mit.gamma.scxml.transformation.commandhandler diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/build.properties b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/build.properties new file mode 100644 index 000000000..e9863e281 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/icons/gamma-icon-16.png b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/icons/gamma-icon-16.png new file mode 100644 index 0000000000000000000000000000000000000000..a880d2b842f441e5cace4ecb68cfde368d3eb4ac GIT binary patch literal 625 zcmV-%0*?KOP)BBU|_#T-VgER2|VcSd3g z5g{0`5E~IIL5TSP0YMS8NFhW~%&~ti?Cx0HA9Be>ec***-e;bfXLw(8H87?FZp09FLSNt2Ye`Z-JOl%+NedEU{1QMsc!O=)`(o z&uU#wtNNy!tLb5_tNHW(OMs!rLk?HL?f8r;QPv?Fwk8M&2fH1F1#*6DZ){%z*m}E_ zvjPr4REgjUt(H*NBQOWR=ft#xZbdxRHt9PAVr`gu3WUl zUd1=!=fms6lx~*xaQjYRm@f#VJdG;R9Khz%CfQ=PhubrO)>|)592vzR`I5{4lqbu5 zi+cnH>w|<-p|w3cA!jvP%o+gAfhPN*D_~~Qo?;5)n3=71@8)b@0qL<&(@})40C||7 zj%VU``~%Le?HvcO)Lz8P@q2)=i81~Q!NZ^vcK?Kb$H$p={#y43u{FFw + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java new file mode 100644 index 000000000..b82fbdc95 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -0,0 +1,15 @@ +package hu.bme.mit.gamma.scxml.transformation.commandhandler; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; + +public class CommandHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.classpath b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.classpath new file mode 100644 index 000000000..47ce7cd07 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.gitignore b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.project b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.project new file mode 100644 index 000000000..60a849793 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.project @@ -0,0 +1,34 @@ + + + hu.bme.mit.gamma.scxml.transformation + + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.xtext.ui.shared.xtextNature + + diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.settings/org.eclipse.jdt.core.prefs b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..c9545f06a --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF new file mode 100644 index 000000000..9e3592bc6 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: SCXML To Gamma Transformation +Bundle-SymbolicName: hu.bme.mit.gamma.scxml.transformation;singleton:=true +Bundle-Version: 1.0.0.qualifier +Automatic-Module-Name: hu.bme.mit.gamma.scxml.transformation +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: ac.soton.scxml, + hu.bme.mit.gamma.statechart.model, + com.google.guava, + org.eclipse.xtext.xbase.lib, + org.eclipse.xtend.lib, + org.eclipse.xtend.lib.macro +Export-Package: hu.bme.mit.gamma.scxml.transformation diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/build.properties b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/build.properties new file mode 100644 index 000000000..d8e2f0e92 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/build.properties @@ -0,0 +1,5 @@ +source.. = src/,\ + xtend-gen/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.xtend new file mode 100644 index 000000000..c66871b60 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.xtend @@ -0,0 +1,5 @@ +package hu.bme.mit.gamma.scxml.transformation + +class ScxmlToGammaTransformer { + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend new file mode 100644 index 000000000..15a9de0cb --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -0,0 +1,5 @@ +package hu.bme.mit.gamma.scxml.transformation + +class Traceability { + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.java._trace b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.java._trace new file mode 100644 index 0000000000000000000000000000000000000000..7cbe5193e2d9e5252df50c4a104e53ba5a529651 GIT binary patch literal 113 zcmZQzU|?lrbf{otV_-5;V`gP!aLy>zPs&Zz&&@2+PfyIvP1G+=uE@>NFDXjQD^ANV z%1tcE%+J#g1__4byMt7Oz@$=(^eReH^HP|M9bA}MAto{~IYddYurM%LNH8-qFaiMM C10Bo& literal 0 HcmV?d00001 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.xtendbin b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.xtendbin new file mode 100644 index 0000000000000000000000000000000000000000..03b9bc81892eff86d9e7b41c77985ec6872d1311 GIT binary patch literal 1511 zcmWIWW@Zs#;Nak3I8+)P!hi&Lfb7)VG~ML>9h3{XnzS)NVagV{h{vz8BoEZ=mRA+k)4Tk5ZivHaJ@cI#A8;OA@@B%s zNB1r(nlIzDIdN>xtVn0W+M1ne^2aybDV12BglMJ&(97P)L-@PX(%Gt4CYU>i=Ii4rx=3J6E7~^BW@oYm`S>Cs@!|%>neAct} zRP0L7yv5OEcI{h|rr644F!U)I{|*T?j)>Roxc9c^Y7Es@6ToY zu&j=W-&fJ#>b96??N2Mr5D{pc{`?^TwE zhvZ{yN(;WFvzxb`Hfw!(uIA^5kALe=$V^&ECnYySqRCwU`(Gs`~yOuGMef9cJc8 z3w$iDSmNZqMRd`kEcKGll79rh>le>Z`!dDajQzhXC}rrkn8)4#ri@;^DFc-86N`)U zlQR=R38Faq^R&jTJ31U~v^VMmuHT|!?0#O|Sl`<8sPaaO!{!?gJZXsUaX8m_--o9s zkmpY4$&)LO9{uO4xzbhCm8XfrHsI=-H{1E-#JqQ$ICJ31u>(^l&!6#V+KiY<@lQ@3 zh@2ESC2G#Z`ICbJ6W$+SV0$X#;KXobRf2|I%8KNKhEpF7q)K>8uzcbDBCF*U^f|~$ zi#w?MD^I~rGmEWH+|GSnv9f&YlNk+eNjvy8_Mcu_`f7{pZQmJ;45yKNeXArY)=m`~WCu7~B8= literal 0 HcmV?d00001 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.xtendbin b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.xtendbin new file mode 100644 index 0000000000000000000000000000000000000000..8c512c5853282b694e1ce6c6d82f7c22cc70ed47 GIT binary patch literal 1494 zcmWIWW@Zs#;Nak3I9(bY!hi&Lfb7)VG~ML9yU`-4^`s!=I=>W>Z=37f+cGn0N5Oy_M{p2H{ahSGS}Ivwvd0^5fGY z(cSkU*jy%LFLwQsaCp(jXS@84#pRdp>zkU>lbKV>;%)KUqGI3Y<}SbfY0qq< zzIc@h+`fB8GUD8g#Yg1tIK&q;%B^(?%PUbnCjV#YD=xu*uZ&D@t+zX`A9yUF)O_K= zYmb(co=fJqe;_*b^@kE`SC09QZe^;5+A!Z$JDohu*6*(0BL61e^YflQeyVWF;kAgO z>XfvnL9C{45^Mf^J==abGL9{E&N2V(-?s#}U0W!>Y37DMm02Zo%(4xZHPj{Te>Dd*GzKH_To)+}Y1ta?QigFyq+^X6+j*ZXec3m8;cGe*FH?uGydNy_^63>c;;+ zk4|d6AK=Z-(Uz~MK97-s!Ht=LApmE*iU8xaD784hv?w`MHzl<=xhS)sBr`wn=tRS8 z5l4~Z_wU}5oGKu2&`;-5rN*r~J7u^K5 zY}_V(&`l@kxZ4NoAB=Bmc4yh>ZY}6C@1Oa<`t$$2m48`x9Xx#EmuB##3~`a}6-q|y zn{@YvoY9moaR?2l3$N7eu@hJsc-x-EJY+(g^_6WEpPXu|staG9RdOh~%B(S0&|;%q z{8RheAJ?R0u8UYV(bshzw^+&2eYP-vdil$FQ&;frez$kV-DQeL+~v>P+l%N6 zXXHAlzhD-X?JZdN>WbjPxl=hfZ!YsVCb+A&^p^Bz4)6W9-6Q6(cYJv>GyeQNA;sH5 z>vn(m`M16Jd%sXd|AQ?XlWc^9*4}Rjo^dh3IQ!Ve*y!e}t*a)B+%9#KYnrDNFH6jxRkii7oK1_ATIK|y7QeUcX3AWzN)MUM zm+LS6-_-Z{#YbsSdT?Htc(!@0)$K0G~vJa;-zo?LnK=s#D@m9C<$JWU+7 z0aw?&+0G{?=Dp*@nFCLb9hf?K{)|V{X2eX2e{%9bpdx;N$p(Ek;{Pzvy7WD;ROl!eH-2^2=C y0J&sD*NGhNpxlN4H-PqF%X{c1AiE3I?iawgM2@WhZ&o&t`OHAL4M=mbf_MNm!FV?S literal 0 HcmV?d00001 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.java new file mode 100644 index 000000000..c6be908dd --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.java @@ -0,0 +1,5 @@ +package hu.bme.mit.gamma.scxml.transformation; + +@SuppressWarnings("all") +public class ScxmlToGammaTransformer { +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java new file mode 100644 index 000000000..f4286455c --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java @@ -0,0 +1,5 @@ +package hu.bme.mit.gamma.scxml.transformation; + +@SuppressWarnings("all") +public class Traceability { +} From 4bb91c14660bcea639142edce8672c63a1ce4f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Sun, 27 Feb 2022 20:29:52 +0100 Subject: [PATCH 02/30] Add root element transformation and handler --- .../Launch Runtime Eclipse with Scxml.launch | 36 +++++++++ .../META-INF/MANIFEST.MF | 13 +++- .../plugin.xml | 4 +- .../commandhandler/CommandHandler.java | 70 +++++++++++++++++- .../transformation/AbstractTransformer.xtend | 25 +++++++ .../gamma/scxml/transformation/Namings.xtend | 11 +++ .../ScxmlToGammaStatechartTransformer.xtend | 41 ++++++++++ .../ScxmlToGammaTransformer.xtend | 5 -- .../scxml/transformation/Traceability.xtend | 44 +++++++++++ .../xtend-gen/.gitignore | 4 + .../.ScxmlToGammaTransformer.xtendbin | Bin 1511 -> 0 bytes .../transformation/.Traceability.java._trace | Bin 101 -> 1959 bytes .../transformation/.Traceability.xtendbin | Bin 1494 -> 4058 bytes .../ScxmlToGammaStatechartTransformer.java | 34 +++++++++ .../ScxmlToGammaTransformer.java | 5 -- .../scxml/transformation/Traceability.java | 45 +++++++++++ 16 files changed, 321 insertions(+), 16 deletions(-) create mode 100644 plugins/core/hu.bme.mit.gamma.property.language/.launch/Launch Runtime Eclipse with Scxml.launch create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/.gitignore delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.xtendbin create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.java delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.java diff --git a/plugins/core/hu.bme.mit.gamma.property.language/.launch/Launch Runtime Eclipse with Scxml.launch b/plugins/core/hu.bme.mit.gamma.property.language/.launch/Launch Runtime Eclipse with Scxml.launch new file mode 100644 index 000000000..e1bec6db0 --- /dev/null +++ b/plugins/core/hu.bme.mit.gamma.property.language/.launch/Launch Runtime Eclipse with Scxml.launch @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF index 97eb5a6cd..41bb72596 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF @@ -7,5 +7,14 @@ Automatic-Module-Name: hu.bme.mit.gamma.scxml.transformation.commandhandler Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.eclipse.core.commands, ac.soton.scxml, - hu.bme.mit.gamma.scxml.transformation -Export-Package: hu.bme.mit.gamma.scxml.transformation.commandhandler + hu.bme.mit.gamma.scxml.transformation, + org.eclipse.core.resources, + org.eclipse.emf.common, + org.eclipse.emf.ecore, + org.eclipse.jface, + org.eclipse.ui.workbench, + org.eclipse.m2e.maven.runtime, + hu.bme.mit.gamma.statechart.model, + hu.bme.mit.gamma.statechart.language.ui, + org.eclipse.equinox.registry +Export-Package: hu.bme.mit.gamma.scxml.transformation.commandhandler;uses:="org.eclipse.core.commands,hu.bme.mit.gamma.util,hu.bme.mit.gamma.statechart.util" diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml index ffc29ca11..ac52a69d3 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml @@ -13,7 +13,7 @@ label="Generate Gamma Statechart" style="push"> - + @@ -27,7 +27,7 @@ label="Generate Gamma Statechart" style="push"> - + diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index b82fbdc95..0d44da0ee 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -1,15 +1,81 @@ package hu.bme.mit.gamma.scxml.transformation.commandhandler; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +import ac.soton.scxml.DocumentRoot; +import ac.soton.scxml.ScxmlScxmlType; +import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaStatechartTransformer; +import hu.bme.mit.gamma.scxml.transformation.Traceability; +import hu.bme.mit.gamma.statechart.interface_.Package; +import hu.bme.mit.gamma.statechart.language.ui.serializer.StatechartLanguageSerializer; +import hu.bme.mit.gamma.statechart.statechart.StatechartDefinition; +import hu.bme.mit.gamma.statechart.util.StatechartUtil; +import hu.bme.mit.gamma.util.FileUtil; +import hu.bme.mit.gamma.util.GammaEcoreUtil; public class CommandHandler extends AbstractHandler { + + protected final FileUtil fileUtil= FileUtil.INSTANCE; + protected final GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE; + protected final StatechartUtil statechartUtil = StatechartUtil.INSTANCE; + protected final Logger logger = Logger.getLogger("GammaLogger"); @Override public Object execute(ExecutionEvent event) throws ExecutionException { - // TODO Auto-generated method stub + try { + ISelection sel = HandlerUtil.getActiveMenuSelection(event); + if (sel instanceof IStructuredSelection) { + IStructuredSelection selection = (IStructuredSelection) sel; + Object firstElement = selection.getFirstElement(); + if (selection.size() == 1) { + if (firstElement != null && firstElement instanceof IFile) { + IFile file = (IFile) firstElement; + IContainer parentFolder = file.getParent(); + String fileName = file.getName(); + String extensionlessFileName = fileUtil.getExtensionlessName(fileName); + String parentPath = parentFolder.getFullPath().toString(); + String path = file.getFullPath().toString(); + URI fileURI = URI.createPlatformResourceURI(path, true); + + // Retrieve SCXML document root to transform + EObject object = ecoreUtil.normalLoad(fileURI); + ScxmlScxmlType scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(object, ScxmlScxmlType.class); + + // Model processing + ScxmlToGammaStatechartTransformer statechartTransformer = new ScxmlToGammaStatechartTransformer(scxmlRoot); + Traceability traceability = statechartTransformer.execute(); + StatechartDefinition statechartDefinition = traceability.getStatechartDefinition(scxmlRoot); + Package gammaComponentPackage = statechartUtil.wrapIntoPackage(statechartDefinition); + + StatechartLanguageSerializer packageSerializer = new StatechartLanguageSerializer(); + logger.log(Level.INFO, "Start serializing Gamma package..."); + String componentPackageFileName = extensionlessFileName + "Transformed.gcd"; + packageSerializer.serialize(gammaComponentPackage, parentPath, componentPackageFileName); + logger.log(Level.INFO, "The SCXML - Gamma statechart transformation has finished."); + + } + } + } + } + catch (IOException e) { + e.printStackTrace(); + } return null; } - + } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend new file mode 100644 index 000000000..6a53897c0 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend @@ -0,0 +1,25 @@ +package hu.bme.mit.gamma.scxml.transformation + +import hu.bme.mit.gamma.statechart.interface_.InterfaceModelFactory +import hu.bme.mit.gamma.statechart.statechart.StatechartModelFactory +import hu.bme.mit.gamma.statechart.util.StatechartUtil +import hu.bme.mit.gamma.util.GammaEcoreUtil +import java.util.logging.Logger + +abstract class AbstractTransformer { + + protected final Traceability traceability + + protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE + protected final extension StatechartUtil statechartUtil = StatechartUtil.INSTANCE + + protected final extension InterfaceModelFactory interfaceModelFactory = InterfaceModelFactory.eINSTANCE + protected final extension StatechartModelFactory statechartModelFactory = StatechartModelFactory.eINSTANCE + + protected final Logger logger = Logger.getLogger("GammaLogger") + + new(Traceability traceability) { + this.traceability = traceability + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend new file mode 100644 index 000000000..84a491fd1 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -0,0 +1,11 @@ +package hu.bme.mit.gamma.scxml.transformation + +import ac.soton.scxml.ScxmlScxmlType +import ac.soton.scxml.ScxmlStateType + +class Namings { + + def static String getStatechartDefinitionName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' + def static String getStateName(ScxmlStateType state) '''«state.id»''' + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend new file mode 100644 index 000000000..8b05a35c4 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -0,0 +1,41 @@ +package hu.bme.mit.gamma.scxml.transformation + +import ac.soton.scxml.ScxmlScxmlType + +import static extension hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures.* +import static extension ac.soton.scxml.ScxmlModelDerivedFeatures.* +import static extension hu.bme.mit.gamma.scxml.transformation.Namings.* +import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition + +class ScxmlToGammaStatechartTransformer extends AbstractTransformer { + + // Root element of the SCXML statechart model to transform + protected final ScxmlScxmlType scxmlRoot + + // Root element of the Gamma statechart definition as the transformation result + protected final SynchronousStatechartDefinition gammaStatechart + + new(ScxmlScxmlType scxmlRoot) { + this(scxmlRoot, + new Traceability(scxmlRoot) + ) + } + + new(ScxmlScxmlType scxmlRoot, Traceability traceability) { + super(traceability) + + this.scxmlRoot = scxmlRoot + this.gammaStatechart = createSynchronousStatechartDefinition => [ + it.name = scxmlRoot.name + ] + } + + def execute() { + traceability.put(scxmlRoot, gammaStatechart) + + // + + return traceability + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.xtend deleted file mode 100644 index c66871b60..000000000 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.xtend +++ /dev/null @@ -1,5 +0,0 @@ -package hu.bme.mit.gamma.scxml.transformation - -class ScxmlToGammaTransformer { - -} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index 15a9de0cb..f70d75a97 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -1,5 +1,49 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.ScxmlScxmlType +import ac.soton.scxml.ScxmlStateType + +import hu.bme.mit.gamma.statechart.statechart.State +import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition + +import hu.bme.mit.gamma.util.GammaEcoreUtil +import java.util.Map + +import static com.google.common.base.Preconditions.checkNotNull + class Traceability { + // Root element of the SCXML statechart model to transform. + // This Traceability class will be able to store multiple + // ScxmlScxmlType - SynchronousStatechartDefinition pairs, but for now, + // we assume only one SCMXL statechart to be transformed (from an root element). + protected final ScxmlScxmlType scxmlRoot + + protected final Map statechartDefinitions = newHashMap + protected final Map states = newHashMap + + protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE + + + new(ScxmlScxmlType scxmlRoot) { + this.scxmlRoot = scxmlRoot + } + + def getScxmlRoot() { + return scxmlRoot + } + + def put(ScxmlScxmlType scxmlRoot, SynchronousStatechartDefinition gammaStatechart) { + checkNotNull(scxmlRoot) + checkNotNull(gammaStatechart) + statechartDefinitions += scxmlRoot -> gammaStatechart + } + + def getStatechartDefinition(ScxmlScxmlType scxmlRoot) { + checkNotNull(scxmlRoot) + val gammaStatechart = statechartDefinitions.get(scxmlRoot) + checkNotNull(gammaStatechart) + return gammaStatechart + } + } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/.gitignore b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/.gitignore new file mode 100644 index 000000000..86d0cb272 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.xtendbin b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.ScxmlToGammaTransformer.xtendbin deleted file mode 100644 index 03b9bc81892eff86d9e7b41c77985ec6872d1311..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1511 zcmWIWW@Zs#;Nak3I8+)P!hi&Lfb7)VG~ML>9h3{XnzS)NVagV{h{vz8BoEZ=mRA+k)4Tk5ZivHaJ@cI#A8;OA@@B%s zNB1r(nlIzDIdN>xtVn0W+M1ne^2aybDV12BglMJ&(97P)L-@PX(%Gt4CYU>i=Ii4rx=3J6E7~^BW@oYm`S>Cs@!|%>neAct} zRP0L7yv5OEcI{h|rr644F!U)I{|*T?j)>Roxc9c^Y7Es@6ToY zu&j=W-&fJ#>b96??N2Mr5D{pc{`?^TwE zhvZ{yN(;WFvzxb`Hfw!(uIA^5kALe=$V^&ECnYySqRCwU`(Gs`~yOuGMef9cJc8 z3w$iDSmNZqMRd`kEcKGll79rh>le>Z`!dDajQzhXC}rrkn8)4#ri@;^DFc-86N`)U zlQR=R38Faq^R&jTJ31U~v^VMmuHT|!?0#O|Sl`<8sPaaO!{!?gJZXsUaX8m_--o9s zkmpY4$&)LO9{uO4xzbhCm8XfrHsI=-H{1E-#JqQ$ICJ31u>(^l&!6#V+KiY<@lQ@3 zh@2ESC2G#Z`ICbJ6W$+SV0$X#;KXobRf2|I%8KNKhEpF7q)K>8uzcbDBCF*U^f|~$ zi#w?MD^I~rGmEWH+|GSnv9f&YlNk+eNjvy8_Mcu_`f7{pZQmJq4;C7v`cTwuj5d%> zFxk?JiVqc(G*~bdBz+MrR1mb(H>o}Zu`1pWsVN95s8xLOp{0c&e&;)}nV~){zx{u= zGm4_<0MR8FQ&{y?zS6o2lzR^!sT``$RO+*h$}_cky;fP8K31QrG!|>~OHVH>)@zN~ zh55=Oi?!*Q+M(IG*~amaV~v^lrx)+ZKK|)Ms~Zx zw&-3SY;RXo_kblr_Xi8b5(0O|pzL=8GjNYO@3*yK&2{H+Dy3-d%ew_VeYcb*rJ=w* zWs#aK6iW!)vjxhs1qL2 zFDT@n&b?2e}ejGzn zwO~Cbm7<~Ry6EtAAqXyupDnS3Aozv$%41kU5L{1WaY5MKHaK|ugG0EtdSZAN?%>Y1 zrHZ15eqng{HX)qJ5Ti_~q(JyWH|fbNN)1n1QWlCO1mSB2WeW!NovT{qQJi|hS;HkP zOj-}mO_a;{MPAGd4Pkn5pj^gck{Yg?QYK~)eq)eU462L^!k?Y#kr5oT_JG)pCzCGp zq0}golS)bHBO|!tf)GSqsco@@AR4nM`&7JDjm9)7jrt}G(iimBC@zR1XJ4g)$86-q w!O?-q3O-y)jgFd9;%N}QWRrfgsWL8z&SpkOamuZ<*c82GkK$(x6#EXrzii}F_W%F@ delta 49 zcmZ3^pDMt>z`)AL=#b0E#=vAG&CEJc$VSrGl9?64V_lBV6xz4W@can0G2KV A00000 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.xtendbin b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.xtendbin index 8c512c5853282b694e1ce6c6d82f7c22cc70ed47..d9978a5633293b919558f55221a4878e7eca5fd9 100644 GIT binary patch literal 4058 zcmaJ^XE+?()*Zb^jNW_C=#hjVh;A@L5E*?8qD3cqFOiW~mk>l9T{2q8=tOU$ixNbM zFoMzJOMczl`+WDV^W&WTf~~~X^j3w+q`*hBs5yWvJ+SK*WW|; zN2a9;OKSGdD7G;{A(*~ptlQSci|3@G1L>wL4W(djfB%{M4Esjb+n4#ydokDwZo@}l zjhcf@#|HJO#2*b;Jg`Djr;E4c1{|P|%&&u?KN&w+yy%{HDt+n>ssUz-2>hX z?WWXzWav8w+?;z4FFy7)DlS;)v#1ZAIacyc*nKse2@B6P4-aZVuSpmslQ#4u%gnDU z<{Q4LX;_N59ummtxEwp7M*L_-*7fFn?P#vy(i?`S=?hhq&v8Iy=2VYj1&Xx3|A53S z-QNO*FD*wMdepr=l}r?!>lH@wzCeU+J-MlG?dv}F>)~CDV?E*W zp`t5DA-9lb;X@$NO3bxZGOnH&b0eaLgrsfLQlo+6`BgNH*WsShq`v>>V^c>qSPm(3 zY0Qhs+%dlr=F{)38)QC2%8aY3toO^p$$AF2;RljYdaRN{MCqQL??Z-wvLKu*#S zq!S}QJF`B*raVY3S7%Z0>OQH)2_@u!;?&2&G zJ(yU^P=)Og*}-1azcqcY9(fL}jgkTTUw!;itID+fqdjhi$ZkC!-~CUlkM!*d4EMJW z9BCsw$6^egBphDOr z{jdg=gl`c-|H1mxE%{^*CY~CLQ1O0s1(vEyIuqH7hh>m{BZi63yoCV$2rUGWg-mQe z*JRWjK6h8hr`PvWD}nu)%3hdI)yEpS+{I@=jybjL&Z*enYjfb&;k&U~{(1D%k;>e8 zTY?vq0v9`wekS7wkAJbjnL~)PhbXd>SF2tPYzx1BXSIiFy&>kIoo>;loBJ~svGT~E z^pofCGI5MLwCR~%)E9x4AGHjjiDUQW*xJ%z#gykPMkvqKr)RW+3ui@ciZ z(NPCI>gi_nOk;Y~pp1y1w3nuwP~x+A@+%G$IR3kQsoA;_@VagVsd8Y*zIruRy9^7)&xGeE9DV&@-7FdB zM~UH58waKXhHtL?Dol6)o-J#_dZAB>?JM**yc;G)CXhQ)GR)BTNhR) zO2;QHa&u&V3z7|S;gPUa+V)N&UXg#B&=KAe?+A%l2GSq;q_FK2`+4k3F`7XR7_?|r zo+Z$O1h9<_XkCFWm*mZ_(%a{9$zyHz2v%yRjqgG!MW`#Xh%fauHlIFPcJuGVD3xVw zT_9|8*09C)NYBhvc_|{KormO58_DOL#Zgip= z9ZQilhGQCyi!ss+llnY`)wa^?n_0ye-JOg-InduPFaD}v)+%5e+z>Z1&KM{AqPn0{ zxeVeN)rNTmjGV^WIFEGNQR4YKoVr$-?kb%-J-Zuu0gk>+eTNKjJJ@!Cb}8j~$o=E6 zj&)C6(|AtYCG|ZtFVV@)Y%B}6AA1eQ?6B#>z|swqRvPJ-N?iAa`cuhW_5>C^;S$b` z1iqIC+5M0AWc`3sUGA_f^*&Nt!~W9PdBXxd_A;{ZjSw%4FVZ~c&dSRH=u0-WLWHNV zdm87jkFTB5EQH>9B={wFBc@Ynq^3{OcZ&mnm>@t;m8uXNtgj&_3yPSDM58KX>muH7B zdkrhdV>(u3v9z#Tib+BKmDh`pKVh7Mx{u1_T4oPxMRUfy!ToiTSd&VQ$B~Lslabj> zL+B%Yy-_q!mfLIhrmJ!0Kmp|!5B}&3z~m=j)?SE>iV!j<{AkE#Ir!{YMJ0*nityWY zxX3N81`%KN03K~F4s)%U);HOSCRIOct5w&kl#NYMAl@_y}Q3qC581s zjntfImlI)pi3HG5f5cq# zk!FMlsqBYej>gk+Xhr+bZ|q`Q=vGN*+V*f?MqlG%1itlqEmYQ`6lLa&oJ_$ZG|wkj z7zCi8_O#7_7Twkx*dTQFYKLQrUo0?poHkAWw9JV+y-az*C{M_w6y+i-_T2lU1nO0x zHWv3z#$}*V+*>Dm5NN4eSSixpGfW{d;>T#VS7p_fO*F>g54ksmGs`&qK$|Mg2Mz!O%<*w^C z`#y9_pN*r3s_xrU6;ZUq=4(c$U*A0%zc7wT(gwd)C{(!pyNQ-75*!0z|2 zIsZdHF&4!DHX!vBOnxVPXE1#n(J!j5cm@}7Tg~EPbaDYOr0R~Y(Hn;)la6KO4ivPA zmAxr8P0 zZZzHeiI0LTuQeHY`GRys&yTPQ!ko-y`4e1h zHe3w`$WIUy5jy8$EGDo^3azRhi|l5B=2^}!x(g4;Y(jbko%r%+5`}~4@U8|T%e(AP zh7zl?!4M3(&FX8uj%)3Y&81Anb+w%Q#glk?I#))0o!0gF(|1|w$6{$6qGCe7*iF>z z?s%;$tesyGHpD1&Ih^OpHUHG4O99uIjAG7&%;pq)xiqBZj*J>#?ZnCG2XD(UoM^H} zykKp(*HKGy``|u)HHB7rUf7^Ag|nxe_NrUQgSGS%0rb{GmS0qVl+n_SS$UQi001)m zFJ=7GK-hYFd)PbM{t-m);*3G}$p;LvrQ4urBN8!4x|cX1BVW9|qNf;fc})2Oh$K0o zHX~Im{2{f0-7dv#cE9^-fs}Y2Q;qus;x~cG?ew)B$`50jl!b33q>11+uVKGr?JvF< z%5OKj?y-jTQ&~FC#rRfS!Q|XMYnnT9Cziey=6pI4@9Axrv$d+B8eQ;W?>x5jJE|%1 zKVCmNG0aO=`6V*~eUwqB*b3S3o%5WT<(>11nc1DCS$-`2__TkoC~6so%gxwLftu)B zC;AoQ2k5ML?>K@jAwvf^i^?e`FJT~K7oU(be`(y5Y|16G4XOK`dQ z_MN{+l(RZKkk{a4w2lAvL8kEa@07N=oW?_qL64JmsRXT!ffe!Acf zQ|OuPsHevzS9tg>hXz=)(KdZZrODKk+{l89Y8(qbX@4T3_Rj~1rL}kuPd6W(nzTcJ zg#4JRb-s$(1S85bqSKh(hxO@K8SIq|B~h2Ckbj=vlXoCU%}8(eUMfwl$aG{!0%?*( zS5oe~ms3FY3PEYp3l;k{xVo^eooh~#ylGz&c(QjV;pJ4SYYxypW!`fw3M)=2W8~TD{{7fZKwdYF zqMe>anIwR&%Mp;*hr8FV$ASR_PIMfi+VFg;Eo)`MuN6Gytj5xWnlwmp?tiDSWVyS`ff zL*_!QWMC>G0I)^#hs*?o41j<2!+%?VKXm?g{M{Y@=gz-V9yU`-4^`s!=I=>W>Z=37f+cGn0N5Oy_M{p2H{ahSGS}Ivwvd0^5fGY z(cSkU*jy%LFLwQsaCp(jXS@84#pRdp>zkU>lbKV>;%)KUqGI3Y<}SbfY0qq< zzIc@h+`fB8GUD8g#Yg1tIK&q;%B^(?%PUbnCjV#YD=xu*uZ&D@t+zX`A9yUF)O_K= zYmb(co=fJqe;_*b^@kE`SC09QZe^;5+A!Z$JDohu*6*(0BL61e^YflQeyVWF;kAgO z>XfvnL9C{45^Mf^J==abGL9{E&N2V(-?s#}U0W!>Y37DMm02Zo%(4xZHPj{Te>Dd*GzKH_To)+}Y1ta?QigFyq+^X6+j*ZXec3m8;cGe*FH?uGydNy_^63>c;;+ zk4|d6AK=Z-(Uz~MK97-s!Ht=LApmE*iU8xaD784hv?w`MHzl<=xhS)sBr`wn=tRS8 z5l4~Z_wU}5oGKu2&`;-5rN*r~J7u^K5 zY}_V(&`l@kxZ4NoAB=Bmc4yh>ZY}6C@1Oa<`t$$2m48`x9Xx#EmuB##3~`a}6-q|y zn{@YvoY9moaR?2l3$N7eu@hJsc-x-EJY+(g^_6WEpPXu|staG9RdOh~%B(S0&|;%q z{8RheAJ?R0u8UYV(bshzw^+&2eYP-vdil$FQ&;frez$kV-DQeL+~v>P+l%N6 zXXHAlzhD-X?JZdN>WbjPxl=hfZ!YsVCb+A&^p^Bz4)6W9-6Q6(cYJv>GyeQNA;sH5 z>vn(m`M16Jd%sXd|AQ?XlWc^9*4}Rjo^dh3IQ!Ve*y!e}t*a)B+%9#KYnrDNFH6jxRkii7oK1_ATIK|y7QeUcX3AWzN)MUM zm+LS6-_-Z{#YbsSdT?Htc(!@0)$K0G~vJa;-zo?LnK=s#D@m9C<$JWU+7 z0aw?&+0G{?=Dp*@nFCLb9hf?K{)|V{X2eX2e{%9bpdx;N$p(Ek;{Pzvy7WD;ROl!eH-2^2=C y0J&sD*NGhNpxlN4H-PqF%X{c1AiE3I?iawgM2@WhZ&o&t`OHAL4M=mbf_MNm!FV?S diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.java new file mode 100644 index 000000000..a71509d56 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.java @@ -0,0 +1,34 @@ +package hu.bme.mit.gamma.scxml.transformation; + +import ac.soton.scxml.ScxmlScxmlType; +import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition; +import org.eclipse.xtext.xbase.lib.ObjectExtensions; +import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; + +@SuppressWarnings("all") +public class ScxmlToGammaStatechartTransformer extends AbstractTransformer { + protected final ScxmlScxmlType scxmlRoot; + + protected final SynchronousStatechartDefinition gammaStatechart; + + public ScxmlToGammaStatechartTransformer(final ScxmlScxmlType scxmlRoot) { + this(scxmlRoot, + new Traceability(scxmlRoot)); + } + + public ScxmlToGammaStatechartTransformer(final ScxmlScxmlType scxmlRoot, final Traceability traceability) { + super(traceability); + this.scxmlRoot = scxmlRoot; + SynchronousStatechartDefinition _createSynchronousStatechartDefinition = this.statechartModelFactory.createSynchronousStatechartDefinition(); + final Procedure1 _function = (SynchronousStatechartDefinition it) -> { + it.setName(scxmlRoot.getName()); + }; + SynchronousStatechartDefinition _doubleArrow = ObjectExtensions.operator_doubleArrow(_createSynchronousStatechartDefinition, _function); + this.gammaStatechart = _doubleArrow; + } + + public Traceability execute() { + this.traceability.put(this.scxmlRoot, this.gammaStatechart); + return this.traceability; + } +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.java deleted file mode 100644 index c6be908dd..000000000 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaTransformer.java +++ /dev/null @@ -1,5 +0,0 @@ -package hu.bme.mit.gamma.scxml.transformation; - -@SuppressWarnings("all") -public class ScxmlToGammaTransformer { -} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java index f4286455c..964aef81d 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java @@ -1,5 +1,50 @@ package hu.bme.mit.gamma.scxml.transformation; +import ac.soton.scxml.ScxmlScxmlType; +import ac.soton.scxml.ScxmlStateType; +import com.google.common.base.Preconditions; +import hu.bme.mit.gamma.statechart.statechart.State; +import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition; +import hu.bme.mit.gamma.util.GammaEcoreUtil; +import java.util.Map; +import org.eclipse.xtext.xbase.lib.CollectionLiterals; +import org.eclipse.xtext.xbase.lib.Extension; +import org.eclipse.xtext.xbase.lib.Pair; + @SuppressWarnings("all") public class Traceability { + protected final ScxmlScxmlType scxmlRoot; + + protected final Map statechartDefinitions = CollectionLiterals.newHashMap(); + + protected final Map states = CollectionLiterals.newHashMap(); + + @Extension + protected final GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE; + + public Traceability(final ScxmlScxmlType scxmlRoot) { + this.scxmlRoot = scxmlRoot; + } + + public ScxmlScxmlType getScxmlRoot() { + return this.scxmlRoot; + } + + public SynchronousStatechartDefinition put(final ScxmlScxmlType scxmlRoot, final SynchronousStatechartDefinition gammaStatechart) { + SynchronousStatechartDefinition _xblockexpression = null; + { + Preconditions.checkNotNull(scxmlRoot); + Preconditions.checkNotNull(gammaStatechart); + Pair _mappedTo = Pair.of(scxmlRoot, gammaStatechart); + _xblockexpression = this.statechartDefinitions.put(_mappedTo.getKey(), _mappedTo.getValue()); + } + return _xblockexpression; + } + + public SynchronousStatechartDefinition getStatechartDefinition(final ScxmlScxmlType scxmlRoot) { + Preconditions.checkNotNull(scxmlRoot); + final SynchronousStatechartDefinition gammaStatechart = this.statechartDefinitions.get(scxmlRoot); + Preconditions.checkNotNull(gammaStatechart); + return gammaStatechart; + } } From fef81bd085892acf5da0ac8cdee4ccee2d430b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Mon, 28 Feb 2022 03:28:36 +0100 Subject: [PATCH 03/30] add state hierarchy transformations --- .../ScxmlToGammaStatechartTransformer.xtend | 139 +++++++++++++++++- .../scxml/transformation/Traceability.xtend | 69 ++++++++- .../transformation/.Traceability.java._trace | Bin 1959 -> 0 bytes .../transformation/.Traceability.xtendbin | Bin 4058 -> 0 bytes .../ScxmlToGammaStatechartTransformer.java | 34 ----- .../scxml/transformation/Traceability.java | 50 ------- 6 files changed, 201 insertions(+), 91 deletions(-) delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.java._trace delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.xtendbin delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.java delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 8b05a35c4..bc33483a5 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -1,11 +1,15 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType - -import static extension hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures.* -import static extension ac.soton.scxml.ScxmlModelDerivedFeatures.* -import static extension hu.bme.mit.gamma.scxml.transformation.Namings.* +import ac.soton.scxml.ScxmlStateType +import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition +import java.util.logging.Level + +import static ac.soton.scxml.ScxmlModelDerivedFeatures.* +import hu.bme.mit.gamma.statechart.statechart.Transition +import ac.soton.scxml.ScxmlTransitionType class ScxmlToGammaStatechartTransformer extends AbstractTransformer { @@ -33,9 +37,134 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { def execute() { traceability.put(scxmlRoot, gammaStatechart) - // + logger.log(Level.INFO, "Transforming root element (" + scxmlRoot.name + ")") + + val mainRegion = createRegion => [ + it.name = scxmlRoot.name + ] + gammaStatechart.regions += mainRegion + + val stateNodes = getStateNodes(scxmlRoot) + for (stateNode : stateNodes) { + if (isParallel(stateNode)) { + val parallel = stateNode as ScxmlParallelType + mainRegion.stateNodes += parallel.transformParallel + } + else if (isState(stateNode)) { + val state = stateNode as ScxmlStateType + mainRegion.stateNodes += state.transformState + } + else if (isFinal(stateNode)) { // TODO + /*val final = stateNode as ScxmlFinalType + mainRegion.stateNodes += final.transformFinal*/ + } + else { + throw new IllegalArgumentException( + "Object " + stateNode + " is of unknown SCXML type.") + } + } + + val transitions = getAllTransitions(scxmlRoot) + for (transition : transitions) { + // TODO gammaStatechart.transitions += transition.transform + } return traceability } + def State transformParallel(ScxmlParallelType parallelNode) { + logger.log(Level.INFO, "Transforming element (" + parallelNode.id + ")") + + val gammaParallel = createState => [ + it.name = parallelNode.id + ] + + val stateNodes = getStateNodes(parallelNode) + + for (stateNode : stateNodes) { + val region = createRegion => [ + it.name = gammaParallel.name + "Region" // TODO + ] + gammaParallel.regions += region + + if (isParallel(stateNode)) { + val parallel = stateNode as ScxmlParallelType + region.stateNodes += parallel.transformParallel + } + else if (isState(stateNode)) { + val state = stateNode as ScxmlStateType + region.stateNodes += state.transformState + } + else if (isFinal(stateNode)) { // TODO + /*val final = stateNode as ScxmlFinalType + region.stateNodes += final.transformFinal*/ + } + else { + throw new IllegalArgumentException( + "Object " + stateNode + " is of unknown SCXML type.") + } + } + + traceability.put(parallelNode, gammaParallel) + + return gammaParallel + } + + def State transformState(ScxmlStateType scxmlState) { + logger.log(Level.INFO, "Transforming element (" + scxmlState.id + ")") + + val gammaState = createState => [ + it.name = scxmlState.id + ] + + if (isCompoundState(scxmlState)) { + val region = createRegion => [ + it.name = gammaState.name + "Region" // TODO + ] + gammaState.regions += region + + val stateNodes = getStateNodes(scxmlState) + + for (stateNode : stateNodes) { + if (isParallel(stateNode)) { + val parallel = stateNode as ScxmlParallelType + region.stateNodes += parallel.transformParallel + } + else if (isState(stateNode)) { + val state = stateNode as ScxmlStateType + region.stateNodes += state.transformState + } + else if (isFinal(stateNode)) { // TODO + /*val final = stateNode as ScxmlFinalType + region.stateNodes += final.transformFinal*/ + } + else { + throw new IllegalArgumentException( + "Object " + stateNode + " is of unknown SCXML type.") + } + } + } + + traceability.put(scxmlState, gammaState) + + return gammaState + } + + protected def Transition transform(ScxmlTransitionType transition) { + // For now, only ScxmlStateType is considered as a type of a transition source. TODO + val sourceId = getParentStateNodeId(transition) + val targetId = transition.target.head + + val gammaSource = traceability.getStateById(sourceId) + val gammaTarget = traceability.getStateById(targetId) + + logger.log(Level.INFO, "Transforming transition" + sourceId + " -> " + targetId) + + val gammaTransition = gammaSource.createTransition(gammaTarget) + + traceability.put(transition, gammaTransition) + + return gammaTransition + } + } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index f70d75a97..b9d168c18 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -1,11 +1,12 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType - +import ac.soton.scxml.ScxmlTransitionType import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition - +import hu.bme.mit.gamma.statechart.statechart.Transition import hu.bme.mit.gamma.util.GammaEcoreUtil import java.util.Map @@ -20,10 +21,13 @@ class Traceability { protected final ScxmlScxmlType scxmlRoot protected final Map statechartDefinitions = newHashMap + protected final Map parallels = newHashMap protected final Map states = newHashMap + protected final Map transitions = newHashMap protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE + // new(ScxmlScxmlType scxmlRoot) { this.scxmlRoot = scxmlRoot @@ -46,4 +50,65 @@ class Traceability { return gammaStatechart } + // + + def put(ScxmlParallelType scxmlParallel, State gammaParallel) { + checkNotNull(scxmlParallel) + checkNotNull(gammaParallel) + parallels += scxmlParallel -> gammaParallel + } + + def getParallel(ScxmlParallelType scxmlParallel) { + checkNotNull(scxmlParallel) + val gammaParallel = parallels.get(scxmlParallel) + checkNotNull(gammaParallel) + return gammaParallel + } + + def getParallelById(String scxmlParallelId) { + checkNotNull(scxmlParallelId) + val keySet = states.keySet + val scxmlParallel = keySet.findFirst[parallel | parallel.id == scxmlParallelId] + checkNotNull(scxmlParallel) + return getState(scxmlParallel) + } + + // + + def put(ScxmlStateType scxmlState, State gammaState) { + checkNotNull(scxmlState) + checkNotNull(gammaState) + states += scxmlState -> gammaState + } + + def getState(ScxmlStateType scxmlState) { + checkNotNull(scxmlState) + val gammaState = states.get(scxmlState) + checkNotNull(gammaState) + return gammaState + } + + def getStateById(String scxmlStateId) { + checkNotNull(scxmlStateId) + val keySet = states.keySet + val scxmlState = keySet.findFirst[state | state.id == scxmlStateId] + checkNotNull(scxmlState) + return getState(scxmlState) + } + + // + + def put(ScxmlTransitionType scxmlTransition, Transition gammaTransition) { + checkNotNull(scxmlTransition) + checkNotNull(gammaTransition) + transitions += scxmlTransition -> gammaTransition + } + + def getTransition(ScxmlTransitionType scxmlTransition) { + checkNotNull(scxmlTransition) + val gammaTransition = transitions.get(scxmlTransition) + checkNotNull(gammaTransition) + return gammaTransition + } + } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.java._trace b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.java._trace deleted file mode 100644 index 92962d787ed4ac4ece3c748fce4cac7d6d0a994d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1959 zcmZwDTWB0r7zgnA&dj7_!equ6_L5CDo3Lq;O*WgFwDE$??97>q4;C7v`cTwuj5d%> zFxk?JiVqc(G*~bdBz+MrR1mb(H>o}Zu`1pWsVN95s8xLOp{0c&e&;)}nV~){zx{u= zGm4_<0MR8FQ&{y?zS6o2lzR^!sT``$RO+*h$}_cky;fP8K31QrG!|>~OHVH>)@zN~ zh55=Oi?!*Q+M(IG*~amaV~v^lrx)+ZKK|)Ms~Zx zw&-3SY;RXo_kblr_Xi8b5(0O|pzL=8GjNYO@3*yK&2{H+Dy3-d%ew_VeYcb*rJ=w* zWs#aK6iW!)vjxhs1qL2 zFDT@n&b?2e}ejGzn zwO~Cbm7<~Ry6EtAAqXyupDnS3Aozv$%41kU5L{1WaY5MKHaK|ugG0EtdSZAN?%>Y1 zrHZ15eqng{HX)qJ5Ti_~q(JyWH|fbNN)1n1QWlCO1mSB2WeW!NovT{qQJi|hS;HkP zOj-}mO_a;{MPAGd4Pkn5pj^gck{Yg?QYK~)eq)eU462L^!k?Y#kr5oT_JG)pCzCGp zq0}golS)bHBO|!tf)GSqsco@@AR4nM`&7JDjm9)7jrt}G(iimBC@zR1XJ4g)$86-q w!O?-q3O-y)jgFd9;%N}QWRrfgsWL8z&SpkOamuZ<*c82GkK$(x6#EXrzii}F_W%F@ diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.xtendbin b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/.Traceability.xtendbin deleted file mode 100644 index d9978a5633293b919558f55221a4878e7eca5fd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4058 zcmaJ^XE+?()*Zb^jNW_C=#hjVh;A@L5E*?8qD3cqFOiW~mk>l9T{2q8=tOU$ixNbM zFoMzJOMczl`+WDV^W&WTf~~~X^j3w+q`*hBs5yWvJ+SK*WW|; zN2a9;OKSGdD7G;{A(*~ptlQSci|3@G1L>wL4W(djfB%{M4Esjb+n4#ydokDwZo@}l zjhcf@#|HJO#2*b;Jg`Djr;E4c1{|P|%&&u?KN&w+yy%{HDt+n>ssUz-2>hX z?WWXzWav8w+?;z4FFy7)DlS;)v#1ZAIacyc*nKse2@B6P4-aZVuSpmslQ#4u%gnDU z<{Q4LX;_N59ummtxEwp7M*L_-*7fFn?P#vy(i?`S=?hhq&v8Iy=2VYj1&Xx3|A53S z-QNO*FD*wMdepr=l}r?!>lH@wzCeU+J-MlG?dv}F>)~CDV?E*W zp`t5DA-9lb;X@$NO3bxZGOnH&b0eaLgrsfLQlo+6`BgNH*WsShq`v>>V^c>qSPm(3 zY0Qhs+%dlr=F{)38)QC2%8aY3toO^p$$AF2;RljYdaRN{MCqQL??Z-wvLKu*#S zq!S}QJF`B*raVY3S7%Z0>OQH)2_@u!;?&2&G zJ(yU^P=)Og*}-1azcqcY9(fL}jgkTTUw!;itID+fqdjhi$ZkC!-~CUlkM!*d4EMJW z9BCsw$6^egBphDOr z{jdg=gl`c-|H1mxE%{^*CY~CLQ1O0s1(vEyIuqH7hh>m{BZi63yoCV$2rUGWg-mQe z*JRWjK6h8hr`PvWD}nu)%3hdI)yEpS+{I@=jybjL&Z*enYjfb&;k&U~{(1D%k;>e8 zTY?vq0v9`wekS7wkAJbjnL~)PhbXd>SF2tPYzx1BXSIiFy&>kIoo>;loBJ~svGT~E z^pofCGI5MLwCR~%)E9x4AGHjjiDUQW*xJ%z#gykPMkvqKr)RW+3ui@ciZ z(NPCI>gi_nOk;Y~pp1y1w3nuwP~x+A@+%G$IR3kQsoA;_@VagVsd8Y*zIruRy9^7)&xGeE9DV&@-7FdB zM~UH58waKXhHtL?Dol6)o-J#_dZAB>?JM**yc;G)CXhQ)GR)BTNhR) zO2;QHa&u&V3z7|S;gPUa+V)N&UXg#B&=KAe?+A%l2GSq;q_FK2`+4k3F`7XR7_?|r zo+Z$O1h9<_XkCFWm*mZ_(%a{9$zyHz2v%yRjqgG!MW`#Xh%fauHlIFPcJuGVD3xVw zT_9|8*09C)NYBhvc_|{KormO58_DOL#Zgip= z9ZQilhGQCyi!ss+llnY`)wa^?n_0ye-JOg-InduPFaD}v)+%5e+z>Z1&KM{AqPn0{ zxeVeN)rNTmjGV^WIFEGNQR4YKoVr$-?kb%-J-Zuu0gk>+eTNKjJJ@!Cb}8j~$o=E6 zj&)C6(|AtYCG|ZtFVV@)Y%B}6AA1eQ?6B#>z|swqRvPJ-N?iAa`cuhW_5>C^;S$b` z1iqIC+5M0AWc`3sUGA_f^*&Nt!~W9PdBXxd_A;{ZjSw%4FVZ~c&dSRH=u0-WLWHNV zdm87jkFTB5EQH>9B={wFBc@Ynq^3{OcZ&mnm>@t;m8uXNtgj&_3yPSDM58KX>muH7B zdkrhdV>(u3v9z#Tib+BKmDh`pKVh7Mx{u1_T4oPxMRUfy!ToiTSd&VQ$B~Lslabj> zL+B%Yy-_q!mfLIhrmJ!0Kmp|!5B}&3z~m=j)?SE>iV!j<{AkE#Ir!{YMJ0*nityWY zxX3N81`%KN03K~F4s)%U);HOSCRIOct5w&kl#NYMAl@_y}Q3qC581s zjntfImlI)pi3HG5f5cq# zk!FMlsqBYej>gk+Xhr+bZ|q`Q=vGN*+V*f?MqlG%1itlqEmYQ`6lLa&oJ_$ZG|wkj z7zCi8_O#7_7Twkx*dTQFYKLQrUo0?poHkAWw9JV+y-az*C{M_w6y+i-_T2lU1nO0x zHWv3z#$}*V+*>Dm5NN4eSSixpGfW{d;>T#VS7p_fO*F>g54ksmGs`&qK$|Mg2Mz!O%<*w^C z`#y9_pN*r3s_xrU6;ZUq=4(c$U*A0%zc7wT(gwd)C{(!pyNQ-75*!0z|2 zIsZdHF&4!DHX!vBOnxVPXE1#n(J!j5cm@}7Tg~EPbaDYOr0R~Y(Hn;)la6KO4ivPA zmAxr8P0 zZZzHeiI0LTuQeHY`GRys&yTPQ!ko-y`4e1h zHe3w`$WIUy5jy8$EGDo^3azRhi|l5B=2^}!x(g4;Y(jbko%r%+5`}~4@U8|T%e(AP zh7zl?!4M3(&FX8uj%)3Y&81Anb+w%Q#glk?I#))0o!0gF(|1|w$6{$6qGCe7*iF>z z?s%;$tesyGHpD1&Ih^OpHUHG4O99uIjAG7&%;pq)xiqBZj*J>#?ZnCG2XD(UoM^H} zykKp(*HKGy``|u)HHB7rUf7^Ag|nxe_NrUQgSGS%0rb{GmS0qVl+n_SS$UQi001)m zFJ=7GK-hYFd)PbM{t-m);*3G}$p;LvrQ4urBN8!4x|cX1BVW9|qNf;fc})2Oh$K0o zHX~Im{2{f0-7dv#cE9^-fs}Y2Q;qus;x~cG?ew)B$`50jl!b33q>11+uVKGr?JvF< z%5OKj?y-jTQ&~FC#rRfS!Q|XMYnnT9Cziey=6pI4@9Axrv$d+B8eQ;W?>x5jJE|%1 zKVCmNG0aO=`6V*~eUwqB*b3S3o%5WT<(>11nc1DCS$-`2__TkoC~6so%gxwLftu)B zC;AoQ2k5ML?>K@jAwvf^i^?e`FJT~K7oU(be`(y5Y|16G4XOK`dQ z_MN{+l(RZKkk{a4w2lAvL8kEa@07N=oW?_qL64JmsRXT!ffe!Acf zQ|OuPsHevzS9tg>hXz=)(KdZZrODKk+{l89Y8(qbX@4T3_Rj~1rL}kuPd6W(nzTcJ zg#4JRb-s$(1S85bqSKh(hxO@K8SIq|B~h2Ckbj=vlXoCU%}8(eUMfwl$aG{!0%?*( zS5oe~ms3FY3PEYp3l;k{xVo^eooh~#ylGz&c(QjV;pJ4SYYxypW!`fw3M)=2W8~TD{{7fZKwdYF zqMe>anIwR&%Mp;*hr8FV$ASR_PIMfi+VFg;Eo)`MuN6Gytj5xWnlwmp?tiDSWVyS`ff zL*_!QWMC>G0I)^#hs*?o41j<2!+%?VKXm?g{M{Y@=gz-V _function = (SynchronousStatechartDefinition it) -> { - it.setName(scxmlRoot.getName()); - }; - SynchronousStatechartDefinition _doubleArrow = ObjectExtensions.operator_doubleArrow(_createSynchronousStatechartDefinition, _function); - this.gammaStatechart = _doubleArrow; - } - - public Traceability execute() { - this.traceability.put(this.scxmlRoot, this.gammaStatechart); - return this.traceability; - } -} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java deleted file mode 100644 index 964aef81d..000000000 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/xtend-gen/hu/bme/mit/gamma/scxml/transformation/Traceability.java +++ /dev/null @@ -1,50 +0,0 @@ -package hu.bme.mit.gamma.scxml.transformation; - -import ac.soton.scxml.ScxmlScxmlType; -import ac.soton.scxml.ScxmlStateType; -import com.google.common.base.Preconditions; -import hu.bme.mit.gamma.statechart.statechart.State; -import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition; -import hu.bme.mit.gamma.util.GammaEcoreUtil; -import java.util.Map; -import org.eclipse.xtext.xbase.lib.CollectionLiterals; -import org.eclipse.xtext.xbase.lib.Extension; -import org.eclipse.xtext.xbase.lib.Pair; - -@SuppressWarnings("all") -public class Traceability { - protected final ScxmlScxmlType scxmlRoot; - - protected final Map statechartDefinitions = CollectionLiterals.newHashMap(); - - protected final Map states = CollectionLiterals.newHashMap(); - - @Extension - protected final GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE; - - public Traceability(final ScxmlScxmlType scxmlRoot) { - this.scxmlRoot = scxmlRoot; - } - - public ScxmlScxmlType getScxmlRoot() { - return this.scxmlRoot; - } - - public SynchronousStatechartDefinition put(final ScxmlScxmlType scxmlRoot, final SynchronousStatechartDefinition gammaStatechart) { - SynchronousStatechartDefinition _xblockexpression = null; - { - Preconditions.checkNotNull(scxmlRoot); - Preconditions.checkNotNull(gammaStatechart); - Pair _mappedTo = Pair.of(scxmlRoot, gammaStatechart); - _xblockexpression = this.statechartDefinitions.put(_mappedTo.getKey(), _mappedTo.getValue()); - } - return _xblockexpression; - } - - public SynchronousStatechartDefinition getStatechartDefinition(final ScxmlScxmlType scxmlRoot) { - Preconditions.checkNotNull(scxmlRoot); - final SynchronousStatechartDefinition gammaStatechart = this.statechartDefinitions.get(scxmlRoot); - Preconditions.checkNotNull(gammaStatechart); - return gammaStatechart; - } -} From 014d25c1fcd027a0ab1ed5c6c485a94a410947b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Wed, 9 Mar 2022 01:48:02 +0100 Subject: [PATCH 04/30] Add basic guard condition parser --- .../META-INF/MANIFEST.MF | 12 +++- .../transformation/AbstractTransformer.xtend | 3 + .../ScxmlToGammaStatechartTransformer.xtend | 43 ++++++++----- .../parse/ConditionalLanguageParser.java | 63 +++++++++++++++++++ .../parse/CustomLanguageParser.java | 12 ++++ .../parse/CustomLanguageScope.java | 21 +++++++ .../parse/CustomLanguageStandaloneSetup.java | 15 +++++ .../parse/CustomRuntimeModule.java | 26 ++++++++ 8 files changed, 179 insertions(+), 16 deletions(-) create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageScope.java create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageStandaloneSetup.java create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomRuntimeModule.java diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF index 9e3592bc6..de2e53465 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF @@ -10,5 +10,15 @@ Require-Bundle: ac.soton.scxml, com.google.guava, org.eclipse.xtext.xbase.lib, org.eclipse.xtend.lib, - org.eclipse.xtend.lib.macro + org.eclipse.xtend.lib.macro, + hu.bme.mit.gamma.expression.language, + com.google.inject;bundle-version="3.0.0", + hu.bme.mit.gamma.expression.model Export-Package: hu.bme.mit.gamma.scxml.transformation +Import-Package: org.antlr.runtime, + org.eclipse.xtext, + org.eclipse.xtext.nodemodel, + org.eclipse.xtext.parser, + org.eclipse.xtext.scoping, + org.eclipse.xtext.scoping.impl, + org.eclipse.xtext.util diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend index 6a53897c0..1eb81828f 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend @@ -1,5 +1,6 @@ package hu.bme.mit.gamma.scxml.transformation +import hu.bme.mit.gamma.scxml.transformation.parse.ConditionalLanguageParser import hu.bme.mit.gamma.statechart.interface_.InterfaceModelFactory import hu.bme.mit.gamma.statechart.statechart.StatechartModelFactory import hu.bme.mit.gamma.statechart.util.StatechartUtil @@ -16,6 +17,8 @@ abstract class AbstractTransformer { protected final extension InterfaceModelFactory interfaceModelFactory = InterfaceModelFactory.eINSTANCE protected final extension StatechartModelFactory statechartModelFactory = StatechartModelFactory.eINSTANCE + protected final ConditionalLanguageParser conditionalLanguageParser = new ConditionalLanguageParser() + protected final Logger logger = Logger.getLogger("GammaLogger") new(Traceability traceability) { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index bc33483a5..cc2cb4559 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -3,13 +3,16 @@ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType +import ac.soton.scxml.ScxmlTransitionType + import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition +import hu.bme.mit.gamma.statechart.statechart.Transition + import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* -import hu.bme.mit.gamma.statechart.statechart.Transition -import ac.soton.scxml.ScxmlTransitionType +import java.util.HashMap class ScxmlToGammaStatechartTransformer extends AbstractTransformer { @@ -50,9 +53,8 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val parallel = stateNode as ScxmlParallelType mainRegion.stateNodes += parallel.transformParallel } - else if (isState(stateNode)) { - val state = stateNode as ScxmlStateType - mainRegion.stateNodes += state.transformState + else if (stateNode instanceof ScxmlStateType) { + mainRegion.stateNodes += stateNode.transformState } else if (isFinal(stateNode)) { // TODO /*val final = stateNode as ScxmlFinalType @@ -66,7 +68,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val transitions = getAllTransitions(scxmlRoot) for (transition : transitions) { - // TODO gammaStatechart.transitions += transition.transform + transition.transform } return traceability @@ -155,16 +157,27 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val sourceId = getParentStateNodeId(transition) val targetId = transition.target.head - val gammaSource = traceability.getStateById(sourceId) - val gammaTarget = traceability.getStateById(targetId) - - logger.log(Level.INFO, "Transforming transition" + sourceId + " -> " + targetId) - - val gammaTransition = gammaSource.createTransition(gammaTarget) - - traceability.put(transition, gammaTransition) + if (sourceId !== null) { + val gammaSource = traceability.getStateById(sourceId) + val gammaTarget = traceability.getStateById(targetId) + + logger.log(Level.INFO, "Transforming transition" + sourceId + " -> " + targetId) + + val gammaTransition = gammaSource.createTransition(gammaTarget) + + val guardStr = transition.cond + if (guardStr !== null) { + val gammaGuardExpression = conditionalLanguageParser + .parse(guardStr, new HashMap) + gammaTransition.guard = gammaGuardExpression + } + + traceability.put(transition, gammaTransition) + + return gammaTransition + } - return gammaTransition + return null } } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java new file mode 100644 index 000000000..aef05a864 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java @@ -0,0 +1,63 @@ +package hu.bme.mit.gamma.scxml.transformation.parse; + +import java.io.StringReader; +import java.util.Map; +import java.util.NoSuchElementException; + +import org.eclipse.xtext.CrossReference; +import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.parser.IParseResult; + +import com.google.inject.Injector; + +import hu.bme.mit.gamma.expression.model.Declaration; +import hu.bme.mit.gamma.expression.model.DirectReferenceExpression; +import hu.bme.mit.gamma.expression.model.Expression; +import hu.bme.mit.gamma.expression.model.ExpressionModelFactory; +import hu.bme.mit.gamma.expression.model.OpaqueExpression; + +public class ConditionalLanguageParser { + + ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE; + + private Injector injector = new CustomLanguageStandaloneSetup() + .createInjectorAndDoEMFRegistration(); + + public Expression parse(String expression, Map scope) { + CustomLanguageParser parser = injector.getInstance(CustomLanguageParser.class); + StringReader reader = new StringReader(expression); + IParseResult result = parser.parse(reader); + + if (result.hasSyntaxErrors()) { + return createOpaqueExpression(expression); + } + + try { + for (INode node : result.getRootNode().getLeafNodes()) { + if (node.getGrammarElement() instanceof CrossReference) { + final DirectReferenceExpression refExpr = + (DirectReferenceExpression) node.getSemanticElement(); + + Declaration decl = scope.get(node.getText()); + if (decl != null) { + refExpr.setDeclaration(decl); + } else { + throw new NoSuchElementException(); + } + } + } + return (Expression) result.getRootASTElement(); + } + catch (NoSuchElementException e) { + } + + return createOpaqueExpression(expression); + } + + private Expression createOpaqueExpression(String expression) { + OpaqueExpression opaqueExpression = expressionModelFactory.createOpaqueExpression(); + opaqueExpression.setExpression(expression); + return opaqueExpression; + } + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java new file mode 100644 index 000000000..eb953b893 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java @@ -0,0 +1,12 @@ +package hu.bme.mit.gamma.scxml.transformation.parse; + +import hu.bme.mit.gamma.expression.language.parser.antlr.ExpressionLanguageParser; + +public class CustomLanguageParser extends ExpressionLanguageParser { + + @Override + protected String getDefaultRuleName() { + return "Expression"; + } + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageScope.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageScope.java new file mode 100644 index 000000000..6a77617da --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageScope.java @@ -0,0 +1,21 @@ +package hu.bme.mit.gamma.scxml.transformation.parse; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.xtext.scoping.IScope; + +import hu.bme.mit.gamma.expression.language.scoping.ExpressionLanguageScopeProvider; + +public class CustomLanguageScope extends ExpressionLanguageScopeProvider { + + @Override + public IScope getScope(EObject context, EReference reference) { + return super.getScope(context, reference); + } + + @Override + protected IScope delegateGetScope(EObject context, EReference reference) { + return super.delegateGetScope(context, reference); + } + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageStandaloneSetup.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageStandaloneSetup.java new file mode 100644 index 000000000..a1182ae27 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageStandaloneSetup.java @@ -0,0 +1,15 @@ +package hu.bme.mit.gamma.scxml.transformation.parse; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +import hu.bme.mit.gamma.expression.language.ExpressionLanguageStandaloneSetup; + +public class CustomLanguageStandaloneSetup extends ExpressionLanguageStandaloneSetup { + + @Override + public Injector createInjector() { + return Guice.createInjector(new CustomRuntimeModule()); + } + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomRuntimeModule.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomRuntimeModule.java new file mode 100644 index 000000000..348748ba1 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomRuntimeModule.java @@ -0,0 +1,26 @@ +package hu.bme.mit.gamma.scxml.transformation.parse; + +import org.eclipse.xtext.parser.IParser; +import org.eclipse.xtext.scoping.IScopeProvider; +import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; + +import com.google.inject.Binder; +import com.google.inject.name.Names; + +import hu.bme.mit.gamma.expression.language.ExpressionLanguageRuntimeModule; + +public class CustomRuntimeModule extends ExpressionLanguageRuntimeModule { + + @Override + public Class bindIParser() { + return CustomLanguageParser.class; + } + + @Override + public void configureIScopeProviderDelegate(Binder binder) { + binder.bind(IScopeProvider.class) + .annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)) + .to(CustomLanguageScope.class); + } + +} From f9cd8e287b2f3e15772da5b45a01153aa0f25452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Mon, 28 Mar 2022 19:12:40 +0200 Subject: [PATCH 05/30] Simplify basic expression parser --- .../parse/ConditionalLanguageParser.java | 10 +++++++--- .../transformation/parse/CustomLanguageParser.java | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java index aef05a864..c51a7f9cf 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java @@ -10,6 +10,8 @@ import com.google.inject.Injector; +import hu.bme.mit.gamma.expression.language.ExpressionLanguageStandaloneSetup; +import hu.bme.mit.gamma.expression.language.parser.antlr.ExpressionLanguageParser; import hu.bme.mit.gamma.expression.model.Declaration; import hu.bme.mit.gamma.expression.model.DirectReferenceExpression; import hu.bme.mit.gamma.expression.model.Expression; @@ -20,11 +22,13 @@ public class ConditionalLanguageParser { ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE; - private Injector injector = new CustomLanguageStandaloneSetup() - .createInjectorAndDoEMFRegistration(); + //private Injector injector = new CustomLanguageStandaloneSetup() + // .createInjectorAndDoEMFRegistration(); + private Injector injector = new ExpressionLanguageStandaloneSetup() + .createInjectorAndDoEMFRegistration(); public Expression parse(String expression, Map scope) { - CustomLanguageParser parser = injector.getInstance(CustomLanguageParser.class); + CustomLanguageParser parser = injector.getInstance(CustomLanguageParser.class); StringReader reader = new StringReader(expression); IParseResult result = parser.parse(reader); diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java index eb953b893..155533d37 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java @@ -3,7 +3,8 @@ import hu.bme.mit.gamma.expression.language.parser.antlr.ExpressionLanguageParser; public class CustomLanguageParser extends ExpressionLanguageParser { - + + // Set default rule to "Expression" from "ExpressionPackage" @Override protected String getDefaultRuleName() { return "Expression"; From 88822a8fee58c59f0ab03d68dc12bcf61748f83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Mon, 28 Mar 2022 21:22:30 +0200 Subject: [PATCH 06/30] Transform final states and add naming functions --- .../gamma/scxml/transformation/Namings.xtend | 9 +++- .../ScxmlToGammaStatechartTransformer.xtend | 52 ++++++++++++------- .../scxml/transformation/Traceability.xtend | 33 ++++++++++-- 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index 84a491fd1..c97c3e4a4 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -1,11 +1,16 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.ScxmlFinalType +import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType class Namings { - def static String getStatechartDefinitionName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' - def static String getStateName(ScxmlStateType state) '''«state.id»''' + def static String getStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' + def static String getRegionName(String scxmlElementName) '''«scxmlElementName»Region''' + def static String getParallelName(ScxmlParallelType scxmlParallel) '''«scxmlParallel.id»''' + def static String getStateName(ScxmlStateType scxmlState) '''«scxmlState.id»''' + def static String getFinalName(ScxmlFinalType scxmlFinal) '''«scxmlFinal.id»''' } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index cc2cb4559..b20767c97 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -4,15 +4,15 @@ import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType - import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition - +import java.util.HashMap import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* -import java.util.HashMap +import static hu.bme.mit.gamma.scxml.transformation.Namings.* +import ac.soton.scxml.ScxmlFinalType class ScxmlToGammaStatechartTransformer extends AbstractTransformer { @@ -33,7 +33,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { this.scxmlRoot = scxmlRoot this.gammaStatechart = createSynchronousStatechartDefinition => [ - it.name = scxmlRoot.name + it.name = getStatechartName(scxmlRoot) ] } @@ -43,7 +43,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { logger.log(Level.INFO, "Transforming root element (" + scxmlRoot.name + ")") val mainRegion = createRegion => [ - it.name = scxmlRoot.name + it.name = getRegionName(scxmlRoot.name) ] gammaStatechart.regions += mainRegion @@ -56,9 +56,9 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { else if (stateNode instanceof ScxmlStateType) { mainRegion.stateNodes += stateNode.transformState } - else if (isFinal(stateNode)) { // TODO - /*val final = stateNode as ScxmlFinalType - mainRegion.stateNodes += final.transformFinal*/ + else if (isFinal(stateNode)) { + val final = stateNode as ScxmlFinalType + mainRegion.stateNodes += final.transformFinal } else { throw new IllegalArgumentException( @@ -74,18 +74,18 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { return traceability } - def State transformParallel(ScxmlParallelType parallelNode) { + protected def State transformParallel(ScxmlParallelType parallelNode) { logger.log(Level.INFO, "Transforming element (" + parallelNode.id + ")") val gammaParallel = createState => [ - it.name = parallelNode.id + it.name = getParallelName(parallelNode) ] val stateNodes = getStateNodes(parallelNode) for (stateNode : stateNodes) { val region = createRegion => [ - it.name = gammaParallel.name + "Region" // TODO + it.name = getRegionName(gammaParallel.name) ] gammaParallel.regions += region @@ -97,9 +97,9 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val state = stateNode as ScxmlStateType region.stateNodes += state.transformState } - else if (isFinal(stateNode)) { // TODO - /*val final = stateNode as ScxmlFinalType - region.stateNodes += final.transformFinal*/ + else if (isFinal(stateNode)) { + val final = stateNode as ScxmlFinalType + region.stateNodes += final.transformFinal } else { throw new IllegalArgumentException( @@ -112,16 +112,16 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { return gammaParallel } - def State transformState(ScxmlStateType scxmlState) { + protected def State transformState(ScxmlStateType scxmlState) { logger.log(Level.INFO, "Transforming element (" + scxmlState.id + ")") val gammaState = createState => [ - it.name = scxmlState.id + it.name = getStateName(scxmlState) ] if (isCompoundState(scxmlState)) { val region = createRegion => [ - it.name = gammaState.name + "Region" // TODO + it.name = getRegionName(gammaState.name) ] gammaState.regions += region @@ -136,9 +136,9 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val state = stateNode as ScxmlStateType region.stateNodes += state.transformState } - else if (isFinal(stateNode)) { // TODO - /*val final = stateNode as ScxmlFinalType - region.stateNodes += final.transformFinal*/ + else if (isFinal(stateNode)) { + val final = stateNode as ScxmlFinalType + region.stateNodes += final.transformFinal } else { throw new IllegalArgumentException( @@ -152,6 +152,18 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { return gammaState } + protected def State transformFinal(ScxmlFinalType scxmlFinal) { + logger.log(Level.INFO, "Transforming element (" + scxmlFinal.id + ")") + + val gammaFinal = createState => [ + it.name = getFinalName(scxmlFinal) + ] + + traceability.put(scxmlFinal, gammaFinal) + + return gammaFinal + } + protected def Transition transform(ScxmlTransitionType transition) { // For now, only ScxmlStateType is considered as a type of a transition source. TODO val sourceId = getParentStateNodeId(transition) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index b9d168c18..eb43a6e1c 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -11,6 +11,7 @@ import hu.bme.mit.gamma.util.GammaEcoreUtil import java.util.Map import static com.google.common.base.Preconditions.checkNotNull +import ac.soton.scxml.ScxmlFinalType class Traceability { @@ -23,11 +24,12 @@ class Traceability { protected final Map statechartDefinitions = newHashMap protected final Map parallels = newHashMap protected final Map states = newHashMap + protected final Map finals = newHashMap protected final Map transitions = newHashMap protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE - // + // - Synchronous Statechart Definition new(ScxmlScxmlType scxmlRoot) { this.scxmlRoot = scxmlRoot @@ -50,7 +52,7 @@ class Traceability { return gammaStatechart } - // + // - State (with orthogonal Regions) def put(ScxmlParallelType scxmlParallel, State gammaParallel) { checkNotNull(scxmlParallel) @@ -73,7 +75,7 @@ class Traceability { return getState(scxmlParallel) } - // + // - State def put(ScxmlStateType scxmlState, State gammaState) { checkNotNull(scxmlState) @@ -96,7 +98,30 @@ class Traceability { return getState(scxmlState) } - // + // - State + + def put(ScxmlFinalType scxmlFinal, State gammaFinal) { + checkNotNull(scxmlFinal) + checkNotNull(gammaFinal) + finals += scxmlFinal -> gammaFinal + } + + def getFinalState(ScxmlFinalType scxmlFinal) { + checkNotNull(scxmlFinal) + val gammaFinal = finals.get(scxmlFinal) + checkNotNull(gammaFinal) + return gammaFinal + } + + def getFinalById(String scxmlFinalId) { + checkNotNull(scxmlFinalId) + val keySet = finals.keySet + val scxmlFinal = keySet.findFirst[final | final.id == scxmlFinalId] + checkNotNull(scxmlFinal) + return getFinalState(scxmlFinal) + } + + // - Transition def put(ScxmlTransitionType scxmlTransition, Transition gammaTransition) { checkNotNull(scxmlTransition) From d110bf82bdd0d33480585cf00353637f812ee799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Tue, 29 Mar 2022 02:28:32 +0200 Subject: [PATCH 07/30] Transform initial states --- .../gamma/scxml/transformation/Namings.xtend | 2 + .../ScxmlToGammaStatechartTransformer.xtend | 124 +++++++++++++----- .../scxml/transformation/Traceability.xtend | 24 +++- 3 files changed, 115 insertions(+), 35 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index c97c3e4a4..3458371e9 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -12,5 +12,7 @@ class Namings { def static String getParallelName(ScxmlParallelType scxmlParallel) '''«scxmlParallel.id»''' def static String getStateName(ScxmlStateType scxmlState) '''«scxmlState.id»''' def static String getFinalName(ScxmlFinalType scxmlFinal) '''«scxmlFinal.id»''' + def static String getInitialName(ScxmlStateType scxmlParentState) '''«scxmlParentState.id»Initial''' + def static String getInitialName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»Initial''' } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index b20767c97..3a5c09723 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -1,9 +1,12 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.ScxmlFinalType +import ac.soton.scxml.ScxmlInitialType import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType +import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition @@ -12,8 +15,8 @@ import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* -import ac.soton.scxml.ScxmlFinalType +// TODO Transform not only the first transition in a target state specification, but all of them. class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Root element of the SCXML statechart model to transform @@ -37,6 +40,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { ] } + // Transformation of the SCXML root element and its contents recursively def execute() { traceability.put(scxmlRoot, gammaStatechart) @@ -47,28 +51,47 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { ] gammaStatechart.regions += mainRegion - val stateNodes = getStateNodes(scxmlRoot) - for (stateNode : stateNodes) { - if (isParallel(stateNode)) { - val parallel = stateNode as ScxmlParallelType + val scxmlStateNodes = getStateNodes(scxmlRoot) + for (scxmlStateNode : scxmlStateNodes) { + if (isParallel(scxmlStateNode)) { + val parallel = scxmlStateNode as ScxmlParallelType mainRegion.stateNodes += parallel.transformParallel } - else if (stateNode instanceof ScxmlStateType) { - mainRegion.stateNodes += stateNode.transformState + else if (scxmlStateNode instanceof ScxmlStateType) { + mainRegion.stateNodes += scxmlStateNode.transformState } - else if (isFinal(stateNode)) { - val final = stateNode as ScxmlFinalType + else if (isFinal(scxmlStateNode)) { + val final = scxmlStateNode as ScxmlFinalType mainRegion.stateNodes += final.transformFinal } else { throw new IllegalArgumentException( - "Object " + stateNode + " is of unknown SCXML type.") + "Object " + scxmlStateNode + " is of unknown SCXML type.") } } val transitions = getAllTransitions(scxmlRoot) for (transition : transitions) { - transition.transform + transition.transformTransition + } + + // Transform the SCXML root element's initial attribute, + // or select its first child as initial state if it is not present. + val gammaInitial = createInitialState => [ + it.name = getInitialName(scxmlRoot) + ] + mainRegion.stateNodes += gammaInitial + + val scxmlInitialAttribute = scxmlRoot.initial + val scxmlFirstInitialAttribute = scxmlInitialAttribute?.head + if (scxmlFirstInitialAttribute !== null) { + val gammaInitialTarget = traceability.getStateById(scxmlFirstInitialAttribute) + gammaInitial.createTransition(gammaInitialTarget) + } + else { + val firstScxmlStateChild = getFirstChildStateNode(scxmlRoot) as ScxmlStateType + val gammaInitialTarget = traceability.getState(firstScxmlStateChild) + gammaInitial.createTransition(gammaInitialTarget) } return traceability @@ -81,29 +104,29 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { it.name = getParallelName(parallelNode) ] - val stateNodes = getStateNodes(parallelNode) + val scxmlStateNodes = getStateNodes(parallelNode) - for (stateNode : stateNodes) { + for (scxmlStateNode : scxmlStateNodes) { val region = createRegion => [ it.name = getRegionName(gammaParallel.name) ] gammaParallel.regions += region - if (isParallel(stateNode)) { - val parallel = stateNode as ScxmlParallelType + if (isParallel(scxmlStateNode)) { + val parallel = scxmlStateNode as ScxmlParallelType region.stateNodes += parallel.transformParallel } - else if (isState(stateNode)) { - val state = stateNode as ScxmlStateType + else if (isState(scxmlStateNode)) { + val state = scxmlStateNode as ScxmlStateType region.stateNodes += state.transformState } - else if (isFinal(stateNode)) { - val final = stateNode as ScxmlFinalType + else if (isFinal(scxmlStateNode)) { + val final = scxmlStateNode as ScxmlFinalType region.stateNodes += final.transformFinal } else { throw new IllegalArgumentException( - "Object " + stateNode + " is of unknown SCXML type.") + "Object " + scxmlStateNode + " is of unknown SCXML type.") } } @@ -125,27 +148,51 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { ] gammaState.regions += region - val stateNodes = getStateNodes(scxmlState) + val scxmlStateNodes = getStateNodes(scxmlState) - for (stateNode : stateNodes) { - if (isParallel(stateNode)) { - val parallel = stateNode as ScxmlParallelType + for (scxmlStateNode : scxmlStateNodes) { + if (isParallel(scxmlStateNode)) { + val parallel = scxmlStateNode as ScxmlParallelType region.stateNodes += parallel.transformParallel } - else if (isState(stateNode)) { - val state = stateNode as ScxmlStateType + else if (isState(scxmlStateNode)) { + val state = scxmlStateNode as ScxmlStateType region.stateNodes += state.transformState } - else if (isFinal(stateNode)) { - val final = stateNode as ScxmlFinalType + else if (isFinal(scxmlStateNode)) { + val final = scxmlStateNode as ScxmlFinalType region.stateNodes += final.transformFinal } else { throw new IllegalArgumentException( - "Object " + stateNode + " is of unknown SCXML type.") + "Object " + scxmlStateNode + " is of unknown SCXML type.") } } - } + + // Transform the state's initial element or attribute, + // or select its first child as initial state if neither one above is present. + val scxmlInitialElement = scxmlState.initial.head + if (scxmlInitialElement !== null) { + region.stateNodes += scxmlInitialElement.transformInitial + } + else { + val gammaInitial = createInitialState => [ + it.name = getInitialName(scxmlState) + ] + region.stateNodes += gammaInitial + + val scxmlInitialAttribute = scxmlState.initial1.head + if (scxmlInitialAttribute !== null) { + val gammaInitialTarget = traceability.getStateById(scxmlInitialAttribute) + gammaInitial.createTransition(gammaInitialTarget) + } + else { + val firstScxmlStateChild = getFirstChildStateNode(scxmlState) as ScxmlStateType + val gammaInitialTarget = traceability.getState(firstScxmlStateChild) + gammaInitial.createTransition(gammaInitialTarget) + } + } + } traceability.put(scxmlState, gammaState) @@ -164,8 +211,21 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { return gammaFinal } - protected def Transition transform(ScxmlTransitionType transition) { - // For now, only ScxmlStateType is considered as a type of a transition source. TODO + protected def InitialState transformInitial(ScxmlInitialType scxmlInitial) { + logger.log(Level.INFO, "Transforming element") + + val parentState = getParentState(scxmlInitial) + val gammaInitial = createInitialState => [ + it.name = getInitialName(parentState) + ] + + traceability.put(scxmlInitial, gammaInitial) + + return gammaInitial + } + + protected def Transition transformTransition(ScxmlTransitionType transition) { + // TODO For now, only ScxmlStateType is considered as a type of transition source. val sourceId = getParentStateNodeId(transition) val targetId = transition.target.head diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index eb43a6e1c..f936ff205 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -1,9 +1,12 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.ScxmlFinalType +import ac.soton.scxml.ScxmlInitialType import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType +import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition @@ -11,7 +14,6 @@ import hu.bme.mit.gamma.util.GammaEcoreUtil import java.util.Map import static com.google.common.base.Preconditions.checkNotNull -import ac.soton.scxml.ScxmlFinalType class Traceability { @@ -25,6 +27,7 @@ class Traceability { protected final Map parallels = newHashMap protected final Map states = newHashMap protected final Map finals = newHashMap + protected final Map initials = newHashMap protected final Map transitions = newHashMap protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE @@ -52,7 +55,7 @@ class Traceability { return gammaStatechart } - // - State (with orthogonal Regions) + // - State (with orthogonal Region children) def put(ScxmlParallelType scxmlParallel, State gammaParallel) { checkNotNull(scxmlParallel) @@ -75,7 +78,7 @@ class Traceability { return getState(scxmlParallel) } - // - State + // - State (with a Region child if it is compound) def put(ScxmlStateType scxmlState, State gammaState) { checkNotNull(scxmlState) @@ -121,6 +124,21 @@ class Traceability { return getFinalState(scxmlFinal) } + // - InitialState + + def put(ScxmlInitialType scxmlInitial, InitialState gammaInitial) { + checkNotNull(scxmlInitial) + checkNotNull(gammaInitial) + initials += scxmlInitial -> gammaInitial + } + + def getInitialState(ScxmlInitialType scxmlInitial) { + checkNotNull(scxmlInitial) + val gammaInitial = initials.get(scxmlInitial) + checkNotNull(gammaInitial) + return gammaInitial + } + // - Transition def put(ScxmlTransitionType scxmlTransition, Transition gammaTransition) { From 75e4d9a10f334579dfaa789fee0e68dcc8106588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Wed, 30 Mar 2022 01:44:10 +0200 Subject: [PATCH 08/30] Transform history states and transitions --- .../gamma/scxml/transformation/Namings.xtend | 3 + .../ScxmlToGammaStatechartTransformer.xtend | 83 ++++++++---- .../scxml/transformation/Traceability.xtend | 125 +++++++++++++----- 3 files changed, 151 insertions(+), 60 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index 3458371e9..53a6f28fd 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -1,6 +1,7 @@ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlFinalType +import ac.soton.scxml.ScxmlHistoryType import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType @@ -14,5 +15,7 @@ class Namings { def static String getFinalName(ScxmlFinalType scxmlFinal) '''«scxmlFinal.id»''' def static String getInitialName(ScxmlStateType scxmlParentState) '''«scxmlParentState.id»Initial''' def static String getInitialName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»Initial''' + def static String getShallowHistoryName(ScxmlHistoryType scxmlHistoryState) '''«scxmlHistoryState.id»ShallowHistory''' + def static String getDeepHistoryName(ScxmlHistoryType scxmlHistoryState) '''«scxmlHistoryState.id»DeepHistory''' } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 3a5c09723..0a66bd9f1 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -1,11 +1,14 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.HistoryTypeDatatype import ac.soton.scxml.ScxmlFinalType +import ac.soton.scxml.ScxmlHistoryType import ac.soton.scxml.ScxmlInitialType import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType +import hu.bme.mit.gamma.statechart.statechart.EntryState import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition @@ -16,7 +19,6 @@ import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* -// TODO Transform not only the first transition in a target state specification, but all of them. class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Root element of the SCXML statechart model to transform @@ -85,7 +87,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val scxmlInitialAttribute = scxmlRoot.initial val scxmlFirstInitialAttribute = scxmlInitialAttribute?.head if (scxmlFirstInitialAttribute !== null) { - val gammaInitialTarget = traceability.getStateById(scxmlFirstInitialAttribute) + val gammaInitialTarget = traceability.getStateNodeById(scxmlFirstInitialAttribute) gammaInitial.createTransition(gammaInitialTarget) } else { @@ -105,7 +107,6 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { ] val scxmlStateNodes = getStateNodes(parallelNode) - for (scxmlStateNode : scxmlStateNodes) { val region = createRegion => [ it.name = getRegionName(gammaParallel.name) @@ -130,6 +131,12 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { } } + // TODO Transform history pseudo-states (by adding a wrapper compound state perhaps) + /*val scxmlHistoryStates = parallelNode.history + for (scxmlHistoryState : scxmlHistoryStates) { + + }*/ + traceability.put(parallelNode, gammaParallel) return gammaParallel @@ -149,7 +156,6 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { gammaState.regions += region val scxmlStateNodes = getStateNodes(scxmlState) - for (scxmlStateNode : scxmlStateNodes) { if (isParallel(scxmlStateNode)) { val parallel = scxmlStateNode as ScxmlParallelType @@ -173,7 +179,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // or select its first child as initial state if neither one above is present. val scxmlInitialElement = scxmlState.initial.head if (scxmlInitialElement !== null) { - region.stateNodes += scxmlInitialElement.transformInitial + region.stateNodes += scxmlInitialElement.transform } else { val gammaInitial = createInitialState => [ @@ -183,7 +189,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val scxmlInitialAttribute = scxmlState.initial1.head if (scxmlInitialAttribute !== null) { - val gammaInitialTarget = traceability.getStateById(scxmlInitialAttribute) + val gammaInitialTarget = traceability.getStateNodeById(scxmlInitialAttribute) gammaInitial.createTransition(gammaInitialTarget) } else { @@ -192,6 +198,12 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { gammaInitial.createTransition(gammaInitialTarget) } } + + // Transform history pseudo-states + val scxmlHistoryStates = scxmlState.history + for (scxmlHistoryState : scxmlHistoryStates) { + region.stateNodes += scxmlHistoryState.transform + } } traceability.put(scxmlState, gammaState) @@ -211,7 +223,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { return gammaFinal } - protected def InitialState transformInitial(ScxmlInitialType scxmlInitial) { + protected def InitialState transform(ScxmlInitialType scxmlInitial) { logger.log(Level.INFO, "Transforming element") val parentState = getParentState(scxmlInitial) @@ -224,32 +236,47 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { return gammaInitial } - protected def Transition transformTransition(ScxmlTransitionType transition) { - // TODO For now, only ScxmlStateType is considered as a type of transition source. - val sourceId = getParentStateNodeId(transition) - val targetId = transition.target.head + protected def EntryState transform(ScxmlHistoryType scxmlHistory) { + logger.log(Level.INFO, "Transforming element (" + scxmlHistory.id + ")") - if (sourceId !== null) { - val gammaSource = traceability.getStateById(sourceId) - val gammaTarget = traceability.getStateById(targetId) - - logger.log(Level.INFO, "Transforming transition" + sourceId + " -> " + targetId) - - val gammaTransition = gammaSource.createTransition(gammaTarget) - - val guardStr = transition.cond - if (guardStr !== null) { - val gammaGuardExpression = conditionalLanguageParser - .parse(guardStr, new HashMap) - gammaTransition.guard = gammaGuardExpression - } + if (scxmlHistory.type == HistoryTypeDatatype.SHALLOW) { + val gammaShallowHistory = createShallowHistoryState => [ + it.name = getShallowHistoryName(scxmlHistory) + ] - traceability.put(transition, gammaTransition) + traceability.put(scxmlHistory, gammaShallowHistory) + return gammaShallowHistory + } + else { + val gammaDeepHistory = createDeepHistoryState => [ + it.name = getDeepHistoryName(scxmlHistory) + ] - return gammaTransition + traceability.put(scxmlHistory, gammaDeepHistory) + return gammaDeepHistory } + } + + protected def Transition transformTransition(ScxmlTransitionType transition) { + val sourceState = getTransitionSource(transition) + val targetId = transition.target.head - return null + val gammaSource = traceability.getStateNode(sourceState) + val gammaTarget = traceability.getStateNodeById(targetId) + + logger.log(Level.INFO, "Transforming transition" + gammaSource.name + " -> " + gammaTarget.name) + + val gammaTransition = gammaSource.createTransition(gammaTarget) + + val guardStr = transition.cond + if (guardStr !== null) { + val gammaGuardExpression = conditionalLanguageParser.parse(guardStr, new HashMap) + gammaTransition.guard = gammaGuardExpression + } + + traceability.put(transition, gammaTransition) + + return gammaTransition } } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index f936ff205..9f612c3e3 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -1,157 +1,218 @@ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlFinalType +import ac.soton.scxml.ScxmlHistoryType import ac.soton.scxml.ScxmlInitialType import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType +import hu.bme.mit.gamma.statechart.statechart.EntryState import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition import hu.bme.mit.gamma.util.GammaEcoreUtil import java.util.Map +import org.eclipse.emf.ecore.EObject import static com.google.common.base.Preconditions.checkNotNull +import hu.bme.mit.gamma.statechart.statechart.StateNode class Traceability { - + // Root element of the SCXML statechart model to transform. - // This Traceability class will be able to store multiple + // This Traceability class could be able to store multiple // ScxmlScxmlType - SynchronousStatechartDefinition pairs, but for now, // we assume only one SCMXL statechart to be transformed (from an root element). protected final ScxmlScxmlType scxmlRoot - + protected final Map statechartDefinitions = newHashMap protected final Map parallels = newHashMap protected final Map states = newHashMap protected final Map finals = newHashMap protected final Map initials = newHashMap + protected final Map historyStates = newHashMap protected final Map transitions = newHashMap - + protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE - + // - Synchronous Statechart Definition - new(ScxmlScxmlType scxmlRoot) { this.scxmlRoot = scxmlRoot } - + def getScxmlRoot() { return scxmlRoot } - + def put(ScxmlScxmlType scxmlRoot, SynchronousStatechartDefinition gammaStatechart) { checkNotNull(scxmlRoot) checkNotNull(gammaStatechart) statechartDefinitions += scxmlRoot -> gammaStatechart } - + def getStatechartDefinition(ScxmlScxmlType scxmlRoot) { checkNotNull(scxmlRoot) val gammaStatechart = statechartDefinitions.get(scxmlRoot) checkNotNull(gammaStatechart) return gammaStatechart } - + // - State (with orthogonal Region children) - def put(ScxmlParallelType scxmlParallel, State gammaParallel) { checkNotNull(scxmlParallel) checkNotNull(gammaParallel) parallels += scxmlParallel -> gammaParallel } - + def getParallel(ScxmlParallelType scxmlParallel) { checkNotNull(scxmlParallel) val gammaParallel = parallels.get(scxmlParallel) checkNotNull(gammaParallel) return gammaParallel } - + def getParallelById(String scxmlParallelId) { checkNotNull(scxmlParallelId) val keySet = states.keySet - val scxmlParallel = keySet.findFirst[parallel | parallel.id == scxmlParallelId] + val scxmlParallel = keySet.findFirst[parallel|parallel.id == scxmlParallelId] checkNotNull(scxmlParallel) return getState(scxmlParallel) } - + // - State (with a Region child if it is compound) - def put(ScxmlStateType scxmlState, State gammaState) { checkNotNull(scxmlState) checkNotNull(gammaState) states += scxmlState -> gammaState } - + def getState(ScxmlStateType scxmlState) { checkNotNull(scxmlState) val gammaState = states.get(scxmlState) checkNotNull(gammaState) return gammaState } - + def getStateById(String scxmlStateId) { checkNotNull(scxmlStateId) val keySet = states.keySet - val scxmlState = keySet.findFirst[state | state.id == scxmlStateId] + val scxmlState = keySet.findFirst[state|state.id == scxmlStateId] checkNotNull(scxmlState) return getState(scxmlState) } - + // - State - def put(ScxmlFinalType scxmlFinal, State gammaFinal) { checkNotNull(scxmlFinal) checkNotNull(gammaFinal) finals += scxmlFinal -> gammaFinal } - + def getFinalState(ScxmlFinalType scxmlFinal) { checkNotNull(scxmlFinal) val gammaFinal = finals.get(scxmlFinal) checkNotNull(gammaFinal) return gammaFinal } - + def getFinalById(String scxmlFinalId) { checkNotNull(scxmlFinalId) val keySet = finals.keySet - val scxmlFinal = keySet.findFirst[final | final.id == scxmlFinalId] + val scxmlFinal = keySet.findFirst[final|final.id == scxmlFinalId] checkNotNull(scxmlFinal) return getFinalState(scxmlFinal) } - + // - InitialState - def put(ScxmlInitialType scxmlInitial, InitialState gammaInitial) { checkNotNull(scxmlInitial) checkNotNull(gammaInitial) initials += scxmlInitial -> gammaInitial } - + def getInitialState(ScxmlInitialType scxmlInitial) { checkNotNull(scxmlInitial) val gammaInitial = initials.get(scxmlInitial) checkNotNull(gammaInitial) return gammaInitial } - + + // - ShallowHistoryState or DeepHistoryState (stored as an EntryState) + def put(ScxmlHistoryType scxmlHistory, EntryState gammaHistory) { + checkNotNull(scxmlHistory) + checkNotNull(gammaHistory) + historyStates += scxmlHistory -> gammaHistory + } + + def getHistoryState(ScxmlHistoryType scxmlHistory) { + checkNotNull(scxmlHistory) + val gammaHistory = historyStates.get(scxmlHistory) + checkNotNull(gammaHistory) + return gammaHistory + } + + def getHistoryStateById(String scxmlHistoryId) { + checkNotNull(scxmlHistoryId) + val keySet = historyStates.keySet + val scxmlHistory = keySet.findFirst[history|history.id == scxmlHistoryId] + checkNotNull(scxmlHistory) + return getHistoryState(scxmlHistory) + } + + // General functions returning a mapped Gamma StateNode + // Retrieves the mapped Gamma StateNode for an arbitrary transition source state + def getStateNode(EObject scxmlStateNode) { + val gammaState = states.get(scxmlStateNode) + if (gammaState !== null) { + return gammaState as StateNode; + } + val gammaParallel = parallels.get(scxmlStateNode) + if (gammaParallel !== null) { + return gammaParallel as StateNode; + } + val gammaInitial = initials.get(scxmlStateNode) + if (gammaInitial !== null) { + return gammaInitial as StateNode; + } + val gammaHistory = historyStates.get(scxmlStateNode) + checkNotNull(gammaHistory); + return gammaHistory as StateNode; + } + + // Retrieves the mapped Gamma StateNode for an arbitrary transition target state id + def getStateNodeById(String scxmlStateNodeId) { + val gammaState = states.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value + if (gammaState !== null) { + return gammaState + } + val gammaParallel = parallels.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value + if (gammaParallel !== null) { + return gammaParallel; + } + val gammaFinal = finals.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value + if (gammaFinal !== null) { + return gammaFinal; + } + val gammaHistory = historyStates.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value + checkNotNull(gammaHistory); + return gammaHistory; + + } + // - Transition - def put(ScxmlTransitionType scxmlTransition, Transition gammaTransition) { checkNotNull(scxmlTransition) checkNotNull(gammaTransition) transitions += scxmlTransition -> gammaTransition } - + def getTransition(ScxmlTransitionType scxmlTransition) { checkNotNull(scxmlTransition) val gammaTransition = transitions.get(scxmlTransition) checkNotNull(gammaTransition) return gammaTransition } - -} \ No newline at end of file + +} From 5e9a83e6505d31b8a77905c65681f34b4c7eeee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Wed, 30 Mar 2022 13:20:17 +0200 Subject: [PATCH 09/30] Remove unnecessary parser related classes --- .../parse/ConditionalLanguageParser.java | 65 +++++++++---------- .../parse/CustomLanguageScope.java | 21 ------ .../parse/CustomLanguageStandaloneSetup.java | 15 ----- .../parse/CustomRuntimeModule.java | 26 -------- 4 files changed, 30 insertions(+), 97 deletions(-) delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageScope.java delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageStandaloneSetup.java delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomRuntimeModule.java diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java index c51a7f9cf..add59501f 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java @@ -19,49 +19,44 @@ import hu.bme.mit.gamma.expression.model.OpaqueExpression; public class ConditionalLanguageParser { - + ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE; - //private Injector injector = new CustomLanguageStandaloneSetup() - // .createInjectorAndDoEMFRegistration(); - private Injector injector = new ExpressionLanguageStandaloneSetup() - .createInjectorAndDoEMFRegistration(); - + private Injector injector = new ExpressionLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); + public Expression parse(String expression, Map scope) { CustomLanguageParser parser = injector.getInstance(CustomLanguageParser.class); - StringReader reader = new StringReader(expression); - IParseResult result = parser.parse(reader); - - if (result.hasSyntaxErrors()) { - return createOpaqueExpression(expression); - } - - try { - for (INode node : result.getRootNode().getLeafNodes()) { - if (node.getGrammarElement() instanceof CrossReference) { - final DirectReferenceExpression refExpr = - (DirectReferenceExpression) node.getSemanticElement(); - - Declaration decl = scope.get(node.getText()); - if (decl != null) { - refExpr.setDeclaration(decl); - } else { - throw new NoSuchElementException(); - } - } - } - return (Expression) result.getRootASTElement(); - } - catch (NoSuchElementException e) { - } - - return createOpaqueExpression(expression); + StringReader reader = new StringReader(expression); + IParseResult result = parser.parse(reader); + + if (result.hasSyntaxErrors()) { + return createOpaqueExpression(expression); + } + + try { + for (INode node : result.getRootNode().getLeafNodes()) { + if (node.getGrammarElement() instanceof CrossReference) { + final DirectReferenceExpression refExpr = (DirectReferenceExpression) node.getSemanticElement(); + + Declaration decl = scope.get(node.getText()); + if (decl != null) { + refExpr.setDeclaration(decl); + } else { + throw new NoSuchElementException(); + } + } + } + return (Expression) result.getRootASTElement(); + } catch (NoSuchElementException e) { + } + + return createOpaqueExpression(expression); } - + private Expression createOpaqueExpression(String expression) { OpaqueExpression opaqueExpression = expressionModelFactory.createOpaqueExpression(); opaqueExpression.setExpression(expression); return opaqueExpression; } - + } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageScope.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageScope.java deleted file mode 100644 index 6a77617da..000000000 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageScope.java +++ /dev/null @@ -1,21 +0,0 @@ -package hu.bme.mit.gamma.scxml.transformation.parse; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.xtext.scoping.IScope; - -import hu.bme.mit.gamma.expression.language.scoping.ExpressionLanguageScopeProvider; - -public class CustomLanguageScope extends ExpressionLanguageScopeProvider { - - @Override - public IScope getScope(EObject context, EReference reference) { - return super.getScope(context, reference); - } - - @Override - protected IScope delegateGetScope(EObject context, EReference reference) { - return super.delegateGetScope(context, reference); - } - -} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageStandaloneSetup.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageStandaloneSetup.java deleted file mode 100644 index a1182ae27..000000000 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageStandaloneSetup.java +++ /dev/null @@ -1,15 +0,0 @@ -package hu.bme.mit.gamma.scxml.transformation.parse; - -import com.google.inject.Guice; -import com.google.inject.Injector; - -import hu.bme.mit.gamma.expression.language.ExpressionLanguageStandaloneSetup; - -public class CustomLanguageStandaloneSetup extends ExpressionLanguageStandaloneSetup { - - @Override - public Injector createInjector() { - return Guice.createInjector(new CustomRuntimeModule()); - } - -} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomRuntimeModule.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomRuntimeModule.java deleted file mode 100644 index 348748ba1..000000000 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomRuntimeModule.java +++ /dev/null @@ -1,26 +0,0 @@ -package hu.bme.mit.gamma.scxml.transformation.parse; - -import org.eclipse.xtext.parser.IParser; -import org.eclipse.xtext.scoping.IScopeProvider; -import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; - -import com.google.inject.Binder; -import com.google.inject.name.Names; - -import hu.bme.mit.gamma.expression.language.ExpressionLanguageRuntimeModule; - -public class CustomRuntimeModule extends ExpressionLanguageRuntimeModule { - - @Override - public Class bindIParser() { - return CustomLanguageParser.class; - } - - @Override - public void configureIScopeProviderDelegate(Binder binder) { - binder.bind(IScopeProvider.class) - .annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)) - .to(CustomLanguageScope.class); - } - -} From 87626c2bbe1665ed93633f670de3b30553157dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Fri, 8 Apr 2022 14:16:27 +0200 Subject: [PATCH 10/30] Add variable transformation in Scxml root node --- .../transformation/AbstractTransformer.xtend | 14 +++- .../transformation/ActionTransformer.xtend | 81 +++++++++++++++++++ .../transformation/DataTransformer.xtend | 28 +++++++ .../ScxmlGammaExpressionTransformer.xtend | 9 +++ .../ScxmlToGammaStatechartTransformer.xtend | 69 +++++++++++++++- .../scxml/transformation/Traceability.xtend | 57 ++++++++++--- ...> ScxmlGammaExpressionLanguageParser.java} | 11 ++- ...ser.java => ScxmlGammaLanguageParser.java} | 2 +- 8 files changed, 249 insertions(+), 22 deletions(-) create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend rename plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/{ConditionalLanguageParser.java => ScxmlGammaExpressionLanguageParser.java} (81%) rename plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/{CustomLanguageParser.java => ScxmlGammaLanguageParser.java} (79%) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend index 1eb81828f..a724986f3 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend @@ -1,11 +1,16 @@ package hu.bme.mit.gamma.scxml.transformation -import hu.bme.mit.gamma.scxml.transformation.parse.ConditionalLanguageParser +import hu.bme.mit.gamma.action.model.ActionModelFactory +import hu.bme.mit.gamma.action.util.ActionUtil +import hu.bme.mit.gamma.expression.model.ExpressionModelFactory +import hu.bme.mit.gamma.expression.util.ExpressionTypeDeterminator2 +import hu.bme.mit.gamma.expression.util.ExpressionUtil import hu.bme.mit.gamma.statechart.interface_.InterfaceModelFactory import hu.bme.mit.gamma.statechart.statechart.StatechartModelFactory import hu.bme.mit.gamma.statechart.util.StatechartUtil import hu.bme.mit.gamma.util.GammaEcoreUtil import java.util.logging.Logger +import hu.bme.mit.gamma.scxml.transformation.parse.ScxmlGammaExpressionLanguageParser abstract class AbstractTransformer { @@ -13,11 +18,16 @@ abstract class AbstractTransformer { protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE protected final extension StatechartUtil statechartUtil = StatechartUtil.INSTANCE + protected final extension ActionUtil actionUtil = ActionUtil.INSTANCE + protected final extension ExpressionUtil expressionUtil = ExpressionUtil.INSTANCE protected final extension InterfaceModelFactory interfaceModelFactory = InterfaceModelFactory.eINSTANCE protected final extension StatechartModelFactory statechartModelFactory = StatechartModelFactory.eINSTANCE + protected final extension ActionModelFactory actionModelFactory = ActionModelFactory.eINSTANCE + protected final extension ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE - protected final ConditionalLanguageParser conditionalLanguageParser = new ConditionalLanguageParser() + protected final ScxmlGammaExpressionLanguageParser expressionLanguageParser = new ScxmlGammaExpressionLanguageParser() + protected final ExpressionTypeDeterminator2 expressionTypeDeterminator = ExpressionTypeDeterminator2.INSTANCE protected final Logger logger = Logger.getLogger("GammaLogger") diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend new file mode 100644 index 000000000..a0ac127ab --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -0,0 +1,81 @@ +package hu.bme.mit.gamma.scxml.transformation + +import ac.soton.scxml.ScxmlAssignType +import ac.soton.scxml.ScxmlIfType +import ac.soton.scxml.ScxmlOnentryType +import ac.soton.scxml.ScxmlOnexitType +import hu.bme.mit.gamma.action.model.Action +import hu.bme.mit.gamma.expression.model.VariableDeclaration +import java.util.logging.Level +import org.eclipse.emf.ecore.EObject + +class ActionTransformer extends AbstractTransformer { + + protected final extension ScxmlGammaExpressionTransformer expressionTransformer + + new(Traceability traceability) { + super(traceability) + + this.expressionTransformer = new ScxmlGammaExpressionTransformer(traceability) + } + + def Action transform(ScxmlOnentryType scxmlOnentry) { + logger.log(Level.INFO, "Transforming element (" + scxmlOnentry + ")") + + // TODO Get list of all children actions, not just -s + val scxmlActions = scxmlOnentry.assign + val gammaEntryAction = scxmlActions.transformBlock; // TODO + + return gammaEntryAction + } + + def Action transform(ScxmlOnexitType scxmlOnexit) { + logger.log(Level.INFO, "Transforming element (" + scxmlOnexit + ")") + + // TODO Get list of all children actions, not just -s + val scxmlActions = scxmlOnexit.assign + val gammaExitAction = scxmlActions.transformBlock; // TODO + + return gammaExitAction + } + + def dispatch Action transformAction(ScxmlAssignType scxmlAssign) { + logger.log(Level.INFO, "Transforming element (" + scxmlAssign + ")") + + val varLoc = scxmlAssign.location + val variable = traceability.getVariable(varLoc) + + val expr = scxmlAssign.expr + if (expr !== null) { + val expression = expressionLanguageParser.parse(expr, traceability.variables) + val gammaAssign = actionUtil.createAssignment(variable as VariableDeclaration, expression) + return gammaAssign + } + + // TODO Assignment by child content if expr is not present + val gammaAssign = createEmptyStatement + + return gammaAssign + } + + def dispatch Action transformAction(ScxmlIfType scxmlIf) { + logger.log(Level.INFO, "Transforming element (" + scxmlIf + ")") + + // TODO + val gammaIf = createEmptyStatement + + return gammaIf + } + + def Action transformBlock(Iterable actions) { + if (actions.empty) { + return createBlock + } + + val gammaActions = actions.map[it.transformAction].toList + val gammaBlock = actionUtil.wrap(gammaActions) + + return gammaBlock + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend new file mode 100644 index 000000000..01b00ea2f --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend @@ -0,0 +1,28 @@ +package hu.bme.mit.gamma.scxml.transformation + +import ac.soton.scxml.ScxmlDataType +import hu.bme.mit.gamma.expression.model.VariableDeclaration +import java.util.logging.Level + +class DataTransformer extends AbstractTransformer { + + new(Traceability traceability) { + super(traceability) + } + + def VariableDeclaration transform(ScxmlDataType scxmlData) { + logger.log(Level.INFO, "Transforming element (" + scxmlData + ")") + + val id = scxmlData.id + val expr = scxmlData.expr + val expression = expressionLanguageParser.parse(expr, traceability.variables) + val type = expressionTypeDeterminator.getType(expression) + + val gammaDeclaration = expressionUtil.createVariableDeclaration(type, id, expression); + + traceability.put(scxmlData, gammaDeclaration) + + return gammaDeclaration + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend new file mode 100644 index 000000000..ca5de03bc --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend @@ -0,0 +1,9 @@ +package hu.bme.mit.gamma.scxml.transformation + +class ScxmlGammaExpressionTransformer extends AbstractTransformer { + + new(Traceability traceability) { + super(traceability) + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 0a66bd9f1..a3af11904 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -13,14 +13,19 @@ import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition -import java.util.HashMap import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* +// 1. Variable transformation and assignment, scoping +// 2. History, parallel +// 3. Event, port, trigger, ... class ScxmlToGammaStatechartTransformer extends AbstractTransformer { + protected final extension ActionTransformer actionTransformer + protected final extension DataTransformer dataTransformer + // Root element of the SCXML statechart model to transform protected final ScxmlScxmlType scxmlRoot @@ -40,6 +45,9 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { this.gammaStatechart = createSynchronousStatechartDefinition => [ it.name = getStatechartName(scxmlRoot) ] + + this.actionTransformer = new ActionTransformer(traceability) + this.dataTransformer = new DataTransformer(traceability) } // Transformation of the SCXML root element and its contents recursively @@ -48,6 +56,18 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { logger.log(Level.INFO, "Transforming root element (" + scxmlRoot.name + ")") + val datamodels = scxmlRoot.datamodel + if (datamodels !== null) { + val datamodel = datamodels.head + if (datamodel !== null) { + val dataElements = getDataElements(datamodel) + for (data : dataElements) { + val gammaVariableDeclaration = dataTransformer.transform(data) + gammaStatechart.variableDeclarations += gammaVariableDeclaration + } + } + } + val mainRegion = createRegion => [ it.name = getRegionName(scxmlRoot.name) ] @@ -132,11 +152,24 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { } // TODO Transform history pseudo-states (by adding a wrapper compound state perhaps) + // Initial-ok kicserélése a gyerek state-ekben, amely parallelekben találok historyt + // Vagy history node hozzáadása minden gyerek régióhoz, ha van kívül history ?? /*val scxmlHistoryStates = parallelNode.history for (scxmlHistoryState : scxmlHistoryStates) { }*/ + // Transform onentry and onexit handlers + val onentryActions = parallelNode.onentry + for (onentryAction : onentryActions) { + gammaParallel.entryActions += onentryAction.transformAction + } + + val onexitActions = parallelNode.onexit + for (onexitAction : onexitActions) { + gammaParallel.exitActions += onexitAction.transformAction + } + traceability.put(parallelNode, gammaParallel) return gammaParallel @@ -204,6 +237,17 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { for (scxmlHistoryState : scxmlHistoryStates) { region.stateNodes += scxmlHistoryState.transform } + + // Transform onentry and onexit handlers + val onentryActions = scxmlState.onentry + for (onentryAction : onentryActions) { + gammaState.entryActions += onentryAction.transform + } + + val onexitActions = scxmlState.onexit + for (onexitAction : onexitActions) { + gammaState.exitActions += onexitAction.transform + } } traceability.put(scxmlState, gammaState) @@ -218,6 +262,17 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { it.name = getFinalName(scxmlFinal) ] + // Transform onentry and onexit handlers + val onentryActions = scxmlFinal.onentry + for (onentryAction : onentryActions) { + gammaFinal.entryActions += onentryAction.transformAction + } + + val onexitActions = scxmlFinal.onexit + for (onexitAction : onexitActions) { + gammaFinal.exitActions += onexitAction.transformAction + } + traceability.put(scxmlFinal, gammaFinal) return gammaFinal @@ -267,12 +322,20 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { logger.log(Level.INFO, "Transforming transition" + gammaSource.name + " -> " + gammaTarget.name) val gammaTransition = gammaSource.createTransition(gammaTarget) - + + val eventName = transition.event // TODO transform event trigger + // TODO EventTrigger, portok, etc. + val guardStr = transition.cond if (guardStr !== null) { - val gammaGuardExpression = conditionalLanguageParser.parse(guardStr, new HashMap) + val gammaGuardExpression = expressionLanguageParser.parse(guardStr, traceability.variables) gammaTransition.guard = gammaGuardExpression } + + val effects = transition.assign // TODO Get all children actions + gammaTransition.effects += effects.transformBlock + + // TODO throw exception when an internal transition encounter, not supported traceability.put(transition, gammaTransition) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index 9f612c3e3..08b6ebf05 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -1,5 +1,6 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.ScxmlDataType import ac.soton.scxml.ScxmlFinalType import ac.soton.scxml.ScxmlHistoryType import ac.soton.scxml.ScxmlInitialType @@ -7,9 +8,12 @@ import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType +import hu.bme.mit.gamma.expression.model.Declaration +import hu.bme.mit.gamma.expression.model.VariableDeclaration import hu.bme.mit.gamma.statechart.statechart.EntryState import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State +import hu.bme.mit.gamma.statechart.statechart.StateNode import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition import hu.bme.mit.gamma.util.GammaEcoreUtil @@ -17,7 +21,6 @@ import java.util.Map import org.eclipse.emf.ecore.EObject import static com.google.common.base.Preconditions.checkNotNull -import hu.bme.mit.gamma.statechart.statechart.StateNode class Traceability { @@ -34,6 +37,9 @@ class Traceability { protected final Map initials = newHashMap protected final Map historyStates = newHashMap protected final Map transitions = newHashMap + + protected final Map dataElements = newHashMap + protected final Map variables = newHashMap protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE @@ -164,21 +170,22 @@ class Traceability { // General functions returning a mapped Gamma StateNode // Retrieves the mapped Gamma StateNode for an arbitrary transition source state def getStateNode(EObject scxmlStateNode) { + // TODO StateNode that check type is appropriate val gammaState = states.get(scxmlStateNode) if (gammaState !== null) { - return gammaState as StateNode; + return gammaState as StateNode } val gammaParallel = parallels.get(scxmlStateNode) if (gammaParallel !== null) { - return gammaParallel as StateNode; + return gammaParallel as StateNode } val gammaInitial = initials.get(scxmlStateNode) if (gammaInitial !== null) { - return gammaInitial as StateNode; + return gammaInitial as StateNode } val gammaHistory = historyStates.get(scxmlStateNode) - checkNotNull(gammaHistory); - return gammaHistory as StateNode; + checkNotNull(gammaHistory) + return gammaHistory as StateNode } // Retrieves the mapped Gamma StateNode for an arbitrary transition target state id @@ -189,15 +196,15 @@ class Traceability { } val gammaParallel = parallels.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value if (gammaParallel !== null) { - return gammaParallel; + return gammaParallel } val gammaFinal = finals.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value if (gammaFinal !== null) { - return gammaFinal; + return gammaFinal } val gammaHistory = historyStates.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value - checkNotNull(gammaHistory); - return gammaHistory; + checkNotNull(gammaHistory) + return gammaHistory } @@ -214,5 +221,35 @@ class Traceability { checkNotNull(gammaTransition) return gammaTransition } + + // - VariableDeclaration + def put(ScxmlDataType scxmlData, VariableDeclaration gammaDeclaration) { + checkNotNull(scxmlData) + checkNotNull(gammaDeclaration) + dataElements += scxmlData -> gammaDeclaration + + put(scxmlData.id, gammaDeclaration) + } + + def getVariable(ScxmlDataType scxmlData) { + checkNotNull(scxmlData) + val gammaDeclaration = dataElements.get(scxmlData) + checkNotNull(gammaDeclaration) + return gammaDeclaration + } + + // Variable Declarations by String identifier + private def put(String scxmlVariableName, VariableDeclaration gammaDeclaration) { + checkNotNull(scxmlVariableName) + checkNotNull(gammaDeclaration) + variables += scxmlVariableName -> gammaDeclaration + } + + def getVariable(String scxmlVariableName) { + checkNotNull(scxmlVariableName) + val gammaDeclaration = variables.get(scxmlVariableName) + checkNotNull(gammaDeclaration) + return gammaDeclaration + } } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java similarity index 81% rename from plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java rename to plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java index add59501f..8d36c6019 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ConditionalLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java @@ -11,21 +11,20 @@ import com.google.inject.Injector; import hu.bme.mit.gamma.expression.language.ExpressionLanguageStandaloneSetup; -import hu.bme.mit.gamma.expression.language.parser.antlr.ExpressionLanguageParser; -import hu.bme.mit.gamma.expression.model.Declaration; import hu.bme.mit.gamma.expression.model.DirectReferenceExpression; import hu.bme.mit.gamma.expression.model.Expression; import hu.bme.mit.gamma.expression.model.ExpressionModelFactory; import hu.bme.mit.gamma.expression.model.OpaqueExpression; +import hu.bme.mit.gamma.expression.model.VariableDeclaration; -public class ConditionalLanguageParser { +public class ScxmlGammaExpressionLanguageParser { ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE; private Injector injector = new ExpressionLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); - public Expression parse(String expression, Map scope) { - CustomLanguageParser parser = injector.getInstance(CustomLanguageParser.class); + public Expression parse(String expression, Map scope) { + ScxmlGammaLanguageParser parser = injector.getInstance(ScxmlGammaLanguageParser.class); StringReader reader = new StringReader(expression); IParseResult result = parser.parse(reader); @@ -38,7 +37,7 @@ public Expression parse(String expression, Map scope) { if (node.getGrammarElement() instanceof CrossReference) { final DirectReferenceExpression refExpr = (DirectReferenceExpression) node.getSemanticElement(); - Declaration decl = scope.get(node.getText()); + VariableDeclaration decl = scope.get(node.getText()); if (decl != null) { refExpr.setDeclaration(decl); } else { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java similarity index 79% rename from plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java rename to plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java index 155533d37..4e188c984 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/CustomLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java @@ -2,7 +2,7 @@ import hu.bme.mit.gamma.expression.language.parser.antlr.ExpressionLanguageParser; -public class CustomLanguageParser extends ExpressionLanguageParser { +public class ScxmlGammaLanguageParser extends ExpressionLanguageParser { // Set default rule to "Expression" from "ExpressionPackage" @Override From 84b75ba1ad549396a47222e18191a8099dfee13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Fri, 22 Apr 2022 15:39:44 +0200 Subject: [PATCH 11/30] Add fixes and todo comments --- .../commandhandler/CommandHandler.java | 25 +++++-- .../ScxmlToGammaStatechartTransformer.xtend | 66 +++++++++++++++++-- .../scxml/transformation/Traceability.xtend | 23 +++++++ .../ScxmlGammaExpressionLanguageParser.java | 4 +- .../parse/ScxmlGammaLanguageParser.java | 1 + 5 files changed, 109 insertions(+), 10 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 0d44da0ee..ce13833e9 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -11,16 +11,15 @@ import org.eclipse.core.resources.IFile; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.handlers.HandlerUtil; -import ac.soton.scxml.DocumentRoot; import ac.soton.scxml.ScxmlScxmlType; import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaStatechartTransformer; import hu.bme.mit.gamma.scxml.transformation.Traceability; +import hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures; +import hu.bme.mit.gamma.statechart.interface_.Interface; import hu.bme.mit.gamma.statechart.interface_.Package; import hu.bme.mit.gamma.statechart.language.ui.serializer.StatechartLanguageSerializer; import hu.bme.mit.gamma.statechart.statechart.StatechartDefinition; @@ -56,16 +55,32 @@ public Object execute(ExecutionEvent event) throws ExecutionException { EObject object = ecoreUtil.normalLoad(fileURI); ScxmlScxmlType scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(object, ScxmlScxmlType.class); + + // Model processing ScxmlToGammaStatechartTransformer statechartTransformer = new ScxmlToGammaStatechartTransformer(scxmlRoot); Traceability traceability = statechartTransformer.execute(); + + // Interfaces and type declarations have to be explicitly serialized in another package + Interface gammaInterface = traceability.getDefaultInterface(); + Package gammaInterfacePackage = statechartUtil.wrapIntoPackage(gammaInterface); + + // TODO issue wrapIntoPackageAndAddImports StatechartDefinition statechartDefinition = traceability.getStatechartDefinition(scxmlRoot); Package gammaComponentPackage = statechartUtil.wrapIntoPackage(statechartDefinition); + gammaComponentPackage.getImports().addAll( + StatechartModelDerivedFeatures.getImportablePackages(statechartDefinition)); + gammaComponentPackage.getImports().remove(gammaComponentPackage); StatechartLanguageSerializer packageSerializer = new StatechartLanguageSerializer(); - logger.log(Level.INFO, "Start serializing Gamma package..."); - String componentPackageFileName = extensionlessFileName + "Transformed.gcd"; + logger.log(Level.INFO, "Start serializing Gamma packages..."); + + String declarationsPackageFileName = extensionlessFileName + "Declarations.gcd"; + packageSerializer.serialize(gammaInterfacePackage, parentPath, declarationsPackageFileName); + + String componentPackageFileName = extensionlessFileName + ".gcd"; packageSerializer.serialize(gammaComponentPackage, parentPath, componentPackageFileName); + logger.log(Level.INFO, "The SCXML - Gamma statechart transformation has finished."); } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index a3af11904..f08e2b99b 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -17,10 +17,22 @@ import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* +import hu.bme.mit.gamma.statechart.interface_.RealizationMode +import hu.bme.mit.gamma.statechart.interface_.EventDirection // 1. Variable transformation and assignment, scoping // 2. History, parallel -// 3. Event, port, trigger, ... + +// TODO pull fresh gamma/dev + +// TODO 3. Event, port, trigger, ... +// Jövő héten pull-olom a GitHubon a forkba a gamma/dev-et, utána pull és újragenerálás +/* 1. step: Default implicit port and interface for (every) statechart -> trace, + * actions will send events to this port, too + * + * 2. step: x.aabb ~ x port's interface's aabb event e.g. + * Szétválasztani a be- és kimenő portokat+interfészeket + */ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { protected final extension ActionTransformer actionTransformer @@ -54,6 +66,9 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { def execute() { traceability.put(scxmlRoot, gammaStatechart) + createDefaultPortAndInterface() + gammaStatechart.ports += traceability.defaultPort + logger.log(Level.INFO, "Transforming root element (" + scxmlRoot.name + ")") val datamodels = scxmlRoot.datamodel @@ -265,6 +280,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Transform onentry and onexit handlers val onentryActions = scxmlFinal.onentry for (onentryAction : onentryActions) { + // TODO Handle nulls gammaFinal.entryActions += onentryAction.transformAction } @@ -323,11 +339,32 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val gammaTransition = gammaSource.createTransition(gammaTarget) - val eventName = transition.event // TODO transform event trigger - // TODO EventTrigger, portok, etc. + // Transform event trigger + // TODO extract methods into proper classes + val eventName = transition.event + + val event = createEvent + event.name = eventName + + // TODO getOrTransform + val eventDeclaration = createEventDeclaration + eventDeclaration.event = event + eventDeclaration.direction = EventDirection.IN + traceability.defaultInterface.events += eventDeclaration + val eventReference = createPortEventReference + eventReference.event = event + eventReference.port = traceability.defaultPort + + val eventTrigger = createEventTrigger + eventTrigger.eventReference = eventReference + gammaTransition.trigger = eventTrigger + + // + + // Check nullOrEmpty val guardStr = transition.cond - if (guardStr !== null) { + if (!guardStr.nullOrEmpty) { val gammaGuardExpression = expressionLanguageParser.parse(guardStr, traceability.variables) gammaTransition.guard = gammaGuardExpression } @@ -342,4 +379,25 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { return gammaTransition } + // TODO event name = port.interface.event ?? split + // e.g. event (1) on default port / port.event (2) / port.interface.event (3) options + // Create event, port and triggertransformer + // Create default port (check at the end not to be used by the user), and interface + // raise event actions + private def createDefaultPortAndInterface() { + val defaultInterface = createInterface + defaultInterface.name = "DefaultInterface1" + + val defaultInterfaceRealization = createInterfaceRealization + defaultInterfaceRealization.realizationMode = RealizationMode.PROVIDED + defaultInterfaceRealization.interface = defaultInterface + + val defaultPort = createPort + defaultPort.name = "DefaultPort" + defaultPort.interfaceRealization = defaultInterfaceRealization + + traceability.defaultInterface = defaultInterface + traceability.defaultPort = defaultPort + } + } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index 08b6ebf05..8f3b29d9b 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -10,6 +10,8 @@ import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType import hu.bme.mit.gamma.expression.model.Declaration import hu.bme.mit.gamma.expression.model.VariableDeclaration +import hu.bme.mit.gamma.statechart.interface_.Interface +import hu.bme.mit.gamma.statechart.interface_.Port import hu.bme.mit.gamma.statechart.statechart.EntryState import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State @@ -39,9 +41,14 @@ class Traceability { protected final Map transitions = newHashMap protected final Map dataElements = newHashMap + + // Works only if variables are globally unique and have a global scope protected final Map variables = newHashMap protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE + + protected Port defaultPort + protected Interface defaultInterface // - Synchronous Statechart Definition new(ScxmlScxmlType scxmlRoot) { @@ -222,6 +229,22 @@ class Traceability { return gammaTransition } + def getDefaultInterface() { + return defaultInterface + } + + def setDefaultInterface(Interface defaultInterface) { + this.defaultInterface = defaultInterface + } + + def getDefaultPort() { + return defaultPort + } + + def setDefaultPort(Port defaultPort) { + this.defaultPort = defaultPort + } + // - VariableDeclaration def put(ScxmlDataType scxmlData, VariableDeclaration gammaDeclaration) { checkNotNull(scxmlData) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java index 8d36c6019..7fb9f42aa 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java @@ -17,12 +17,14 @@ import hu.bme.mit.gamma.expression.model.OpaqueExpression; import hu.bme.mit.gamma.expression.model.VariableDeclaration; +// TODO rename, e.g. Custom... public class ScxmlGammaExpressionLanguageParser { ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE; private Injector injector = new ExpressionLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); - + + // Works only if variables in the scope are globally unique and have a global scope public Expression parse(String expression, Map scope) { ScxmlGammaLanguageParser parser = injector.getInstance(ScxmlGammaLanguageParser.class); StringReader reader = new StringReader(expression); diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java index 4e188c984..ca16b84fa 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java @@ -2,6 +2,7 @@ import hu.bme.mit.gamma.expression.language.parser.antlr.ExpressionLanguageParser; +// TODO rename public class ScxmlGammaLanguageParser extends ExpressionLanguageParser { // Set default rule to "Expression" from "ExpressionPackage" From 98f2389a63349660b54b6d44dc7b922696a51cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Tue, 3 May 2022 14:52:24 +0200 Subject: [PATCH 12/30] Introduce port and event transformers --- .../commandhandler/CommandHandler.java | 9 +- .../transformation/EventTransformer.xtend | 59 +++++++ .../gamma/scxml/transformation/Namings.xtend | 7 + .../transformation/PortTransformer.xtend | 43 +++++ .../ScxmlToGammaStatechartTransformer.xtend | 70 ++++---- .../scxml/transformation/Traceability.xtend | 152 ++++++++++++++++-- .../transformation/TriggerTransformer.xtend | 48 ++++++ 7 files changed, 323 insertions(+), 65 deletions(-) create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index ce13833e9..36596b6f2 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -55,8 +55,6 @@ public Object execute(ExecutionEvent event) throws ExecutionException { EObject object = ecoreUtil.normalLoad(fileURI); ScxmlScxmlType scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(object, ScxmlScxmlType.class); - - // Model processing ScxmlToGammaStatechartTransformer statechartTransformer = new ScxmlToGammaStatechartTransformer(scxmlRoot); Traceability traceability = statechartTransformer.execute(); @@ -64,13 +62,10 @@ public Object execute(ExecutionEvent event) throws ExecutionException { // Interfaces and type declarations have to be explicitly serialized in another package Interface gammaInterface = traceability.getDefaultInterface(); Package gammaInterfacePackage = statechartUtil.wrapIntoPackage(gammaInterface); + gammaInterfacePackage.getInterfaces().addAll(traceability.getInterfaces().values()); - // TODO issue wrapIntoPackageAndAddImports StatechartDefinition statechartDefinition = traceability.getStatechartDefinition(scxmlRoot); - Package gammaComponentPackage = statechartUtil.wrapIntoPackage(statechartDefinition); - gammaComponentPackage.getImports().addAll( - StatechartModelDerivedFeatures.getImportablePackages(statechartDefinition)); - gammaComponentPackage.getImports().remove(gammaComponentPackage); + Package gammaComponentPackage = statechartUtil.wrapIntoPackageAndAddImports(statechartDefinition); StatechartLanguageSerializer packageSerializer = new StatechartLanguageSerializer(); logger.log(Level.INFO, "Start serializing Gamma packages..."); diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend new file mode 100644 index 000000000..91a362cb5 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend @@ -0,0 +1,59 @@ +package hu.bme.mit.gamma.scxml.transformation + +import hu.bme.mit.gamma.statechart.interface_.EventDirection + +import static hu.bme.mit.gamma.scxml.transformation.Namings.* +import hu.bme.mit.gamma.statechart.interface_.Port + +class EventTransformer extends AbstractTransformer { + new(Traceability traceability) { + super(traceability) + } + + def getOrTransformInEvent(Port gammaPort, String eventName) { + if (traceability.containsInEvent(gammaPort -> eventName)) { + return traceability.getInEvent(gammaPort -> eventName) + } + else { + return transformInEvent(gammaPort, eventName) + } + } + + protected def transformInEvent(Port gammaPort, String eventName) { + val gammaEvent = transformEvent(gammaPort, EventDirection.IN, eventName) + gammaEvent.name = getInEventName(eventName) + traceability.putInEvent(gammaPort -> eventName, gammaEvent) + return gammaEvent + } + + def getOrTransformOutEvent(Port gammaPort, String eventName) { + if (traceability.containsOutEvent(gammaPort -> eventName)) { + return traceability.getOutEvent(gammaPort -> eventName) + } + else { + return transformOutEvent(gammaPort, eventName) + } + } + + protected def transformOutEvent(Port gammaPort, String eventName) { + val gammaEvent = transformEvent(gammaPort, EventDirection.OUT, eventName) + gammaEvent.name = getOutEventName(eventName) + traceability.putOutEvent(gammaPort -> eventName, gammaEvent) + return gammaEvent + } + + // This method assumes that the transformation of the port and interface of the respecting event + // has already happened when we transform the event. + private def transformEvent(Port gammaPort, EventDirection direction, String eventName) { + val gammaEvent = createEvent + val gammaEventDeclaration = createEventDeclaration + gammaEventDeclaration.event = gammaEvent + gammaEventDeclaration.direction = direction + + val gammaInterface = gammaPort.interfaceRealization.interface + gammaInterface.events += gammaEventDeclaration + + return gammaEvent + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index 53a6f28fd..08e539509 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -8,11 +8,18 @@ import ac.soton.scxml.ScxmlStateType class Namings { + def static String getInterfaceName(String scxmlPortName) '''«scxmlPortName»_Interface''' + def static String getPortName(String scxmlPortName) '''«scxmlPortName»''' + def static String getInEventName(String scxmlEventName) '''in_«scxmlEventName»''' + def static String getOutEventName(String scxmlEventName) '''out_«scxmlEventName»''' + def static String getStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' def static String getRegionName(String scxmlElementName) '''«scxmlElementName»Region''' + def static String getParallelName(ScxmlParallelType scxmlParallel) '''«scxmlParallel.id»''' def static String getStateName(ScxmlStateType scxmlState) '''«scxmlState.id»''' def static String getFinalName(ScxmlFinalType scxmlFinal) '''«scxmlFinal.id»''' + def static String getInitialName(ScxmlStateType scxmlParentState) '''«scxmlParentState.id»Initial''' def static String getInitialName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»Initial''' def static String getShallowHistoryName(ScxmlHistoryType scxmlHistoryState) '''«scxmlHistoryState.id»ShallowHistory''' diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend new file mode 100644 index 000000000..fb5bc4921 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend @@ -0,0 +1,43 @@ +package hu.bme.mit.gamma.scxml.transformation + +import hu.bme.mit.gamma.statechart.interface_.RealizationMode + +import static com.google.common.base.Preconditions.checkState +import static hu.bme.mit.gamma.scxml.transformation.Namings.* + +class PortTransformer extends AbstractTransformer { + new(Traceability traceability) { + super(traceability) + } + + def getOrTransformPortByName(String portName) { + checkState(portName !== null) + if (traceability.containsPort(portName)) { + return traceability.getPort(portName) + } + else { + val gammaPort = transformPortByName(portName) + return gammaPort + } + } + + // For now, different ports realize different interfaces. + protected def transformPortByName(String portName) { + val gammaInterface = createInterface + val gammaInterfaceName = getInterfaceName(portName) + gammaInterface.name = gammaInterfaceName + traceability.putInterface(gammaInterfaceName, gammaInterface) + + val gammaInterfaceRealization = createInterfaceRealization + gammaInterfaceRealization.realizationMode = RealizationMode.PROVIDED + gammaInterfaceRealization.interface = gammaInterface + + val gammaPort = createPort + gammaPort.name = getPortName(portName) + gammaPort.interfaceRealization = gammaInterfaceRealization + traceability.putPort(portName, gammaPort) + + return gammaPort + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index f08e2b99b..b80160473 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -8,6 +8,8 @@ import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType +import ac.soton.scxml.TransitionTypeDatatype +import hu.bme.mit.gamma.statechart.interface_.RealizationMode import hu.bme.mit.gamma.statechart.statechart.EntryState import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State @@ -17,26 +19,27 @@ import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* -import hu.bme.mit.gamma.statechart.interface_.RealizationMode -import hu.bme.mit.gamma.statechart.interface_.EventDirection -// 1. Variable transformation and assignment, scoping -// 2. History, parallel +// Scoping in variable transformation and assignment +// TODO History, parallel + +// TODO Events, ports, triggers, ... +// port.interface.event ~ port's interface's event split +// event (1) on default port / interface.event (2) / port.interface.event (3) options +// default port for each interface +// TODO raise event actions + +// TODO docs +// TODO scxml support (wiki, MagicDraw, RationalRhapsody etc.) -// TODO pull fresh gamma/dev +// Create event, port and triggertransformer +// Create default port (check at the end not to be used by the user), and interface -// TODO 3. Event, port, trigger, ... -// Jövő héten pull-olom a GitHubon a forkba a gamma/dev-et, utána pull és újragenerálás -/* 1. step: Default implicit port and interface for (every) statechart -> trace, - * actions will send events to this port, too - * - * 2. step: x.aabb ~ x port's interface's aabb event e.g. - * Szétválasztani a be- és kimenő portokat+interfészeket - */ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { protected final extension ActionTransformer actionTransformer protected final extension DataTransformer dataTransformer + protected final extension TriggerTransformer triggerTransformer // Root element of the SCXML statechart model to transform protected final ScxmlScxmlType scxmlRoot @@ -60,6 +63,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { this.actionTransformer = new ActionTransformer(traceability) this.dataTransformer = new DataTransformer(traceability) + this.triggerTransformer = new TriggerTransformer(traceability) } // Transformation of the SCXML root element and its contents recursively @@ -131,6 +135,10 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { gammaInitial.createTransition(gammaInitialTarget) } + // Add all ports from traceability + gammaStatechart.ports += traceability.ports.values + // + return traceability } @@ -328,7 +336,13 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { } } + // Internal transitions are not supported by the transformer. protected def Transition transformTransition(ScxmlTransitionType transition) { + if (transition.type == TransitionTypeDatatype.INTERNAL) { + throw new IllegalArgumentException( + "Transforming internal transition " + transition + " is not supported.") + } + val sourceState = getTransitionSource(transition) val targetId = transition.target.head @@ -340,29 +354,10 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val gammaTransition = gammaSource.createTransition(gammaTarget) // Transform event trigger - // TODO extract methods into proper classes val eventName = transition.event - - val event = createEvent - event.name = eventName - - // TODO getOrTransform - val eventDeclaration = createEventDeclaration - eventDeclaration.event = event - eventDeclaration.direction = EventDirection.IN - traceability.defaultInterface.events += eventDeclaration - - val eventReference = createPortEventReference - eventReference.event = event - eventReference.port = traceability.defaultPort - - val eventTrigger = createEventTrigger - eventTrigger.eventReference = eventReference + val eventTrigger = transformTrigger(eventName) gammaTransition.trigger = eventTrigger - // - - // Check nullOrEmpty val guardStr = transition.cond if (!guardStr.nullOrEmpty) { val gammaGuardExpression = expressionLanguageParser.parse(guardStr, traceability.variables) @@ -371,22 +366,15 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val effects = transition.assign // TODO Get all children actions gammaTransition.effects += effects.transformBlock - - // TODO throw exception when an internal transition encounter, not supported traceability.put(transition, gammaTransition) return gammaTransition } - // TODO event name = port.interface.event ?? split - // e.g. event (1) on default port / port.event (2) / port.interface.event (3) options - // Create event, port and triggertransformer - // Create default port (check at the end not to be used by the user), and interface - // raise event actions private def createDefaultPortAndInterface() { val defaultInterface = createInterface - defaultInterface.name = "DefaultInterface1" + defaultInterface.name = "DefaultInterface" val defaultInterfaceRealization = createInterfaceRealization defaultInterfaceRealization.realizationMode = RealizationMode.PROVIDED diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index 8f3b29d9b..45d59cdcb 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -10,6 +10,7 @@ import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType import hu.bme.mit.gamma.expression.model.Declaration import hu.bme.mit.gamma.expression.model.VariableDeclaration +import hu.bme.mit.gamma.statechart.interface_.Event import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port import hu.bme.mit.gamma.statechart.statechart.EntryState @@ -44,6 +45,11 @@ class Traceability { // Works only if variables are globally unique and have a global scope protected final Map variables = newHashMap + + protected final Map ports = newHashMap + protected final Map interfaces = newHashMap + protected final Map, Event> inEvents = newHashMap + protected final Map, Event> outEvents = newHashMap protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE @@ -177,7 +183,6 @@ class Traceability { // General functions returning a mapped Gamma StateNode // Retrieves the mapped Gamma StateNode for an arbitrary transition source state def getStateNode(EObject scxmlStateNode) { - // TODO StateNode that check type is appropriate val gammaState = states.get(scxmlStateNode) if (gammaState !== null) { return gammaState as StateNode @@ -229,22 +234,6 @@ class Traceability { return gammaTransition } - def getDefaultInterface() { - return defaultInterface - } - - def setDefaultInterface(Interface defaultInterface) { - this.defaultInterface = defaultInterface - } - - def getDefaultPort() { - return defaultPort - } - - def setDefaultPort(Port defaultPort) { - this.defaultPort = defaultPort - } - // - VariableDeclaration def put(ScxmlDataType scxmlData, VariableDeclaration gammaDeclaration) { checkNotNull(scxmlData) @@ -274,5 +263,134 @@ class Traceability { checkNotNull(gammaDeclaration) return gammaDeclaration } + + // Default port and interface + def getDefaultInterface() { + return defaultInterface + } + + def setDefaultInterface(Interface defaultInterface) { + this.defaultInterface = defaultInterface + } + + def getDefaultPort() { + return defaultPort + } + + def setDefaultPort(Port defaultPort) { + this.defaultPort = defaultPort + } + + // Interfaces by string identifier + def putInterface(String scxmlInterfaceName, Interface gammaInterface) { + checkNotNull(scxmlInterfaceName) + checkNotNull(gammaInterface) + interfaces += scxmlInterfaceName -> gammaInterface + } + + def getInterface(String scxmlInterfaceName) { + checkNotNull(scxmlInterfaceName) + val gammaInterface = interfaces.get(scxmlInterfaceName) + checkNotNull(gammaInterface) + return gammaInterface + } + + def containsInterface(String scxmlInterfaceName) { + checkNotNull(scxmlInterfaceName) + return interfaces.containsKey(scxmlInterfaceName) + } + + def getInterfaces() { + return interfaces; + } + + // Ports by string identifier + def putPort(String scxmlPortName, Port gammaPort) { + checkNotNull(scxmlPortName) + checkNotNull(gammaPort) + ports += scxmlPortName -> gammaPort + } + + def getPort(String scxmlPortName) { + checkNotNull(scxmlPortName) + val gammaPort = ports.get(scxmlPortName) + checkNotNull(gammaPort) + return gammaPort + } + + def containsPort(String scxmlPortName) { + checkNotNull(scxmlPortName) + return ports.containsKey(scxmlPortName) + } + + // Input events by pairs of {Gamma port + event name} + def putInEvent(Pair portEvent, Event gammaEvent) { + checkNotNull(portEvent) + checkNotNull(portEvent.key) + checkNotNull(portEvent.value) + checkNotNull(gammaEvent) + + val port = portEvent.key + val eventName = portEvent.value + inEvents += (port -> eventName) -> gammaEvent + } + + def getInEvent(Pair portEvent) { + checkNotNull(portEvent) + checkNotNull(portEvent.key) + checkNotNull(portEvent.value) + + val port = portEvent.key + val eventName = portEvent.value + val gammaEvent = inEvents.get(port -> eventName) + + checkNotNull(gammaEvent) + return gammaEvent + } + + def containsInEvent(Pair portEvent) { + checkNotNull(portEvent) + checkNotNull(portEvent.key) + checkNotNull(portEvent.value) + + val port = portEvent.key + val eventName = portEvent.value + return inEvents.containsKey(port -> eventName) + } + + // Output events by pairs of port name - event name + def putOutEvent(Pair portEvent, Event gammaEvent) { + checkNotNull(portEvent) + checkNotNull(portEvent.key) + checkNotNull(portEvent.value) + checkNotNull(gammaEvent) + + val port = portEvent.key + val eventName = portEvent.value + outEvents += (port -> eventName) -> gammaEvent + } + + def getOutEvent(Pair portEvent) { + checkNotNull(portEvent) + checkNotNull(portEvent.key) + checkNotNull(portEvent.value) + + val port = portEvent.key + val eventName = portEvent.value + val gammaEvent = outEvents.get(port -> eventName) + + checkNotNull(gammaEvent) + return gammaEvent + } + + def containsOutEvent(Pair portEvent) { + checkNotNull(portEvent) + checkNotNull(portEvent.key) + checkNotNull(portEvent.value) + + val port = portEvent.key + val eventName = portEvent.value + return outEvents.containsKey(port -> eventName) + } } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend new file mode 100644 index 000000000..0347ae5e2 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -0,0 +1,48 @@ +package hu.bme.mit.gamma.scxml.transformation + +import hu.bme.mit.gamma.statechart.interface_.EventDirection + +class TriggerTransformer extends AbstractTransformer { + + protected final extension PortTransformer portTransformer + protected final extension EventTransformer eventTransformer + + new(Traceability traceability) { + super(traceability) + this.portTransformer = new PortTransformer(traceability) + this.eventTransformer = new EventTransformer(traceability) + } + + def transformTrigger(String eventString) { + val tokens = eventString.split("\\.") + if (tokens.size < 1 || tokens.size > 3) { + throw new IllegalArgumentException("Event descriptor " + eventString + + " does not contain exactly 1, 2 or 3 dot separated tokens." + ) + } + + val defaultPort = traceability.defaultPort + val gammaPort = ( + if (tokens.size == 2) { + val portName = tokens.head + val newGammaPort = getOrTransformPortByName(portName) + newGammaPort + } + else { + defaultPort + } + ) + + val eventName = tokens.last + val gammaEvent = getOrTransformInEvent(gammaPort, eventName) + + val gammaEventReference = createPortEventReference + gammaEventReference.port = gammaPort + gammaEventReference.event = gammaEvent + + val gammaEventTrigger = createEventTrigger + gammaEventTrigger.eventReference = gammaEventReference + return gammaEventTrigger + } + +} \ No newline at end of file From 74080b754ed9ca07d75279cad957a549e2754345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Tue, 10 May 2022 15:00:33 +0200 Subject: [PATCH 13/30] Add interface transformation --- .../commandhandler/CommandHandler.java | 9 +- .../transformation/EventTransformer.xtend | 38 +++-- .../transformation/InterfaceTransformer.xtend | 51 +++++++ .../gamma/scxml/transformation/Namings.xtend | 8 +- .../transformation/PortTransformer.xtend | 70 ++++++++-- .../ScxmlToGammaStatechartTransformer.xtend | 26 +--- .../scxml/transformation/Traceability.xtend | 131 +++++++++++------- .../transformation/TriggerTransformer.xtend | 30 ++-- 8 files changed, 246 insertions(+), 117 deletions(-) create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 36596b6f2..789af5b7c 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -1,6 +1,7 @@ package hu.bme.mit.gamma.scxml.transformation.commandhandler; import java.io.IOException; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -18,7 +19,6 @@ import ac.soton.scxml.ScxmlScxmlType; import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaStatechartTransformer; import hu.bme.mit.gamma.scxml.transformation.Traceability; -import hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures; import hu.bme.mit.gamma.statechart.interface_.Interface; import hu.bme.mit.gamma.statechart.interface_.Package; import hu.bme.mit.gamma.statechart.language.ui.serializer.StatechartLanguageSerializer; @@ -60,9 +60,10 @@ public Object execute(ExecutionEvent event) throws ExecutionException { Traceability traceability = statechartTransformer.execute(); // Interfaces and type declarations have to be explicitly serialized in another package - Interface gammaInterface = traceability.getDefaultInterface(); - Package gammaInterfacePackage = statechartUtil.wrapIntoPackage(gammaInterface); - gammaInterfacePackage.getInterfaces().addAll(traceability.getInterfaces().values()); + List gammaInterfaces = traceability.getAllInterfaces(); + Package gammaInterfacePackage = statechartUtil.wrapIntoPackage(gammaInterfaces.get(0)); + gammaInterfaces.remove(0); + gammaInterfacePackage.getInterfaces().addAll(gammaInterfaces); StatechartDefinition statechartDefinition = traceability.getStatechartDefinition(scxmlRoot); Package gammaComponentPackage = statechartUtil.wrapIntoPackageAndAddImports(statechartDefinition); diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend index 91a362cb5..44cf4600d 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend @@ -3,56 +3,54 @@ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.statechart.interface_.EventDirection import static hu.bme.mit.gamma.scxml.transformation.Namings.* -import hu.bme.mit.gamma.statechart.interface_.Port +import hu.bme.mit.gamma.statechart.interface_.Interface class EventTransformer extends AbstractTransformer { new(Traceability traceability) { super(traceability) } - def getOrTransformInEvent(Port gammaPort, String eventName) { - if (traceability.containsInEvent(gammaPort -> eventName)) { - return traceability.getInEvent(gammaPort -> eventName) + def getOrTransformInEvent(Interface gammaInterface, String eventName) { + if (traceability.containsInEvent(gammaInterface -> eventName)) { + return traceability.getInEvent(gammaInterface -> eventName) } else { - return transformInEvent(gammaPort, eventName) + return transformInEvent(gammaInterface, eventName) } } - protected def transformInEvent(Port gammaPort, String eventName) { - val gammaEvent = transformEvent(gammaPort, EventDirection.IN, eventName) + protected def transformInEvent(Interface gammaInterface, String eventName) { + val gammaEvent = transformEvent(gammaInterface, EventDirection.IN, eventName) gammaEvent.name = getInEventName(eventName) - traceability.putInEvent(gammaPort -> eventName, gammaEvent) + traceability.putInEvent(gammaInterface -> eventName, gammaEvent) return gammaEvent } - def getOrTransformOutEvent(Port gammaPort, String eventName) { - if (traceability.containsOutEvent(gammaPort -> eventName)) { - return traceability.getOutEvent(gammaPort -> eventName) + def getOrTransformOutEvent(Interface gammaInterface, String eventName) { + if (traceability.containsOutEvent(gammaInterface -> eventName)) { + return traceability.getOutEvent(gammaInterface -> eventName) } else { - return transformOutEvent(gammaPort, eventName) + return transformOutEvent(gammaInterface, eventName) } } - protected def transformOutEvent(Port gammaPort, String eventName) { - val gammaEvent = transformEvent(gammaPort, EventDirection.OUT, eventName) + protected def transformOutEvent(Interface gammaInterface, String eventName) { + val gammaEvent = transformEvent(gammaInterface, EventDirection.OUT, eventName) gammaEvent.name = getOutEventName(eventName) - traceability.putOutEvent(gammaPort -> eventName, gammaEvent) + traceability.putOutEvent(gammaInterface -> eventName, gammaEvent) return gammaEvent } - // This method assumes that the transformation of the port and interface of the respecting event - // has already happened when we transform the event. - private def transformEvent(Port gammaPort, EventDirection direction, String eventName) { + // This method assumes that the transformation of the interface + // of the respective event has already happened when we transform the event. + private def transformEvent(Interface gammaInterface, EventDirection direction, String eventName) { val gammaEvent = createEvent val gammaEventDeclaration = createEventDeclaration gammaEventDeclaration.event = gammaEvent gammaEventDeclaration.direction = direction - val gammaInterface = gammaPort.interfaceRealization.interface gammaInterface.events += gammaEventDeclaration - return gammaEvent } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend new file mode 100644 index 000000000..5f52f7c03 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend @@ -0,0 +1,51 @@ +package hu.bme.mit.gamma.scxml.transformation + +import static com.google.common.base.Preconditions.checkState +import static hu.bme.mit.gamma.scxml.transformation.Namings.* + +class InterfaceTransformer extends AbstractTransformer { + new(Traceability traceability) { + super(traceability) + } + + def getOrCreateDefaultInterface() { + val defaultInterface = traceability.getDefaultInterface + if (defaultInterface !== null) { + return defaultInterface + } + else { + val gammaInterface = createDefaultInterface + traceability.setDefaultInterface(gammaInterface) + return gammaInterface + } + } + + protected def createDefaultInterface() { + val defaultInterface = createInterface + val defaultInterfaceName = getDefaultInterfaceName + defaultInterface.name = defaultInterfaceName + + return defaultInterface + } + + def getOrTransformInterfaceByName(String interfaceName) { + checkState(interfaceName !== null) + if (traceability.containsInterface(interfaceName)) { + return traceability.getInterface(interfaceName) + } + else { + val gammaInterface = transformInterfaceByName(interfaceName) + traceability.putInterface(interfaceName, gammaInterface) + return gammaInterface + } + } + + protected def transformInterfaceByName(String interfaceName) { + val gammaInterface = createInterface + val gammaInterfaceName = getInterfaceName(interfaceName) + gammaInterface.name = gammaInterfaceName + + return gammaInterface + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index 08e539509..3a6628ded 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -8,8 +8,14 @@ import ac.soton.scxml.ScxmlStateType class Namings { - def static String getInterfaceName(String scxmlPortName) '''«scxmlPortName»_Interface''' + // TODO check default names differ from user defined interface and port names + // at the end of the transformation + def static String getDefaultPortName() '''_DefaultPort''' + def static String getDefaultInterfaceName() '''_DefaultInterface''' + def static String getDefaultInterfacePortName(String scxmlInterfaceName) '''«scxmlInterfaceName»_DefaultPort''' + def static String getInterfaceName(String scxmlInterfaceName) '''«scxmlInterfaceName»''' def static String getPortName(String scxmlPortName) '''«scxmlPortName»''' + def static String getInEventName(String scxmlEventName) '''in_«scxmlEventName»''' def static String getOutEventName(String scxmlEventName) '''out_«scxmlEventName»''' diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend index fb5bc4921..de9af1741 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend @@ -4,30 +4,81 @@ import hu.bme.mit.gamma.statechart.interface_.RealizationMode import static com.google.common.base.Preconditions.checkState import static hu.bme.mit.gamma.scxml.transformation.Namings.* +import hu.bme.mit.gamma.statechart.interface_.Interface class PortTransformer extends AbstractTransformer { new(Traceability traceability) { super(traceability) } - def getOrTransformPortByName(String portName) { + def getOrCreateDefaultPort() { + val defaultPort = traceability.getDefaultPort + if (defaultPort !== null) { + return defaultPort + } + else { + val gammaPort = createDefaultPort + traceability.setDefaultPort(gammaPort) + return gammaPort + } + } + + // We assume that the statechart's default interface already exists at this point. + protected def createDefaultPort() { + val defaultInterface = traceability.getDefaultInterface + + val defaultInterfaceRealization = createInterfaceRealization + defaultInterfaceRealization.realizationMode = RealizationMode.PROVIDED + defaultInterfaceRealization.interface = defaultInterface + + val defaultPort = createPort + defaultPort.name = getDefaultPortName + defaultPort.interfaceRealization = defaultInterfaceRealization + + return defaultPort + } + + def getOrTransformDefaultInterfacePort(Interface gammaInterface) { + checkState(gammaInterface !== null) + if (traceability.containsDefaultInterfacePort(gammaInterface)) { + return traceability.getDefaultInterfacePort(gammaInterface) + } + else { + val gammaPort = transformDefaultInterfacePort(gammaInterface) + traceability.putDefaultInterfacePort(gammaInterface, gammaPort) + return gammaPort + } + } + + // For now, all ports realize their interfaces in provided mode. + protected def transformDefaultInterfacePort(Interface gammaInterface) { + val gammaInterfaceRealization = createInterfaceRealization + gammaInterfaceRealization.realizationMode = RealizationMode.PROVIDED + gammaInterfaceRealization.interface = gammaInterface + + val gammaPort = createPort + val gammaInterfaceName = gammaInterface.name + gammaPort.name = getDefaultInterfacePortName(gammaInterfaceName) + gammaPort.interfaceRealization = gammaInterfaceRealization + + return gammaPort + } + + def getOrTransformPortByName(Interface gammaInterface, String portName) { + checkState(gammaInterface !== null) checkState(portName !== null) if (traceability.containsPort(portName)) { return traceability.getPort(portName) } else { - val gammaPort = transformPortByName(portName) + val gammaPort = transformPortByName(gammaInterface, portName) + traceability.putPort(portName, gammaPort) return gammaPort } } - // For now, different ports realize different interfaces. - protected def transformPortByName(String portName) { - val gammaInterface = createInterface - val gammaInterfaceName = getInterfaceName(portName) - gammaInterface.name = gammaInterfaceName - traceability.putInterface(gammaInterfaceName, gammaInterface) - + // For now, all ports realize their interfaces in provided mode. + protected def transformPortByName(Interface gammaInterface, String portName) { val gammaInterfaceRealization = createInterfaceRealization gammaInterfaceRealization.realizationMode = RealizationMode.PROVIDED gammaInterfaceRealization.interface = gammaInterface @@ -35,7 +86,6 @@ class PortTransformer extends AbstractTransformer { val gammaPort = createPort gammaPort.name = getPortName(portName) gammaPort.interfaceRealization = gammaInterfaceRealization - traceability.putPort(portName, gammaPort) return gammaPort } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index b80160473..0c2bb73cc 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -69,10 +69,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Transformation of the SCXML root element and its contents recursively def execute() { traceability.put(scxmlRoot, gammaStatechart) - - createDefaultPortAndInterface() - gammaStatechart.ports += traceability.defaultPort - + logger.log(Level.INFO, "Transforming root element (" + scxmlRoot.name + ")") val datamodels = scxmlRoot.datamodel @@ -136,8 +133,11 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { } // Add all ports from traceability + if (traceability.getDefaultPort !== null) { + gammaStatechart.ports += traceability.getDefaultPort + } + gammaStatechart.ports += traceability.defaultInterfacePorts.values gammaStatechart.ports += traceability.ports.values - // return traceability } @@ -372,20 +372,4 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { return gammaTransition } - private def createDefaultPortAndInterface() { - val defaultInterface = createInterface - defaultInterface.name = "DefaultInterface" - - val defaultInterfaceRealization = createInterfaceRealization - defaultInterfaceRealization.realizationMode = RealizationMode.PROVIDED - defaultInterfaceRealization.interface = defaultInterface - - val defaultPort = createPort - defaultPort.name = "DefaultPort" - defaultPort.interfaceRealization = defaultInterfaceRealization - - traceability.defaultInterface = defaultInterface - traceability.defaultPort = defaultPort - } - } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index 45d59cdcb..ae3679e6c 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -46,16 +46,16 @@ class Traceability { // Works only if variables are globally unique and have a global scope protected final Map variables = newHashMap + protected Port defaultPort + protected Interface defaultInterface + protected final Map defaultInterfacePorts = newHashMap protected final Map ports = newHashMap protected final Map interfaces = newHashMap - protected final Map, Event> inEvents = newHashMap - protected final Map, Event> outEvents = newHashMap + protected final Map, Event> inEvents = newHashMap + protected final Map, Event> outEvents = newHashMap protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE - protected Port defaultPort - protected Interface defaultInterface - // - Synchronous Statechart Definition new(ScxmlScxmlType scxmlRoot) { this.scxmlRoot = scxmlRoot @@ -264,7 +264,7 @@ class Traceability { return gammaDeclaration } - // Default port and interface + // Default port and interface (for event strings like 'event') def getDefaultInterface() { return defaultInterface } @@ -281,7 +281,26 @@ class Traceability { this.defaultPort = defaultPort } - // Interfaces by string identifier + // Default ports of interfaces (for event strings like 'interface.event') + def putDefaultInterfacePort(Interface gammaInterface, Port gammaPort) { + checkNotNull(gammaInterface) + checkNotNull(gammaPort) + defaultInterfacePorts += gammaInterface -> gammaPort + } + + def getDefaultInterfacePort(Interface gammaInterface) { + checkNotNull(gammaInterface) + val gammaPort = defaultInterfacePorts.get(gammaInterface) + checkNotNull(gammaPort) + return gammaPort + } + + def containsDefaultInterfacePort(Interface gammaInterface) { + checkNotNull(gammaInterface) + return defaultInterfacePorts.containsKey(gammaInterface) + } + + // Interfaces by string identifier (for event strings like '[port.]interface.event) def putInterface(String scxmlInterfaceName, Interface gammaInterface) { checkNotNull(scxmlInterfaceName) checkNotNull(gammaInterface) @@ -304,7 +323,15 @@ class Traceability { return interfaces; } - // Ports by string identifier + def getAllInterfaces() { + var allInterfaces = interfaces.values.toList + if (getDefaultInterface !== null) { + allInterfaces += getDefaultInterface + } + return allInterfaces + } + + // Ports by string identifier (for event strings like 'port.interface.event) def putPort(String scxmlPortName, Port gammaPort) { checkNotNull(scxmlPortName) checkNotNull(gammaPort) @@ -323,74 +350,74 @@ class Traceability { return ports.containsKey(scxmlPortName) } - // Input events by pairs of {Gamma port + event name} - def putInEvent(Pair portEvent, Event gammaEvent) { - checkNotNull(portEvent) - checkNotNull(portEvent.key) - checkNotNull(portEvent.value) + // Input events by pairs of {Gamma interface; event name} + def putInEvent(Pair interfaceEvent, Event gammaEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) checkNotNull(gammaEvent) - val port = portEvent.key - val eventName = portEvent.value - inEvents += (port -> eventName) -> gammaEvent + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + inEvents += (interface -> eventName) -> gammaEvent } - def getInEvent(Pair portEvent) { - checkNotNull(portEvent) - checkNotNull(portEvent.key) - checkNotNull(portEvent.value) + def getInEvent(Pair interfaceEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) - val port = portEvent.key - val eventName = portEvent.value - val gammaEvent = inEvents.get(port -> eventName) + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + val gammaEvent = inEvents.get(interface -> eventName) checkNotNull(gammaEvent) return gammaEvent } - def containsInEvent(Pair portEvent) { - checkNotNull(portEvent) - checkNotNull(portEvent.key) - checkNotNull(portEvent.value) + def containsInEvent(Pair interfaceEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) - val port = portEvent.key - val eventName = portEvent.value - return inEvents.containsKey(port -> eventName) + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + return inEvents.containsKey(interface -> eventName) } - // Output events by pairs of port name - event name - def putOutEvent(Pair portEvent, Event gammaEvent) { - checkNotNull(portEvent) - checkNotNull(portEvent.key) - checkNotNull(portEvent.value) + // Output events by pairs of {port name; event name} + def putOutEvent(Pair interfaceEvent, Event gammaEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) checkNotNull(gammaEvent) - val port = portEvent.key - val eventName = portEvent.value - outEvents += (port -> eventName) -> gammaEvent + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + outEvents += (interface -> eventName) -> gammaEvent } - def getOutEvent(Pair portEvent) { - checkNotNull(portEvent) - checkNotNull(portEvent.key) - checkNotNull(portEvent.value) + def getOutEvent(Pair interfaceEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) - val port = portEvent.key - val eventName = portEvent.value - val gammaEvent = outEvents.get(port -> eventName) + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + val gammaEvent = outEvents.get(interface -> eventName) checkNotNull(gammaEvent) return gammaEvent } - def containsOutEvent(Pair portEvent) { - checkNotNull(portEvent) - checkNotNull(portEvent.key) - checkNotNull(portEvent.value) + def containsOutEvent(Pair interfaceEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) - val port = portEvent.key - val eventName = portEvent.value - return outEvents.containsKey(port -> eventName) + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + return outEvents.containsKey(interface -> eventName) } } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend index 0347ae5e2..ea006fd60 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -1,18 +1,22 @@ package hu.bme.mit.gamma.scxml.transformation -import hu.bme.mit.gamma.statechart.interface_.EventDirection +import hu.bme.mit.gamma.statechart.interface_.Interface +import hu.bme.mit.gamma.statechart.interface_.Port class TriggerTransformer extends AbstractTransformer { protected final extension PortTransformer portTransformer + protected final extension InterfaceTransformer interfaceTransformer protected final extension EventTransformer eventTransformer new(Traceability traceability) { super(traceability) this.portTransformer = new PortTransformer(traceability) + this.interfaceTransformer = new InterfaceTransformer(traceability) this.eventTransformer = new EventTransformer(traceability) } + // TODO sanitize and check eventString def transformTrigger(String eventString) { val tokens = eventString.split("\\.") if (tokens.size < 1 || tokens.size > 3) { @@ -21,20 +25,28 @@ class TriggerTransformer extends AbstractTransformer { ) } - val defaultPort = traceability.defaultPort - val gammaPort = ( - if (tokens.size == 2) { + var gammaInterface = null as Interface + var gammaPort = null as Port + + if (tokens.size == 1) { + gammaInterface = getOrCreateDefaultInterface() + gammaPort = getOrCreateDefaultPort() + } + else { + val interfaceName = tokens.get(tokens.size - 2) + gammaInterface = getOrTransformInterfaceByName(interfaceName) + + if (tokens.size >= 3) { val portName = tokens.head - val newGammaPort = getOrTransformPortByName(portName) - newGammaPort + gammaPort = getOrTransformPortByName(gammaInterface, portName) } else { - defaultPort + gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) } - ) + } val eventName = tokens.last - val gammaEvent = getOrTransformInEvent(gammaPort, eventName) + val gammaEvent = getOrTransformInEvent(gammaInterface, eventName) val gammaEventReference = createPortEventReference gammaEventReference.port = gammaPort From 71550c3256add4209adbf82daba32352cdb4e6a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Tue, 10 May 2022 15:33:01 +0200 Subject: [PATCH 14/30] Transform raise event actions --- .../transformation/ActionTransformer.xtend | 48 +++++++++++++++++++ .../ScxmlToGammaStatechartTransformer.xtend | 13 ++++- .../transformation/TriggerTransformer.xtend | 1 + 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index a0ac127ab..2d0182095 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -4,18 +4,27 @@ import ac.soton.scxml.ScxmlAssignType import ac.soton.scxml.ScxmlIfType import ac.soton.scxml.ScxmlOnentryType import ac.soton.scxml.ScxmlOnexitType +import ac.soton.scxml.ScxmlRaiseType import hu.bme.mit.gamma.action.model.Action import hu.bme.mit.gamma.expression.model.VariableDeclaration +import hu.bme.mit.gamma.statechart.interface_.Interface +import hu.bme.mit.gamma.statechart.interface_.Port import java.util.logging.Level import org.eclipse.emf.ecore.EObject class ActionTransformer extends AbstractTransformer { + protected final extension PortTransformer portTransformer + protected final extension InterfaceTransformer interfaceTransformer + protected final extension EventTransformer eventTransformer protected final extension ScxmlGammaExpressionTransformer expressionTransformer new(Traceability traceability) { super(traceability) + this.portTransformer = new PortTransformer(traceability) + this.interfaceTransformer = new InterfaceTransformer(traceability) + this.eventTransformer = new EventTransformer(traceability) this.expressionTransformer = new ScxmlGammaExpressionTransformer(traceability) } @@ -58,6 +67,45 @@ class ActionTransformer extends AbstractTransformer { return gammaAssign } + def dispatch Action transformAction(ScxmlRaiseType scxmlRaise) { + logger.log(Level.INFO, "Transforming element (" + scxmlRaise + ")") + + val eventString = scxmlRaise.event + val tokens = eventString.split("\\.") + if (tokens.size < 1 || tokens.size > 3) { + throw new IllegalArgumentException("Event descriptor " + eventString + + " does not contain exactly 1, 2 or 3 dot separated tokens." + ) + } + + var gammaInterface = null as Interface + var gammaPort = null as Port + + if (tokens.size == 1) { + gammaInterface = getOrCreateDefaultInterface() + gammaPort = getOrCreateDefaultPort() + } + else { + val interfaceName = tokens.get(tokens.size - 2) + gammaInterface = getOrTransformInterfaceByName(interfaceName) + + if (tokens.size >= 3) { + val portName = tokens.head + gammaPort = getOrTransformPortByName(gammaInterface, portName) + } + else { + gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) + } + } + + val eventName = tokens.last + val gammaEvent = getOrTransformOutEvent(gammaInterface, eventName) + + // Event parameters are currently not supported. + val gammaRaise = createRaiseEventAction(gammaPort, gammaEvent, newArrayList) + return gammaRaise + } + def dispatch Action transformAction(ScxmlIfType scxmlIf) { logger.log(Level.INFO, "Transforming element (" + scxmlIf + ")") diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 0c2bb73cc..7f2030469 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -364,8 +364,17 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { gammaTransition.guard = gammaGuardExpression } - val effects = transition.assign // TODO Get all children actions - gammaTransition.effects += effects.transformBlock + // TODO for all types of actions + val assignEffects = transition.assign // TODO Get all children actions + if (!assignEffects.nullOrEmpty) { + gammaTransition.effects += assignEffects.transformBlock + } + + val raiseEffects = transition.raise // TODO Get all children actions + if (!raiseEffects.nullOrEmpty) { + gammaTransition.effects += raiseEffects.transformBlock + } + // traceability.put(transition, gammaTransition) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend index ea006fd60..c974f30e7 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -11,6 +11,7 @@ class TriggerTransformer extends AbstractTransformer { new(Traceability traceability) { super(traceability) + this.portTransformer = new PortTransformer(traceability) this.interfaceTransformer = new InterfaceTransformer(traceability) this.eventTransformer = new EventTransformer(traceability) From 458615a3bfc06b0743fad42b8cd854f06a2e89ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Sun, 22 May 2022 13:22:21 +0200 Subject: [PATCH 15/30] Fix adding all transitions from initial states --- .../transformation/ActionTransformer.xtend | 24 ++-- .../ScxmlToGammaStatechartTransformer.xtend | 106 +++++++++--------- .../scxml/transformation/Traceability.xtend | 21 +++- 3 files changed, 85 insertions(+), 66 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index 2d0182095..298753919 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -28,24 +28,28 @@ class ActionTransformer extends AbstractTransformer { this.expressionTransformer = new ScxmlGammaExpressionTransformer(traceability) } - def Action transform(ScxmlOnentryType scxmlOnentry) { + def Action transformOnentry(ScxmlOnentryType scxmlOnentry) { logger.log(Level.INFO, "Transforming element (" + scxmlOnentry + ")") // TODO Get list of all children actions, not just -s - val scxmlActions = scxmlOnentry.assign - val gammaEntryAction = scxmlActions.transformBlock; // TODO - - return gammaEntryAction + val scxmlActions = scxmlOnentry.assign + scxmlOnentry.raise + if (!scxmlActions.nullOrEmpty) { + val gammaEntryAction = scxmlActions.transformBlock; + return gammaEntryAction + } + return null } - def Action transform(ScxmlOnexitType scxmlOnexit) { + def Action transformOnexit(ScxmlOnexitType scxmlOnexit) { logger.log(Level.INFO, "Transforming element (" + scxmlOnexit + ")") // TODO Get list of all children actions, not just -s - val scxmlActions = scxmlOnexit.assign - val gammaExitAction = scxmlActions.transformBlock; // TODO - - return gammaExitAction + val scxmlActions = scxmlOnexit.assign + scxmlOnexit.raise + if (!scxmlActions.nullOrEmpty) { + val gammaExitAction = scxmlActions.transformBlock; + return gammaExitAction + } + return null } def dispatch Action transformAction(ScxmlAssignType scxmlAssign) { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 7f2030469..dcc499b79 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -9,7 +9,6 @@ import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType import ac.soton.scxml.TransitionTypeDatatype -import hu.bme.mit.gamma.statechart.interface_.RealizationMode import hu.bme.mit.gamma.statechart.statechart.EntryState import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State @@ -20,21 +19,8 @@ import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* -// Scoping in variable transformation and assignment +// TODO Scoping in variable transformation and assignment // TODO History, parallel - -// TODO Events, ports, triggers, ... -// port.interface.event ~ port's interface's event split -// event (1) on default port / interface.event (2) / port.interface.event (3) options -// default port for each interface -// TODO raise event actions - -// TODO docs -// TODO scxml support (wiki, MagicDraw, RationalRhapsody etc.) - -// Create event, port and triggertransformer -// Create default port (check at the end not to be used by the user), and interface - class ScxmlToGammaStatechartTransformer extends AbstractTransformer { protected final extension ActionTransformer actionTransformer @@ -95,8 +81,9 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val parallel = scxmlStateNode as ScxmlParallelType mainRegion.stateNodes += parallel.transformParallel } - else if (scxmlStateNode instanceof ScxmlStateType) { - mainRegion.stateNodes += scxmlStateNode.transformState + else if (isState(scxmlStateNode)) { + val state = scxmlStateNode as ScxmlStateType + mainRegion.stateNodes += state.transformState } else if (isFinal(scxmlStateNode)) { val final = scxmlStateNode as ScxmlFinalType @@ -132,6 +119,10 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { gammaInitial.createTransition(gammaInitialTarget) } + // Add all transitions from initial states of Gamma compound states + // specified by scxml initial attributes or document order + gammaStatechart.transitions += traceability.getInitialTransitions + // Add all ports from traceability if (traceability.getDefaultPort !== null) { gammaStatechart.ports += traceability.getDefaultPort @@ -176,7 +167,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // TODO Transform history pseudo-states (by adding a wrapper compound state perhaps) // Initial-ok kicserélése a gyerek state-ekben, amely parallelekben találok historyt - // Vagy history node hozzáadása minden gyerek régióhoz, ha van kívül history ?? + // Vagy history node hozzáadása minden gyerek régióhoz, ha van kívül history? /*val scxmlHistoryStates = parallelNode.history for (scxmlHistoryState : scxmlHistoryStates) { @@ -185,12 +176,16 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Transform onentry and onexit handlers val onentryActions = parallelNode.onentry for (onentryAction : onentryActions) { - gammaParallel.entryActions += onentryAction.transformAction + if (onentryAction !== null) { + gammaParallel.entryActions += onentryAction.transformOnentry + } } - + val onexitActions = parallelNode.onexit for (onexitAction : onexitActions) { - gammaParallel.exitActions += onexitAction.transformAction + if (onexitAction !== null) { + gammaParallel.exitActions += onexitAction.transformOnexit + } } traceability.put(parallelNode, gammaParallel) @@ -231,6 +226,12 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { } } + // Transform history pseudo-states + val scxmlHistoryStates = scxmlState.history + for (scxmlHistoryState : scxmlHistoryStates) { + region.stateNodes += scxmlHistoryState.transform + } + // Transform the state's initial element or attribute, // or select its first child as initial state if neither one above is present. val scxmlInitialElement = scxmlState.initial.head @@ -246,32 +247,32 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val scxmlInitialAttribute = scxmlState.initial1.head if (scxmlInitialAttribute !== null) { val gammaInitialTarget = traceability.getStateNodeById(scxmlInitialAttribute) - gammaInitial.createTransition(gammaInitialTarget) + val initialTransition = gammaInitial.createTransition(gammaInitialTarget) + traceability.putInitialTransition(initialTransition) } else { val firstScxmlStateChild = getFirstChildStateNode(scxmlState) as ScxmlStateType val gammaInitialTarget = traceability.getState(firstScxmlStateChild) - gammaInitial.createTransition(gammaInitialTarget) + val initialTransition = gammaInitial.createTransition(gammaInitialTarget) + traceability.putInitialTransition(initialTransition) } } + } - // Transform history pseudo-states - val scxmlHistoryStates = scxmlState.history - for (scxmlHistoryState : scxmlHistoryStates) { - region.stateNodes += scxmlHistoryState.transform - } - - // Transform onentry and onexit handlers - val onentryActions = scxmlState.onentry - for (onentryAction : onentryActions) { - gammaState.entryActions += onentryAction.transform + // Transform onentry and onexit handlers + val onentryActions = scxmlState.onentry + for (onentryAction : onentryActions) { + if (onentryAction !== null) { + gammaState.entryActions += onentryAction.transformOnentry } - - val onexitActions = scxmlState.onexit - for (onexitAction : onexitActions) { - gammaState.exitActions += onexitAction.transform + } + + val onexitActions = scxmlState.onexit + for (onexitAction : onexitActions) { + if (onexitAction !== null) { + gammaState.exitActions += onexitAction.transformOnexit } - } + } traceability.put(scxmlState, gammaState) @@ -288,13 +289,16 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Transform onentry and onexit handlers val onentryActions = scxmlFinal.onentry for (onentryAction : onentryActions) { - // TODO Handle nulls - gammaFinal.entryActions += onentryAction.transformAction + if (onentryAction !== null) { + gammaFinal.entryActions += onentryAction.transformOnentry + } } val onexitActions = scxmlFinal.onexit for (onexitAction : onexitActions) { - gammaFinal.exitActions += onexitAction.transformAction + if (onexitAction !== null) { + gammaFinal.exitActions += onexitAction.transformOnexit + } } traceability.put(scxmlFinal, gammaFinal) @@ -353,11 +357,14 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { val gammaTransition = gammaSource.createTransition(gammaTarget) - // Transform event trigger + // Transform event trigger if present val eventName = transition.event - val eventTrigger = transformTrigger(eventName) - gammaTransition.trigger = eventTrigger + if (!eventName.nullOrEmpty) { + val eventTrigger = transformTrigger(eventName) + gammaTransition.trigger = eventTrigger + } + // Transform guard if present val guardStr = transition.cond if (!guardStr.nullOrEmpty) { val gammaGuardExpression = expressionLanguageParser.parse(guardStr, traceability.variables) @@ -365,14 +372,9 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { } // TODO for all types of actions - val assignEffects = transition.assign // TODO Get all children actions - if (!assignEffects.nullOrEmpty) { - gammaTransition.effects += assignEffects.transformBlock - } - - val raiseEffects = transition.raise // TODO Get all children actions - if (!raiseEffects.nullOrEmpty) { - gammaTransition.effects += raiseEffects.transformBlock + val effects = transition.assign + transition.raise + if (!effects.nullOrEmpty) { + gammaTransition.effects += effects.transformBlock } // diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index ae3679e6c..b235ed4c5 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -24,6 +24,7 @@ import java.util.Map import org.eclipse.emf.ecore.EObject import static com.google.common.base.Preconditions.checkNotNull +import java.util.Set class Traceability { @@ -40,6 +41,7 @@ class Traceability { protected final Map initials = newHashMap protected final Map historyStates = newHashMap protected final Map transitions = newHashMap + protected final Set initialTransitions = newHashSet protected final Map dataElements = newHashMap @@ -202,19 +204,19 @@ class Traceability { // Retrieves the mapped Gamma StateNode for an arbitrary transition target state id def getStateNodeById(String scxmlStateNodeId) { - val gammaState = states.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value + val gammaState = states.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId]?.value if (gammaState !== null) { return gammaState } - val gammaParallel = parallels.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value + val gammaParallel = parallels.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId]?.value if (gammaParallel !== null) { return gammaParallel } - val gammaFinal = finals.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value + val gammaFinal = finals.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId]?.value if (gammaFinal !== null) { return gammaFinal } - val gammaHistory = historyStates.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId].value + val gammaHistory = historyStates.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId]?.value checkNotNull(gammaHistory) return gammaHistory @@ -234,6 +236,17 @@ class Traceability { return gammaTransition } + // Transitions from initial states of Gamma compound states + // specified by scxml initial attributes or document order + def putInitialTransition(Transition gammaTransition) { + checkNotNull(gammaTransition) + initialTransitions += gammaTransition + } + + def getInitialTransitions() { + return initialTransitions + } + // - VariableDeclaration def put(ScxmlDataType scxmlData, VariableDeclaration gammaDeclaration) { checkNotNull(scxmlData) From 1299968313da3828005dfb02c21ed087c1c04fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Mon, 3 Oct 2022 11:11:48 +0200 Subject: [PATCH 16/30] Wrap transformed statechart in async adapter --- .../commandhandler/CommandHandler.java | 15 ++++- .../transformation/AbstractTransformer.xtend | 4 +- .../gamma/scxml/transformation/Namings.xtend | 4 ++ .../ScxmlToGammaStatechartTransformer.xtend | 59 +++++++++++++++++++ .../scxml/transformation/Traceability.xtend | 12 +++- 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 789af5b7c..f959f1332 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -19,6 +19,7 @@ import ac.soton.scxml.ScxmlScxmlType; import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaStatechartTransformer; import hu.bme.mit.gamma.scxml.transformation.Traceability; +import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter; import hu.bme.mit.gamma.statechart.interface_.Interface; import hu.bme.mit.gamma.statechart.interface_.Package; import hu.bme.mit.gamma.statechart.language.ui.serializer.StatechartLanguageSerializer; @@ -65,8 +66,13 @@ public Object execute(ExecutionEvent event) throws ExecutionException { gammaInterfaces.remove(0); gammaInterfacePackage.getInterfaces().addAll(gammaInterfaces); + // Pack and serialize statechart StatechartDefinition statechartDefinition = traceability.getStatechartDefinition(scxmlRoot); - Package gammaComponentPackage = statechartUtil.wrapIntoPackageAndAddImports(statechartDefinition); + Package gammaStatechartPackage = statechartUtil.wrapIntoPackageAndAddImports(statechartDefinition); + + // Pack and serialize adapter + AsynchronousAdapter adapter = traceability.getAdapter(); + Package gammaAdapterPackage = statechartUtil.wrapIntoPackageAndAddImports(adapter); StatechartLanguageSerializer packageSerializer = new StatechartLanguageSerializer(); logger.log(Level.INFO, "Start serializing Gamma packages..."); @@ -74,8 +80,11 @@ public Object execute(ExecutionEvent event) throws ExecutionException { String declarationsPackageFileName = extensionlessFileName + "Declarations.gcd"; packageSerializer.serialize(gammaInterfacePackage, parentPath, declarationsPackageFileName); - String componentPackageFileName = extensionlessFileName + ".gcd"; - packageSerializer.serialize(gammaComponentPackage, parentPath, componentPackageFileName); + String statechartPackageFileName = extensionlessFileName + ".gcd"; + packageSerializer.serialize(gammaStatechartPackage, parentPath, statechartPackageFileName); + + String adapterPackageFileName = extensionlessFileName + "Adapter.gcd"; + packageSerializer.serialize(gammaAdapterPackage, parentPath, adapterPackageFileName); logger.log(Level.INFO, "The SCXML - Gamma statechart transformation has finished."); diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend index a724986f3..662d28e69 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend @@ -5,12 +5,13 @@ import hu.bme.mit.gamma.action.util.ActionUtil import hu.bme.mit.gamma.expression.model.ExpressionModelFactory import hu.bme.mit.gamma.expression.util.ExpressionTypeDeterminator2 import hu.bme.mit.gamma.expression.util.ExpressionUtil +import hu.bme.mit.gamma.scxml.transformation.parse.ScxmlGammaExpressionLanguageParser +import hu.bme.mit.gamma.statechart.composite.CompositeModelFactory import hu.bme.mit.gamma.statechart.interface_.InterfaceModelFactory import hu.bme.mit.gamma.statechart.statechart.StatechartModelFactory import hu.bme.mit.gamma.statechart.util.StatechartUtil import hu.bme.mit.gamma.util.GammaEcoreUtil import java.util.logging.Logger -import hu.bme.mit.gamma.scxml.transformation.parse.ScxmlGammaExpressionLanguageParser abstract class AbstractTransformer { @@ -22,6 +23,7 @@ abstract class AbstractTransformer { protected final extension ExpressionUtil expressionUtil = ExpressionUtil.INSTANCE protected final extension InterfaceModelFactory interfaceModelFactory = InterfaceModelFactory.eINSTANCE + protected final extension CompositeModelFactory compositeModelFactory = CompositeModelFactory.eINSTANCE protected final extension StatechartModelFactory statechartModelFactory = StatechartModelFactory.eINSTANCE protected final extension ActionModelFactory actionModelFactory = ActionModelFactory.eINSTANCE protected final extension ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index 3a6628ded..32730b5eb 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -19,6 +19,10 @@ class Namings { def static String getInEventName(String scxmlEventName) '''in_«scxmlEventName»''' def static String getOutEventName(String scxmlEventName) '''out_«scxmlEventName»''' + def static String getAdapterName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»Adapter''' + def static String getInternalEventQueueName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»InternalEventQueue''' + def static String getExternalEventQueueName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»ExternalEventQueue''' + def static String getStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' def static String getRegionName(String scxmlElementName) '''«scxmlElementName»Region''' diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index dcc499b79..adc36693d 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -9,11 +9,16 @@ import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType import ac.soton.scxml.TransitionTypeDatatype +import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter +import hu.bme.mit.gamma.statechart.composite.ControlFunction +import hu.bme.mit.gamma.statechart.composite.DiscardStrategy +import hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures import hu.bme.mit.gamma.statechart.statechart.EntryState import hu.bme.mit.gamma.statechart.statechart.InitialState import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition +import java.math.BigInteger import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* @@ -30,6 +35,9 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Root element of the SCXML statechart model to transform protected final ScxmlScxmlType scxmlRoot + // Asynchronous wrapper component around the synchronous statechart definition + protected AsynchronousAdapter adapter + // Root element of the Gamma statechart definition as the transformation result protected final SynchronousStatechartDefinition gammaStatechart @@ -43,6 +51,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { super(traceability) this.scxmlRoot = scxmlRoot + this.adapter = null this.gammaStatechart = createSynchronousStatechartDefinition => [ it.name = getStatechartName(scxmlRoot) ] @@ -130,9 +139,59 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { gammaStatechart.ports += traceability.defaultInterfacePorts.values gammaStatechart.ports += traceability.ports.values + val adapter = wrapIntoAdapter + traceability.adapter = adapter + return traceability } + protected def AsynchronousAdapter wrapIntoAdapter() { + adapter = gammaStatechart.wrapIntoAdapter(getAdapterName(scxmlRoot)) + + // Set control specification + val controlSpecification = compositeModelFactory.createControlSpecification + controlSpecification.trigger = interfaceModelFactory.createAnyTrigger + controlSpecification.controlFunction = ControlFunction.RUN_ONCE + + adapter.controlSpecifications += controlSpecification + + // Create internal event queue + // TODO Check capacity and priority + val internalEventQueue = compositeModelFactory.createMessageQueue + internalEventQueue.name = getInternalEventQueueName(scxmlRoot) + internalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING + internalEventQueue.priority = BigInteger.TWO + internalEventQueue.capacity = expressionUtil.toIntegerLiteral(10) + + // TODO Add only internal ports + for (port : StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart)) { + val reference = statechartModelFactory.createAnyPortEventReference + reference.port = port + internalEventQueue.eventReferences += reference + } + + adapter.messageQueues += internalEventQueue + + // Create external event queue + // TODO Check capacity and priority + val externalEventQueue = compositeModelFactory.createMessageQueue + externalEventQueue.name = getExternalEventQueueName(scxmlRoot) + externalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING + externalEventQueue.priority = BigInteger.ONE + externalEventQueue.capacity = expressionUtil.toIntegerLiteral(10) + + // TODO Add only external ports + for (port : StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart)) { + val reference = statechartModelFactory.createAnyPortEventReference + reference.port = port + externalEventQueue.eventReferences += reference + } + + adapter.messageQueues.add(externalEventQueue) + + return adapter + } + protected def State transformParallel(ScxmlParallelType parallelNode) { logger.log(Level.INFO, "Transforming element (" + parallelNode.id + ")") diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend index b235ed4c5..d91a15800 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend @@ -10,6 +10,7 @@ import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType import hu.bme.mit.gamma.expression.model.Declaration import hu.bme.mit.gamma.expression.model.VariableDeclaration +import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter import hu.bme.mit.gamma.statechart.interface_.Event import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port @@ -21,10 +22,10 @@ import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition import hu.bme.mit.gamma.util.GammaEcoreUtil import java.util.Map +import java.util.Set import org.eclipse.emf.ecore.EObject import static com.google.common.base.Preconditions.checkNotNull -import java.util.Set class Traceability { @@ -33,6 +34,7 @@ class Traceability { // ScxmlScxmlType - SynchronousStatechartDefinition pairs, but for now, // we assume only one SCMXL statechart to be transformed (from an root element). protected final ScxmlScxmlType scxmlRoot + protected AsynchronousAdapter adapter protected final Map statechartDefinitions = newHashMap protected final Map parallels = newHashMap @@ -66,6 +68,14 @@ class Traceability { def getScxmlRoot() { return scxmlRoot } + + def setAdapter(AsynchronousAdapter adapter) { + this.adapter = adapter + } + + def getAdapter() { + return adapter + } def put(ScxmlScxmlType scxmlRoot, SynchronousStatechartDefinition gammaStatechart) { checkNotNull(scxmlRoot) From 7175e05361f994fcf828d1b31c413c5a0605507c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Sat, 15 Oct 2022 17:07:41 +0200 Subject: [PATCH 17/30] Update required Java version to 17 --- .../.classpath | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 7 ++++--- .../META-INF/MANIFEST.MF | 2 +- .../scxml/hu.bme.mit.gamma.scxml.transformation/.classpath | 6 +++++- .../.settings/org.eclipse.jdt.core.prefs | 7 ++++--- .../META-INF/MANIFEST.MF | 2 +- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.classpath b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.classpath index e801ebfb4..81fe078c2 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.classpath +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.settings/org.eclipse.jdt.core.prefs b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.settings/org.eclipse.jdt.core.prefs index c9545f06a..d4540a53f 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,10 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=17 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF index 41bb72596..84827f024 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/META-INF/MANIFEST.MF @@ -4,7 +4,7 @@ Bundle-Name: SCXML To Gamma Transformer Commandhandler Bundle-SymbolicName: hu.bme.mit.gamma.scxml.transformation.commandhandler;singleton:=true Bundle-Version: 1.0.0.qualifier Automatic-Module-Name: hu.bme.mit.gamma.scxml.transformation.commandhandler -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-17 Require-Bundle: org.eclipse.core.commands, ac.soton.scxml, hu.bme.mit.gamma.scxml.transformation, diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.classpath b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.classpath index 47ce7cd07..5cf859b24 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.classpath +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.classpath @@ -1,6 +1,10 @@ - + + + + + diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.settings/org.eclipse.jdt.core.prefs b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.settings/org.eclipse.jdt.core.prefs index c9545f06a..d4540a53f 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,10 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=17 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF index de2e53465..ec6fd76e9 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF @@ -4,7 +4,7 @@ Bundle-Name: SCXML To Gamma Transformation Bundle-SymbolicName: hu.bme.mit.gamma.scxml.transformation;singleton:=true Bundle-Version: 1.0.0.qualifier Automatic-Module-Name: hu.bme.mit.gamma.scxml.transformation -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-17 Require-Bundle: ac.soton.scxml, hu.bme.mit.gamma.statechart.model, com.google.guava, From 81c46636f0f06a4f3131062940d33470ed8bd696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Fri, 4 Nov 2022 13:36:58 +0100 Subject: [PATCH 18/30] Introduce composite SCXML model transformation --- .../commandhandler/CommandHandler.java | 42 +++--- .../transformation/AbstractTransformer.xtend | 6 - .../transformation/ActionTransformer.xtend | 4 +- .../AtomicElementTransformer.xtend | 10 ++ .../CompositeElementTransformer.xtend | 10 ++ .../CompositeTraceability.xtend | 127 ++++++++++++++++++ .../transformation/DataTransformer.xtend | 4 +- .../transformation/EventTransformer.xtend | 4 +- .../transformation/InterfaceTransformer.xtend | 4 +- .../gamma/scxml/transformation/Namings.xtend | 1 + .../transformation/PortTransformer.xtend | 4 +- .../ScxmlGammaExpressionTransformer.xtend | 4 +- .../ScxmlToGammaCompositeTransformer.xtend | 99 ++++++++++++++ .../ScxmlToGammaStatechartTransformer.xtend | 15 +-- ...ity.xtend => StatechartTraceability.xtend} | 41 +++--- .../transformation/TriggerTransformer.xtend | 4 +- 16 files changed, 310 insertions(+), 69 deletions(-) create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend rename plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/{Traceability.xtend => StatechartTraceability.xtend} (92%) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index f959f1332..63acd2448 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -1,6 +1,8 @@ package hu.bme.mit.gamma.scxml.transformation.commandhandler; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -17,13 +19,14 @@ import org.eclipse.ui.handlers.HandlerUtil; import ac.soton.scxml.ScxmlScxmlType; -import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaStatechartTransformer; -import hu.bme.mit.gamma.scxml.transformation.Traceability; -import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter; +import hu.bme.mit.gamma.scxml.transformation.CompositeTraceability; +import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaCompositeTransformer; +import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent; +import hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures; +import hu.bme.mit.gamma.statechart.interface_.Component; import hu.bme.mit.gamma.statechart.interface_.Interface; import hu.bme.mit.gamma.statechart.interface_.Package; import hu.bme.mit.gamma.statechart.language.ui.serializer.StatechartLanguageSerializer; -import hu.bme.mit.gamma.statechart.statechart.StatechartDefinition; import hu.bme.mit.gamma.statechart.util.StatechartUtil; import hu.bme.mit.gamma.util.FileUtil; import hu.bme.mit.gamma.util.GammaEcoreUtil; @@ -57,34 +60,33 @@ public Object execute(ExecutionEvent event) throws ExecutionException { ScxmlScxmlType scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(object, ScxmlScxmlType.class); // Model processing - ScxmlToGammaStatechartTransformer statechartTransformer = new ScxmlToGammaStatechartTransformer(scxmlRoot); - Traceability traceability = statechartTransformer.execute(); + ScxmlToGammaCompositeTransformer compositeTransformer = new ScxmlToGammaCompositeTransformer(scxmlRoot); + CompositeTraceability traceability = compositeTransformer.execute(); // Interfaces and type declarations have to be explicitly serialized in another package - List gammaInterfaces = traceability.getAllInterfaces(); + List gammaInterfaces = new ArrayList(traceability.getInterfaces()); Package gammaInterfacePackage = statechartUtil.wrapIntoPackage(gammaInterfaces.get(0)); gammaInterfaces.remove(0); gammaInterfacePackage.getInterfaces().addAll(gammaInterfaces); - // Pack and serialize statechart - StatechartDefinition statechartDefinition = traceability.getStatechartDefinition(scxmlRoot); - Package gammaStatechartPackage = statechartUtil.wrapIntoPackageAndAddImports(statechartDefinition); - - // Pack and serialize adapter - AsynchronousAdapter adapter = traceability.getAdapter(); - Package gammaAdapterPackage = statechartUtil.wrapIntoPackageAndAddImports(adapter); + // Pack and serialize asynchronous component + AsynchronousComponent rootComponent = traceability.getRootComponent(); + Package gammaCompositePackage = statechartUtil.wrapIntoPackage(rootComponent); + Collection components = traceability.getComponents(); + gammaCompositePackage.getComponents().addAll(components); + gammaCompositePackage.getImports().addAll( + StatechartModelDerivedFeatures.getImportablePackages(gammaCompositePackage)); + gammaCompositePackage.getImports().remove(gammaCompositePackage); StatechartLanguageSerializer packageSerializer = new StatechartLanguageSerializer(); logger.log(Level.INFO, "Start serializing Gamma packages..."); String declarationsPackageFileName = extensionlessFileName + "Declarations.gcd"; packageSerializer.serialize(gammaInterfacePackage, parentPath, declarationsPackageFileName); - - String statechartPackageFileName = extensionlessFileName + ".gcd"; - packageSerializer.serialize(gammaStatechartPackage, parentPath, statechartPackageFileName); - - String adapterPackageFileName = extensionlessFileName + "Adapter.gcd"; - packageSerializer.serialize(gammaAdapterPackage, parentPath, adapterPackageFileName); + //String compositePackageFileName = extensionlessFileName + ".gsm"; + //ecoreUtil.normalSave(gammaCompositePackage, parentPath, compositePackageFileName); + String compositePackageFileName = extensionlessFileName + ".gcd"; + packageSerializer.serialize(gammaCompositePackage, parentPath, compositePackageFileName); logger.log(Level.INFO, "The SCXML - Gamma statechart transformation has finished."); diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend index 662d28e69..6b5f95729 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend @@ -15,8 +15,6 @@ import java.util.logging.Logger abstract class AbstractTransformer { - protected final Traceability traceability - protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE protected final extension StatechartUtil statechartUtil = StatechartUtil.INSTANCE protected final extension ActionUtil actionUtil = ActionUtil.INSTANCE @@ -32,9 +30,5 @@ abstract class AbstractTransformer { protected final ExpressionTypeDeterminator2 expressionTypeDeterminator = ExpressionTypeDeterminator2.INSTANCE protected final Logger logger = Logger.getLogger("GammaLogger") - - new(Traceability traceability) { - this.traceability = traceability - } } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index 298753919..d207b990b 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -12,14 +12,14 @@ import hu.bme.mit.gamma.statechart.interface_.Port import java.util.logging.Level import org.eclipse.emf.ecore.EObject -class ActionTransformer extends AbstractTransformer { +class ActionTransformer extends AtomicElementTransformer { protected final extension PortTransformer portTransformer protected final extension InterfaceTransformer interfaceTransformer protected final extension EventTransformer eventTransformer protected final extension ScxmlGammaExpressionTransformer expressionTransformer - new(Traceability traceability) { + new(StatechartTraceability traceability) { super(traceability) this.portTransformer = new PortTransformer(traceability) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend new file mode 100644 index 000000000..e570efb79 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend @@ -0,0 +1,10 @@ +package hu.bme.mit.gamma.scxml.transformation + +abstract class AtomicElementTransformer extends AbstractTransformer { + + protected final StatechartTraceability traceability + + new(StatechartTraceability traceability) { + this.traceability = traceability + } +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend new file mode 100644 index 000000000..2507d3552 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend @@ -0,0 +1,10 @@ +package hu.bme.mit.gamma.scxml.transformation + +abstract class CompositeElementTransformer extends AbstractTransformer { + + protected final CompositeTraceability traceability + + new(CompositeTraceability traceability) { + this.traceability = traceability + } +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend new file mode 100644 index 000000000..3c22c5072 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -0,0 +1,127 @@ +package hu.bme.mit.gamma.scxml.transformation + +import ac.soton.scxml.ScxmlInvokeType +import ac.soton.scxml.ScxmlScxmlType +import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent +import hu.bme.mit.gamma.statechart.composite.AsynchronousComponentInstance +import hu.bme.mit.gamma.statechart.interface_.Event +import hu.bme.mit.gamma.statechart.interface_.Interface +import java.util.Map + +import static com.google.common.base.Preconditions.checkNotNull +import org.eclipse.emf.common.util.URI + +class CompositeTraceability { + + // Root element of the composite SCXML statechart model to transform. + protected final ScxmlScxmlType scxmlRoot + + // Resulting root component + protected AsynchronousComponent rootComponent + + // TODO Add interfaces, events, ports, bindings and channels + // (Needed for the declarations package and serialization of the components package.) + + protected final Map statecharts = newHashMap + protected final Map instances = newHashMap + + // Global mappings: Interfaces, events, declarations + protected final Map interfaces = newHashMap + protected final Map, Event> inEvents = newHashMap + protected final Map, Event> outEvents = newHashMap + + // - Asynchronous Component + new(ScxmlScxmlType scxmlRoot) { + this.scxmlRoot = scxmlRoot + } + + def getScxmlRoot() { + return scxmlRoot + } + + def getRootComponent() { + return rootComponent + } + + def setRootComponent(AsynchronousComponent rootComponent) { + this.rootComponent = rootComponent + } + + // String URI of the SCXML statechart definition source - Statechart Traceability + def putTraceability(String statechartUri, StatechartTraceability statechartTraceability) { + checkNotNull(statechartUri) + checkNotNull(statechartTraceability) + statecharts += statechartUri -> statechartTraceability + } + + def getTraceability(String statechartUri) { + checkNotNull(statechartUri) + val statechartTraceability = statecharts.get(statechartUri) + checkNotNull(statechartTraceability) + return statechartTraceability + } + + def getTraceability(ScxmlScxmlType scxmlRoot) { + checkNotNull(scxmlRoot) + val statechartTraceability = statecharts.values.filter[it.scxmlRoot === scxmlRoot].head + checkNotNull(statechartTraceability) + return statechartTraceability + } + + def containsTraceability(String statechartUri) { + checkNotNull(statechartUri) + return statecharts.containsKey(statechartUri) + } + + // - Asynchronous Component Instance + def putComponentInstance(ScxmlInvokeType scxmlInvoke, AsynchronousComponentInstance instance) { + checkNotNull(scxmlInvoke) + checkNotNull(instance) + instances += scxmlInvoke -> instance + } + + def getComponentInstance(ScxmlInvokeType scxmlInvoke) { + checkNotNull(scxmlInvoke) + val instance = instances.get(scxmlInvoke) + checkNotNull(instance) + return instance + } + + // + + def getInEvents() { + return inEvents + } + + def getOutEvents() { + return outEvents + } + + def getInstances() { + return instances + } + + def getStatecharts() { + return statecharts.values.toList + } + + // + + def getInterfaces() { + return interfaces.values + } + + def getComponents() { + val statechartTraceabilities = statecharts.values + return (instances.values.map[it.getType] + + statechartTraceabilities.map[it.getAdapter] + + statechartTraceabilities.map[it.getStatechart] + ).toSet + } + + def createStatechartTraceability(ScxmlScxmlType scxmlRoot) { + return new StatechartTraceability(scxmlRoot, + interfaces, inEvents, outEvents + ) + } +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend index 01b00ea2f..dc85254bf 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend @@ -4,9 +4,9 @@ import ac.soton.scxml.ScxmlDataType import hu.bme.mit.gamma.expression.model.VariableDeclaration import java.util.logging.Level -class DataTransformer extends AbstractTransformer { +class DataTransformer extends AtomicElementTransformer { - new(Traceability traceability) { + new(StatechartTraceability traceability) { super(traceability) } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend index 44cf4600d..1bf4aca74 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend @@ -5,8 +5,8 @@ import hu.bme.mit.gamma.statechart.interface_.EventDirection import static hu.bme.mit.gamma.scxml.transformation.Namings.* import hu.bme.mit.gamma.statechart.interface_.Interface -class EventTransformer extends AbstractTransformer { - new(Traceability traceability) { +class EventTransformer extends AtomicElementTransformer { + new(StatechartTraceability traceability) { super(traceability) } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend index 5f52f7c03..d9137f0d1 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend @@ -3,8 +3,8 @@ package hu.bme.mit.gamma.scxml.transformation import static com.google.common.base.Preconditions.checkState import static hu.bme.mit.gamma.scxml.transformation.Namings.* -class InterfaceTransformer extends AbstractTransformer { - new(Traceability traceability) { +class InterfaceTransformer extends AtomicElementTransformer { + new(StatechartTraceability traceability) { super(traceability) } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index 32730b5eb..9d6e73ab3 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -23,6 +23,7 @@ class Namings { def static String getInternalEventQueueName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»InternalEventQueue''' def static String getExternalEventQueueName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»ExternalEventQueue''' + def static String getCompositeStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' def static String getStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' def static String getRegionName(String scxmlElementName) '''«scxmlElementName»Region''' diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend index de9af1741..cbca9a0ed 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend @@ -6,8 +6,8 @@ import static com.google.common.base.Preconditions.checkState import static hu.bme.mit.gamma.scxml.transformation.Namings.* import hu.bme.mit.gamma.statechart.interface_.Interface -class PortTransformer extends AbstractTransformer { - new(Traceability traceability) { +class PortTransformer extends AtomicElementTransformer { + new(StatechartTraceability traceability) { super(traceability) } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend index ca5de03bc..73f8a5f4e 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend @@ -1,8 +1,8 @@ package hu.bme.mit.gamma.scxml.transformation -class ScxmlGammaExpressionTransformer extends AbstractTransformer { +class ScxmlGammaExpressionTransformer extends AtomicElementTransformer { - new(Traceability traceability) { + new(StatechartTraceability traceability) { super(traceability) } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend new file mode 100644 index 000000000..1427214a4 --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend @@ -0,0 +1,99 @@ +package hu.bme.mit.gamma.scxml.transformation + +import ac.soton.scxml.ScxmlInvokeType +import ac.soton.scxml.ScxmlScxmlType +import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent +import java.util.List +import org.eclipse.emf.common.util.URI + +import static ac.soton.scxml.ScxmlModelDerivedFeatures.* +import static hu.bme.mit.gamma.scxml.transformation.Namings.* + +class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { + + // Root element of the SCXML statechart model to transform + protected final ScxmlScxmlType scxmlRoot + + // Contained elements invoking SCXML substatecharts + protected List invokes + + new(ScxmlScxmlType scxmlRoot) { + this(scxmlRoot, + new CompositeTraceability(scxmlRoot) + ) + } + + new(ScxmlScxmlType scxmlRoot, CompositeTraceability traceability) { + super(traceability) + this.scxmlRoot = scxmlRoot + } + + def execute() { + val rootComponent = scxmlRoot.transform + traceability.rootComponent = rootComponent as AsynchronousComponent + + return traceability + } + + protected def AsynchronousComponent transform(ScxmlScxmlType scxmlRoot) { + invokes = getAllInvokes(scxmlRoot) + + if (invokes.empty) { + return scxmlRoot.transformAtomic + } + else { + for (invoke : invokes) { + var src = invoke.src + + // TODO Load and transform invoked statechart types only + // when the composite traceability object does not contain the statechart. + if (!traceability.containsTraceability(src)) { + val subcomponentRoot = loadSubcomponent(src) + + val newStatechartTraceability = traceability.createStatechartTraceability(subcomponentRoot) + traceability.putTraceability(src, newStatechartTraceability) + + subcomponentRoot.transformAtomic + } + } + + return scxmlRoot.transformComposite + } + } + + private def loadSubcomponent(String path) { + val fileURI = URI.createPlatformResourceURI(path, true); + val documentRoot = ecoreUtil.normalLoad(fileURI); + val scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(documentRoot, ScxmlScxmlType); + return scxmlRoot + } + + protected def transformAtomic(ScxmlScxmlType scxmlRoot) { + val statechartTraceability = traceability.getTraceability(scxmlRoot) + val statechartTransformer = new ScxmlToGammaStatechartTransformer(scxmlRoot, statechartTraceability) + statechartTransformer.execute + + return statechartTraceability.getAdapter + } + + protected def transformComposite(ScxmlScxmlType scxmlRoot) { + val gammaComposite = createScheduledAsynchronousCompositeComponent + gammaComposite.name = getCompositeStatechartName(scxmlRoot) + + // Instantiate transformed invoked child statecharts + for (invoke : invokes) { + val statechartTraceability = traceability.getTraceability(invoke.src) + + // TODO Extend to deeper composition hierarchy levels + val gammaSubcomponentType = statechartTraceability.adapter as AsynchronousComponent + + val gammaSubcomponent = gammaSubcomponentType.instantiateAsynchronousComponent + gammaComposite.components += gammaSubcomponent + + traceability.putComponentInstance(invoke, gammaSubcomponent) + } + + return gammaComposite + } + +} \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index adc36693d..b4030b5cc 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -19,14 +19,15 @@ import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition import java.math.BigInteger -import java.util.logging.Level +import java.util.logging.Logger import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* +import java.util.logging.Level // TODO Scoping in variable transformation and assignment // TODO History, parallel -class ScxmlToGammaStatechartTransformer extends AbstractTransformer { +class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { protected final extension ActionTransformer actionTransformer protected final extension DataTransformer dataTransformer @@ -41,13 +42,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Root element of the Gamma statechart definition as the transformation result protected final SynchronousStatechartDefinition gammaStatechart - new(ScxmlScxmlType scxmlRoot) { - this(scxmlRoot, - new Traceability(scxmlRoot) - ) - } - - new(ScxmlScxmlType scxmlRoot, Traceability traceability) { + new(ScxmlScxmlType scxmlRoot, StatechartTraceability traceability) { super(traceability) this.scxmlRoot = scxmlRoot @@ -63,7 +58,7 @@ class ScxmlToGammaStatechartTransformer extends AbstractTransformer { // Transformation of the SCXML root element and its contents recursively def execute() { - traceability.put(scxmlRoot, gammaStatechart) + traceability.setStatechart(gammaStatechart) logger.log(Level.INFO, "Transforming root element (" + scxmlRoot.name + ")") diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend similarity index 92% rename from plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend rename to plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend index d91a15800..7fd63a740 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Traceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend @@ -27,16 +27,13 @@ import org.eclipse.emf.ecore.EObject import static com.google.common.base.Preconditions.checkNotNull -class Traceability { +class StatechartTraceability { - // Root element of the SCXML statechart model to transform. - // This Traceability class could be able to store multiple - // ScxmlScxmlType - SynchronousStatechartDefinition pairs, but for now, - // we assume only one SCMXL statechart to be transformed (from an root element). + // Root element of the atomic SCXML statechart model to transform. protected final ScxmlScxmlType scxmlRoot + protected SynchronousStatechartDefinition statechart protected AsynchronousAdapter adapter - - protected final Map statechartDefinitions = newHashMap + protected final Map parallels = newHashMap protected final Map states = newHashMap protected final Map finals = newHashMap @@ -50,19 +47,29 @@ class Traceability { // Works only if variables are globally unique and have a global scope protected final Map variables = newHashMap + // Internal mappings (internal to the statechart) protected Port defaultPort protected Interface defaultInterface protected final Map defaultInterfacePorts = newHashMap protected final Map ports = newHashMap - protected final Map interfaces = newHashMap - protected final Map, Event> inEvents = newHashMap - protected final Map, Event> outEvents = newHashMap + + // Global mappings (from composite traceability) + protected final Map interfaces + protected final Map, Event> inEvents + protected final Map, Event> outEvents protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE // - Synchronous Statechart Definition - new(ScxmlScxmlType scxmlRoot) { + new(ScxmlScxmlType scxmlRoot, + Map interfaces, + Map, Event> inEvents, + Map, Event> outEvents + ) { this.scxmlRoot = scxmlRoot + this.interfaces = interfaces + this.inEvents = inEvents + this.outEvents = outEvents } def getScxmlRoot() { @@ -77,17 +84,13 @@ class Traceability { return adapter } - def put(ScxmlScxmlType scxmlRoot, SynchronousStatechartDefinition gammaStatechart) { - checkNotNull(scxmlRoot) + def setStatechart(SynchronousStatechartDefinition gammaStatechart) { checkNotNull(gammaStatechart) - statechartDefinitions += scxmlRoot -> gammaStatechart + statechart = gammaStatechart } - def getStatechartDefinition(ScxmlScxmlType scxmlRoot) { - checkNotNull(scxmlRoot) - val gammaStatechart = statechartDefinitions.get(scxmlRoot) - checkNotNull(gammaStatechart) - return gammaStatechart + def getStatechart() { + return statechart } // - State (with orthogonal Region children) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend index c974f30e7..aa1af20cd 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -3,13 +3,13 @@ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port -class TriggerTransformer extends AbstractTransformer { +class TriggerTransformer extends AtomicElementTransformer { protected final extension PortTransformer portTransformer protected final extension InterfaceTransformer interfaceTransformer protected final extension EventTransformer eventTransformer - new(Traceability traceability) { + new(StatechartTraceability traceability) { super(traceability) this.portTransformer = new PortTransformer(traceability) From d7be7918c5acf44c6634a91bc6fc3cf260b75801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Fri, 2 Dec 2022 13:40:37 +0100 Subject: [PATCH 19/30] Add transformation of port bindings and channels --- .../transformation/ActionTransformer.xtend | 3 +- .../CompositeTraceability.xtend | 41 ++- .../transformation/PortTransformer.xtend | 35 ++- .../ScxmlToGammaCompositeTransformer.xtend | 146 +++++++++- .../ScxmlToGammaStatechartTransformer.xtend | 267 ++++++++++-------- .../transformation/TriggerTransformer.xtend | 3 +- 6 files changed, 369 insertions(+), 126 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index d207b990b..981cbb729 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -9,6 +9,7 @@ import hu.bme.mit.gamma.action.model.Action import hu.bme.mit.gamma.expression.model.VariableDeclaration import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port +import hu.bme.mit.gamma.statechart.interface_.RealizationMode import java.util.logging.Level import org.eclipse.emf.ecore.EObject @@ -95,7 +96,7 @@ class ActionTransformer extends AtomicElementTransformer { if (tokens.size >= 3) { val portName = tokens.head - gammaPort = getOrTransformPortByName(gammaInterface, portName) + gammaPort = getOrTransformPortByName(gammaInterface, portName, RealizationMode.PROVIDED) } else { gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend index 3c22c5072..d16312e02 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -6,10 +6,10 @@ import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent import hu.bme.mit.gamma.statechart.composite.AsynchronousComponentInstance import hu.bme.mit.gamma.statechart.interface_.Event import hu.bme.mit.gamma.statechart.interface_.Interface +import hu.bme.mit.gamma.statechart.interface_.Port import java.util.Map import static com.google.common.base.Preconditions.checkNotNull -import org.eclipse.emf.common.util.URI class CompositeTraceability { @@ -24,6 +24,7 @@ class CompositeTraceability { protected final Map statecharts = newHashMap protected final Map instances = newHashMap + protected final Map ports = newHashMap // Global mappings: Interfaces, events, declarations protected final Map interfaces = newHashMap @@ -61,9 +62,19 @@ class CompositeTraceability { return statechartTraceability } + // TODO Simplify map structure and getter. + def getTraceabilityById(String scxmlInvokeId) { + checkNotNull(scxmlInvokeId) + val invoke = instances.keySet.findFirst[invoke | invoke.id == scxmlInvokeId] + checkNotNull(invoke) + val statechartTraceability = statecharts.filter[source, _ | source == invoke.src].values.head + checkNotNull(statechartTraceability) + return statechartTraceability + } + def getTraceability(ScxmlScxmlType scxmlRoot) { checkNotNull(scxmlRoot) - val statechartTraceability = statecharts.values.filter[it.scxmlRoot === scxmlRoot].head + val statechartTraceability = statecharts.values.findFirst[it.scxmlRoot === scxmlRoot] checkNotNull(statechartTraceability) return statechartTraceability } @@ -87,6 +98,32 @@ class CompositeTraceability { return instance } + def getComponentInstance(String scxmlInvokeId) { + checkNotNull(scxmlInvokeId) + val instance = instances.filter[invoke, _ | invoke.id == scxmlInvokeId].values.head + checkNotNull(instance) + return instance + } + + // Ports by string identifier (for event strings like 'port.interface.event) + def putPort(String scxmlPortName, Port gammaPort) { + checkNotNull(scxmlPortName) + checkNotNull(gammaPort) + ports += scxmlPortName -> gammaPort + } + + def getPort(String scxmlPortName) { + checkNotNull(scxmlPortName) + val gammaPort = ports.get(scxmlPortName) + checkNotNull(gammaPort) + return gammaPort + } + + def containsPort(String scxmlPortName) { + checkNotNull(scxmlPortName) + return ports.containsKey(scxmlPortName) + } + // def getInEvents() { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend index cbca9a0ed..8abbf727a 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend @@ -1,14 +1,32 @@ package hu.bme.mit.gamma.scxml.transformation +import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.RealizationMode import static com.google.common.base.Preconditions.checkState import static hu.bme.mit.gamma.scxml.transformation.Namings.* -import hu.bme.mit.gamma.statechart.interface_.Interface class PortTransformer extends AtomicElementTransformer { + + protected final extension InterfaceTransformer interfaceTransformer + new(StatechartTraceability traceability) { super(traceability) + + this.interfaceTransformer = new InterfaceTransformer(traceability) + } + + // Gets or creates an interface and a port realizing the interface in the specified mode. + def getOrTransformPort(String scxmlPortName, + String scxmlInterfaceName, RealizationMode realizationMode + ) { + val gammaInterfaceName = getInterfaceName(scxmlInterfaceName) + val gammaInterface = interfaceTransformer.getOrTransformInterfaceByName(gammaInterfaceName) + + val gammaPortName = getPortName(scxmlPortName) + val gammaPort = getOrTransformPortByName(gammaInterface, gammaPortName, realizationMode) + + return gammaPort } def getOrCreateDefaultPort() { @@ -64,23 +82,28 @@ class PortTransformer extends AtomicElementTransformer { return gammaPort } - def getOrTransformPortByName(Interface gammaInterface, String portName) { + def getOrTransformPortByName(Interface gammaInterface, + String portName, RealizationMode realizationMode + ) { checkState(gammaInterface !== null) checkState(portName !== null) + checkState(realizationMode !== null) + if (traceability.containsPort(portName)) { return traceability.getPort(portName) } else { - val gammaPort = transformPortByName(gammaInterface, portName) + val gammaPort = transformPortByName(gammaInterface, portName, realizationMode) traceability.putPort(portName, gammaPort) return gammaPort } } - // For now, all ports realize their interfaces in provided mode. - protected def transformPortByName(Interface gammaInterface, String portName) { + protected def transformPortByName(Interface gammaInterface, + String portName, RealizationMode realizationMode + ) { val gammaInterfaceRealization = createInterfaceRealization - gammaInterfaceRealization.realizationMode = RealizationMode.PROVIDED + gammaInterfaceRealization.realizationMode = realizationMode gammaInterfaceRealization.interface = gammaInterface val gammaPort = createPort diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend index 1427214a4..999bcdfbc 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend @@ -1,16 +1,22 @@ package hu.bme.mit.gamma.scxml.transformation +import ac.soton.scxml.ScxmlDataType import ac.soton.scxml.ScxmlInvokeType import ac.soton.scxml.ScxmlScxmlType import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent +import hu.bme.mit.gamma.statechart.interface_.RealizationMode import java.util.List import org.eclipse.emf.common.util.URI import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* +// TODO Check features of both composite and atomic components. +// Transform these features for both kinds of statecharts. class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { + protected final extension PortTransformer portTransformer + // Root element of the SCXML statechart model to transform protected final ScxmlScxmlType scxmlRoot @@ -26,6 +32,9 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { new(ScxmlScxmlType scxmlRoot, CompositeTraceability traceability) { super(traceability) this.scxmlRoot = scxmlRoot + + val portTraceability = traceability.createStatechartTraceability(scxmlRoot) + this.portTransformer = new PortTransformer(portTraceability) } def execute() { @@ -43,10 +52,8 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { } else { for (invoke : invokes) { - var src = invoke.src + var src = invoke.src // TODO Check src | srcexpr - // TODO Load and transform invoked statechart types only - // when the composite traceability object does not contain the statechart. if (!traceability.containsTraceability(src)) { val subcomponentRoot = loadSubcomponent(src) @@ -88,12 +95,145 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { val gammaSubcomponentType = statechartTraceability.adapter as AsynchronousComponent val gammaSubcomponent = gammaSubcomponentType.instantiateAsynchronousComponent + gammaSubcomponent.name = invoke.id gammaComposite.components += gammaSubcomponent traceability.putComponentInstance(invoke, gammaSubcomponent) } + // Create ports, port bindings and channels in the composite component + val datamodels = scxmlRoot.datamodel + if (datamodels !== null) { + val datamodel = datamodels.head + if (datamodel !== null) { + val dataElements = getDataElements(datamodel) + + // TODO Move string literal parts of names to Namings + val portDataElements = dataElements.filter [ it | + it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("pro_port_") || + it.id.startsWith("req_port_") + ] + for (portData : portDataElements) { + val gammaPort = portData.getOrCreatePort + gammaComposite.ports += gammaPort + } + + val bindingDataElements = dataElements.filter [ it | + it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("binding_") + ] + for (binding : bindingDataElements) { + val gammaPortBinding = binding.createBinding + gammaComposite.portBindings += gammaPortBinding + } + + val channelDataElements = dataElements.filter [ it | + it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("channel_") + ] + for (channel : channelDataElements) { + val gammaChannel = channel.createChannel + gammaComposite.channels += gammaChannel + } + } + } + return gammaComposite } + protected def getOrCreatePort(ScxmlDataType portData) { + val isProvided = portData.id.startsWith("pro_port_") + val realizationMode = isProvided ? RealizationMode.PROVIDED : RealizationMode.REQUIRED + + // Get port name and interface name from port descriptor string + val portString = portData.expr.trim + val tokens = portString.split("\\.") + if (tokens.size < 1 || tokens.size > 2) { + throw new IllegalArgumentException( + "Port descriptor " + portString + " does not contain exactly 1 or 2 dot separated tokens." + ) + } + + var scxmlInterfaceName = "" + var scxmlPortName = "" + + if (tokens.size == 1) { + scxmlInterfaceName = portString + scxmlPortName = portString + } else { + scxmlInterfaceName = tokens.get(tokens.size - 1) + scxmlPortName = tokens.head + } + // + + val gammaPort = portTransformer.getOrTransformPort( + scxmlPortName, + scxmlInterfaceName, + realizationMode + ) + + traceability.putPort(scxmlPortName, gammaPort) + + return gammaPort + } + + // TODO + protected def createBinding(ScxmlDataType bindingData) { + // Get binding endpoint data + val bindingString = bindingData.expr.trim + val tokens = bindingString.split("\\.|\\s*\\-\\s*") + if (tokens.size != 3) { + throw new IllegalArgumentException( + "Binding descriptor " + bindingString + " does not contain exactly 3 dot separated tokens." + ) + } + + val sourcePortName = tokens.get(0) + val targetInstanceName = tokens.get(1) + val targetPortName = tokens.get(2) + + // + + val gammaSourcePort = traceability.getPort(sourcePortName) + val gammaInstancePortReference = createInstancePortReference(targetInstanceName, targetPortName) + + val gammaPortBinding = createPortBinding(gammaSourcePort, gammaInstancePortReference) + return gammaPortBinding + } + + // TODO + protected def createChannel(ScxmlDataType channelData) { + // Get channel endpoint data + val channelString = channelData.expr.trim + val tokens = channelString.split("\\.|\\s*\\-\\s*") + if (tokens.size != 4) { + throw new IllegalArgumentException( + "Channel descriptor " + channelString + " does not contain exactly 4 dot separated tokens." + ) + } + + val sourceInstanceName = tokens.get(0) + val sourcePortName = tokens.get(1) + val targetInstanceName = tokens.get(2) + val targetPortName = tokens.get(3) + + // + + val sourceInstancePortReference = createInstancePortReference(sourceInstanceName, sourcePortName) + val targetInstancePortReference = createInstancePortReference(targetInstanceName, targetPortName) + + val gammaChannel = createChannel(sourceInstancePortReference, targetInstancePortReference) + return gammaChannel + } + + private def createInstancePortReference(String instanceName, String scxmlPortName) { + val instance = traceability.getComponentInstance(instanceName) + + // TODO Make it more performant to get statechart traceability + // by instance invokeId or source URI. + val statechartTraceability = traceability.getTraceabilityById(instanceName) + val port = statechartTraceability.getPort(scxmlPortName) + + + val instancePortReference = createInstancePortReference(instance, port) + return instancePortReference + } } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index b4030b5cc..434bb242a 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -1,6 +1,7 @@ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.HistoryTypeDatatype +import ac.soton.scxml.ScxmlDataType import ac.soton.scxml.ScxmlFinalType import ac.soton.scxml.ScxmlHistoryType import ac.soton.scxml.ScxmlInitialType @@ -13,220 +14,268 @@ import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter import hu.bme.mit.gamma.statechart.composite.ControlFunction import hu.bme.mit.gamma.statechart.composite.DiscardStrategy import hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures +import hu.bme.mit.gamma.statechart.interface_.RealizationMode import hu.bme.mit.gamma.statechart.statechart.EntryState +import hu.bme.mit.gamma.statechart.statechart.GuardEvaluation import hu.bme.mit.gamma.statechart.statechart.InitialState +import hu.bme.mit.gamma.statechart.statechart.OrthogonalRegionSchedulingOrder +import hu.bme.mit.gamma.statechart.statechart.SchedulingOrder import hu.bme.mit.gamma.statechart.statechart.State import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition +import hu.bme.mit.gamma.statechart.statechart.TransitionPriority import java.math.BigInteger -import java.util.logging.Logger +import java.util.logging.Level import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* -import java.util.logging.Level // TODO Scoping in variable transformation and assignment // TODO History, parallel class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { - + protected final extension ActionTransformer actionTransformer protected final extension DataTransformer dataTransformer + protected final extension PortTransformer portTransformer protected final extension TriggerTransformer triggerTransformer - + // Root element of the SCXML statechart model to transform protected final ScxmlScxmlType scxmlRoot - + // Asynchronous wrapper component around the synchronous statechart definition protected AsynchronousAdapter adapter - + // Root element of the Gamma statechart definition as the transformation result protected final SynchronousStatechartDefinition gammaStatechart - + new(ScxmlScxmlType scxmlRoot, StatechartTraceability traceability) { super(traceability) - + this.scxmlRoot = scxmlRoot this.adapter = null this.gammaStatechart = createSynchronousStatechartDefinition => [ it.name = getStatechartName(scxmlRoot) ] - + this.actionTransformer = new ActionTransformer(traceability) this.dataTransformer = new DataTransformer(traceability) + this.portTransformer = new PortTransformer(traceability) this.triggerTransformer = new TriggerTransformer(traceability) } - + // Transformation of the SCXML root element and its contents recursively def execute() { traceability.setStatechart(gammaStatechart) - + logger.log(Level.INFO, "Transforming root element (" + scxmlRoot.name + ")") + + // Configure transition selection and execution + // TODO Check settings! + gammaStatechart.schedulingOrder = SchedulingOrder.BOTTOM_UP + gammaStatechart.orthogonalRegionSchedulingOrder = OrthogonalRegionSchedulingOrder.SEQUENTIAL + gammaStatechart.transitionPriority = TransitionPriority.ORDER_BASED; + gammaStatechart.guardEvaluation = GuardEvaluation.BEGINNING_OF_STEP val datamodels = scxmlRoot.datamodel if (datamodels !== null) { val datamodel = datamodels.head if (datamodel !== null) { val dataElements = getDataElements(datamodel) - for (data : dataElements) { - val gammaVariableDeclaration = dataTransformer.transform(data) + + // TODO Move string literal parts of names to Namings + val portDataElements = dataElements.filter [ it | + it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("pro_port_") || + it.id.startsWith("req_port_") + ] + for (portData : portDataElements) { + val gammaPort = portData.getOrCreatePort + gammaStatechart.ports += gammaPort + } + + val variableDataElements = dataElements.filter[it|!portDataElements.contains(it)] + for (variableData : variableDataElements) { + val gammaVariableDeclaration = dataTransformer.transform(variableData) gammaStatechart.variableDeclarations += gammaVariableDeclaration } } } - + val mainRegion = createRegion => [ it.name = getRegionName(scxmlRoot.name) ] gammaStatechart.regions += mainRegion - + val scxmlStateNodes = getStateNodes(scxmlRoot) for (scxmlStateNode : scxmlStateNodes) { if (isParallel(scxmlStateNode)) { val parallel = scxmlStateNode as ScxmlParallelType mainRegion.stateNodes += parallel.transformParallel - } - else if (isState(scxmlStateNode)) { + } else if (isState(scxmlStateNode)) { val state = scxmlStateNode as ScxmlStateType mainRegion.stateNodes += state.transformState - } - else if (isFinal(scxmlStateNode)) { + } else if (isFinal(scxmlStateNode)) { val final = scxmlStateNode as ScxmlFinalType mainRegion.stateNodes += final.transformFinal - } - else { - throw new IllegalArgumentException( - "Object " + scxmlStateNode + " is of unknown SCXML type.") + } else { + throw new IllegalArgumentException("Object " + scxmlStateNode + " is of unknown SCXML type.") } } - + val transitions = getAllTransitions(scxmlRoot) for (transition : transitions) { transition.transformTransition } - + // Transform the SCXML root element's initial attribute, // or select its first child as initial state if it is not present. val gammaInitial = createInitialState => [ it.name = getInitialName(scxmlRoot) ] - mainRegion.stateNodes += gammaInitial - + mainRegion.stateNodes += gammaInitial + val scxmlInitialAttribute = scxmlRoot.initial val scxmlFirstInitialAttribute = scxmlInitialAttribute?.head if (scxmlFirstInitialAttribute !== null) { val gammaInitialTarget = traceability.getStateNodeById(scxmlFirstInitialAttribute) gammaInitial.createTransition(gammaInitialTarget) - } - else { + } else { val firstScxmlStateChild = getFirstChildStateNode(scxmlRoot) as ScxmlStateType val gammaInitialTarget = traceability.getState(firstScxmlStateChild) gammaInitial.createTransition(gammaInitialTarget) } - + // Add all transitions from initial states of Gamma compound states // specified by scxml initial attributes or document order gammaStatechart.transitions += traceability.getInitialTransitions - + // Add all ports from traceability if (traceability.getDefaultPort !== null) { gammaStatechart.ports += traceability.getDefaultPort } gammaStatechart.ports += traceability.defaultInterfacePorts.values gammaStatechart.ports += traceability.ports.values - + val adapter = wrapIntoAdapter traceability.adapter = adapter - + return traceability } - + + protected def getOrCreatePort(ScxmlDataType portData) { + val isProvided = portData.id.startsWith("pro_port_") + val realizationMode = isProvided ? RealizationMode.PROVIDED : RealizationMode.REQUIRED + + // Get port name and interface name from port descriptor string + val portString = portData.expr.trim + val tokens = portString.split("\\.") + if (tokens.size < 1 || tokens.size > 2) { + throw new IllegalArgumentException( + "Port descriptor " + portString + " does not contain exactly 1 or 2 dot separated tokens." + ) + } + + var scxmlInterfaceName = "" + var scxmlPortName = "" + + if (tokens.size == 1) { + scxmlInterfaceName = portString + scxmlPortName = portString + } else { + scxmlInterfaceName = tokens.get(tokens.size - 1) + scxmlPortName = tokens.head + } + // + + val gammaPort = portTransformer.getOrTransformPort( + scxmlPortName, + scxmlInterfaceName, + realizationMode + ) + return gammaPort + } + protected def AsynchronousAdapter wrapIntoAdapter() { adapter = gammaStatechart.wrapIntoAdapter(getAdapterName(scxmlRoot)) - + // Set control specification val controlSpecification = compositeModelFactory.createControlSpecification controlSpecification.trigger = interfaceModelFactory.createAnyTrigger controlSpecification.controlFunction = ControlFunction.RUN_ONCE - + adapter.controlSpecifications += controlSpecification - + // Create internal event queue // TODO Check capacity and priority val internalEventQueue = compositeModelFactory.createMessageQueue internalEventQueue.name = getInternalEventQueueName(scxmlRoot) internalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING internalEventQueue.priority = BigInteger.TWO - internalEventQueue.capacity = expressionUtil.toIntegerLiteral(10) - + internalEventQueue.capacity = expressionUtil.toIntegerLiteral(4) + // TODO Add only internal ports for (port : StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart)) { val reference = statechartModelFactory.createAnyPortEventReference reference.port = port internalEventQueue.eventReferences += reference } - + adapter.messageQueues += internalEventQueue - + // Create external event queue // TODO Check capacity and priority val externalEventQueue = compositeModelFactory.createMessageQueue externalEventQueue.name = getExternalEventQueueName(scxmlRoot) externalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING externalEventQueue.priority = BigInteger.ONE - externalEventQueue.capacity = expressionUtil.toIntegerLiteral(10) - + externalEventQueue.capacity = expressionUtil.toIntegerLiteral(4) + // TODO Add only external ports for (port : StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart)) { val reference = statechartModelFactory.createAnyPortEventReference reference.port = port externalEventQueue.eventReferences += reference } - + adapter.messageQueues.add(externalEventQueue) - + return adapter } - + protected def State transformParallel(ScxmlParallelType parallelNode) { logger.log(Level.INFO, "Transforming element (" + parallelNode.id + ")") - + val gammaParallel = createState => [ it.name = getParallelName(parallelNode) ] - + val scxmlStateNodes = getStateNodes(parallelNode) for (scxmlStateNode : scxmlStateNodes) { val region = createRegion => [ it.name = getRegionName(gammaParallel.name) ] gammaParallel.regions += region - + if (isParallel(scxmlStateNode)) { val parallel = scxmlStateNode as ScxmlParallelType region.stateNodes += parallel.transformParallel - } - else if (isState(scxmlStateNode)) { + } else if (isState(scxmlStateNode)) { val state = scxmlStateNode as ScxmlStateType region.stateNodes += state.transformState - } - else if (isFinal(scxmlStateNode)) { + } else if (isFinal(scxmlStateNode)) { val final = scxmlStateNode as ScxmlFinalType region.stateNodes += final.transformFinal - } - else { - throw new IllegalArgumentException( - "Object " + scxmlStateNode + " is of unknown SCXML type.") + } else { + throw new IllegalArgumentException("Object " + scxmlStateNode + " is of unknown SCXML type.") } } - + // TODO Transform history pseudo-states (by adding a wrapper compound state perhaps) // Initial-ok kicserélése a gyerek state-ekben, amely parallelekben találok historyt // Vagy history node hozzáadása minden gyerek régióhoz, ha van kívül history? /*val scxmlHistoryStates = parallelNode.history - for (scxmlHistoryState : scxmlHistoryStates) { - - }*/ - + * for (scxmlHistoryState : scxmlHistoryStates) { + * + }*/ // Transform onentry and onexit handlers val onentryActions = parallelNode.onentry for (onentryAction : onentryActions) { @@ -234,77 +283,72 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { gammaParallel.entryActions += onentryAction.transformOnentry } } - + val onexitActions = parallelNode.onexit for (onexitAction : onexitActions) { if (onexitAction !== null) { gammaParallel.exitActions += onexitAction.transformOnexit } } - + traceability.put(parallelNode, gammaParallel) - + return gammaParallel } - + protected def State transformState(ScxmlStateType scxmlState) { logger.log(Level.INFO, "Transforming element (" + scxmlState.id + ")") - + val gammaState = createState => [ it.name = getStateName(scxmlState) ] - + if (isCompoundState(scxmlState)) { val region = createRegion => [ it.name = getRegionName(gammaState.name) ] gammaState.regions += region - + val scxmlStateNodes = getStateNodes(scxmlState) for (scxmlStateNode : scxmlStateNodes) { if (isParallel(scxmlStateNode)) { val parallel = scxmlStateNode as ScxmlParallelType region.stateNodes += parallel.transformParallel - } - else if (isState(scxmlStateNode)) { + } else if (isState(scxmlStateNode)) { val state = scxmlStateNode as ScxmlStateType region.stateNodes += state.transformState - } - else if (isFinal(scxmlStateNode)) { + } else if (isFinal(scxmlStateNode)) { val final = scxmlStateNode as ScxmlFinalType region.stateNodes += final.transformFinal - } - else { + } else { throw new IllegalArgumentException( "Object " + scxmlStateNode + " is of unknown SCXML type.") } } - + // Transform history pseudo-states val scxmlHistoryStates = scxmlState.history for (scxmlHistoryState : scxmlHistoryStates) { region.stateNodes += scxmlHistoryState.transform } - + // Transform the state's initial element or attribute, // or select its first child as initial state if neither one above is present. val scxmlInitialElement = scxmlState.initial.head if (scxmlInitialElement !== null) { region.stateNodes += scxmlInitialElement.transform - } - else { + } else { val gammaInitial = createInitialState => [ it.name = getInitialName(scxmlState) ] - region.stateNodes += gammaInitial - + region.stateNodes += gammaInitial + val scxmlInitialAttribute = scxmlState.initial1.head if (scxmlInitialAttribute !== null) { val gammaInitialTarget = traceability.getStateNodeById(scxmlInitialAttribute) val initialTransition = gammaInitial.createTransition(gammaInitialTarget) traceability.putInitialTransition(initialTransition) - } - else { + } else { val firstScxmlStateChild = getFirstChildStateNode(scxmlState) as ScxmlStateType val gammaInitialTarget = traceability.getState(firstScxmlStateChild) val initialTransition = gammaInitial.createTransition(gammaInitialTarget) @@ -312,7 +356,7 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { } } } - + // Transform onentry and onexit handlers val onentryActions = scxmlState.onentry for (onentryAction : onentryActions) { @@ -327,19 +371,19 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { gammaState.exitActions += onexitAction.transformOnexit } } - + traceability.put(scxmlState, gammaState) - + return gammaState } - + protected def State transformFinal(ScxmlFinalType scxmlFinal) { logger.log(Level.INFO, "Transforming element (" + scxmlFinal.id + ")") - + val gammaFinal = createState => [ it.name = getFinalName(scxmlFinal) ] - + // Transform onentry and onexit handlers val onentryActions = scxmlFinal.onentry for (onentryAction : onentryActions) { @@ -354,87 +398,84 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { gammaFinal.exitActions += onexitAction.transformOnexit } } - + traceability.put(scxmlFinal, gammaFinal) - + return gammaFinal } - + protected def InitialState transform(ScxmlInitialType scxmlInitial) { logger.log(Level.INFO, "Transforming element") - + val parentState = getParentState(scxmlInitial) val gammaInitial = createInitialState => [ it.name = getInitialName(parentState) ] - + traceability.put(scxmlInitial, gammaInitial) - + return gammaInitial } - + protected def EntryState transform(ScxmlHistoryType scxmlHistory) { logger.log(Level.INFO, "Transforming element (" + scxmlHistory.id + ")") - + if (scxmlHistory.type == HistoryTypeDatatype.SHALLOW) { val gammaShallowHistory = createShallowHistoryState => [ it.name = getShallowHistoryName(scxmlHistory) ] - + traceability.put(scxmlHistory, gammaShallowHistory) return gammaShallowHistory - } - else { + } else { val gammaDeepHistory = createDeepHistoryState => [ it.name = getDeepHistoryName(scxmlHistory) ] - + traceability.put(scxmlHistory, gammaDeepHistory) return gammaDeepHistory } } - + // Internal transitions are not supported by the transformer. protected def Transition transformTransition(ScxmlTransitionType transition) { if (transition.type == TransitionTypeDatatype.INTERNAL) { - throw new IllegalArgumentException( - "Transforming internal transition " + transition + " is not supported.") + throw new IllegalArgumentException("Transforming internal transition " + transition + " is not supported.") } - + val sourceState = getTransitionSource(transition) val targetId = transition.target.head - + val gammaSource = traceability.getStateNode(sourceState) val gammaTarget = traceability.getStateNodeById(targetId) logger.log(Level.INFO, "Transforming transition" + gammaSource.name + " -> " + gammaTarget.name) val gammaTransition = gammaSource.createTransition(gammaTarget) - + // Transform event trigger if present val eventName = transition.event if (!eventName.nullOrEmpty) { val eventTrigger = transformTrigger(eventName) gammaTransition.trigger = eventTrigger } - + // Transform guard if present val guardStr = transition.cond if (!guardStr.nullOrEmpty) { val gammaGuardExpression = expressionLanguageParser.parse(guardStr, traceability.variables) gammaTransition.guard = gammaGuardExpression } - + // TODO for all types of actions val effects = transition.assign + transition.raise if (!effects.nullOrEmpty) { gammaTransition.effects += effects.transformBlock } // - traceability.put(transition, gammaTransition) - + return gammaTransition } - -} \ No newline at end of file + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend index aa1af20cd..4252ae125 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -2,6 +2,7 @@ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port +import hu.bme.mit.gamma.statechart.interface_.RealizationMode class TriggerTransformer extends AtomicElementTransformer { @@ -39,7 +40,7 @@ class TriggerTransformer extends AtomicElementTransformer { if (tokens.size >= 3) { val portName = tokens.head - gammaPort = getOrTransformPortByName(gammaInterface, portName) + gammaPort = getOrTransformPortByName(gammaInterface, portName, RealizationMode.PROVIDED) } else { gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) From cd3dffb06c2e65c58776816194c536205b35f2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Tue, 6 Dec 2022 02:12:15 +0100 Subject: [PATCH 20/30] WIP: Fix composite transformation issues --- .../commandhandler/CommandHandler.java | 5 ++++- .../transformation/ActionTransformer.xtend | 20 ++++++++++++++++++- .../CompositeTraceability.xtend | 6 +++++- .../transformation/InterfaceTransformer.xtend | 2 +- .../gamma/scxml/transformation/Namings.xtend | 9 +++++---- .../transformation/PortTransformer.xtend | 4 ++-- .../ScxmlToGammaCompositeTransformer.xtend | 14 ++++++++----- .../ScxmlToGammaStatechartTransformer.xtend | 12 ++++++++--- .../StatechartTraceability.xtend | 5 +++++ .../transformation/TriggerTransformer.xtend | 16 +++++++++++++-- 10 files changed, 73 insertions(+), 20 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 63acd2448..19e566c60 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -20,6 +20,7 @@ import ac.soton.scxml.ScxmlScxmlType; import hu.bme.mit.gamma.scxml.transformation.CompositeTraceability; +import hu.bme.mit.gamma.scxml.transformation.Namings; import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaCompositeTransformer; import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent; import hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures; @@ -60,12 +61,14 @@ public Object execute(ExecutionEvent event) throws ExecutionException { ScxmlScxmlType scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(object, ScxmlScxmlType.class); // Model processing - ScxmlToGammaCompositeTransformer compositeTransformer = new ScxmlToGammaCompositeTransformer(scxmlRoot); + ScxmlToGammaCompositeTransformer compositeTransformer = + new ScxmlToGammaCompositeTransformer(scxmlRoot, path); CompositeTraceability traceability = compositeTransformer.execute(); // Interfaces and type declarations have to be explicitly serialized in another package List gammaInterfaces = new ArrayList(traceability.getInterfaces()); Package gammaInterfacePackage = statechartUtil.wrapIntoPackage(gammaInterfaces.get(0)); + gammaInterfacePackage.setName(Namings.getInterfacePackageName(scxmlRoot)); gammaInterfaces.remove(0); gammaInterfacePackage.getInterfaces().addAll(gammaInterfaces); diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index 981cbb729..a3417373b 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -85,8 +85,10 @@ class ActionTransformer extends AtomicElementTransformer { var gammaInterface = null as Interface var gammaPort = null as Port + var isDefault = false if (tokens.size == 1) { + isDefault = true gammaInterface = getOrCreateDefaultInterface() gammaPort = getOrCreateDefaultPort() } @@ -99,11 +101,15 @@ class ActionTransformer extends AtomicElementTransformer { gammaPort = getOrTransformPortByName(gammaInterface, portName, RealizationMode.PROVIDED) } else { + isDefault = true gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) } } val eventName = tokens.last + + // The action raises an event out on an interface provided by a port + // either it is a default interface or not. val gammaEvent = getOrTransformOutEvent(gammaInterface, eventName) // Event parameters are currently not supported. @@ -115,8 +121,20 @@ class ActionTransformer extends AtomicElementTransformer { logger.log(Level.INFO, "Transforming element (" + scxmlIf + ")") // TODO - val gammaIf = createEmptyStatement + /* + val gammaIf = createIfStatement + val cond = scxmlIf.cond + if (!cond.nullOrEmpty) { + val condExpression = expressionLanguageParser.parse(cond, traceability.variables) + val thenExpression = scxmlIf. + val elseExpression = scxmlIf. + + val gammaConditional = createConditional + gammaIf.conditionals += + } + */ + val gammaIf = createEmptyStatement return gammaIf } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend index d16312e02..30f3cadd1 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -145,7 +145,11 @@ class CompositeTraceability { // def getInterfaces() { - return interfaces.values + val statechartTraceabilities = statecharts.values + return (interfaces.values + + statechartTraceabilities.map[it.defaultInterface] + + statechartTraceabilities.map[it.defaultInterfacePorts.keySet].flatten + ).toSet } def getComponents() { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend index d9137f0d1..1f2bb7b45 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend @@ -22,7 +22,7 @@ class InterfaceTransformer extends AtomicElementTransformer { protected def createDefaultInterface() { val defaultInterface = createInterface - val defaultInterfaceName = getDefaultInterfaceName + val defaultInterfaceName = getDefaultInterfaceName(traceability.getTypeName()) defaultInterface.name = defaultInterfaceName return defaultInterface diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index 9d6e73ab3..fc1cd3013 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -10,19 +10,20 @@ class Namings { // TODO check default names differ from user defined interface and port names // at the end of the transformation - def static String getDefaultPortName() '''_DefaultPort''' - def static String getDefaultInterfaceName() '''_DefaultInterface''' + def static String getDefaultPortName(String instanceName) '''«instanceName»_DefaultPort''' + def static String getDefaultInterfaceName(String instanceName) '''«instanceName»_DefaultInterface''' def static String getDefaultInterfacePortName(String scxmlInterfaceName) '''«scxmlInterfaceName»_DefaultPort''' def static String getInterfaceName(String scxmlInterfaceName) '''«scxmlInterfaceName»''' def static String getPortName(String scxmlPortName) '''«scxmlPortName»''' - def static String getInEventName(String scxmlEventName) '''in_«scxmlEventName»''' - def static String getOutEventName(String scxmlEventName) '''out_«scxmlEventName»''' + def static String getInEventName(String scxmlEventName) '''«scxmlEventName»''' + def static String getOutEventName(String scxmlEventName) '''«scxmlEventName»''' def static String getAdapterName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»Adapter''' def static String getInternalEventQueueName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»InternalEventQueue''' def static String getExternalEventQueueName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»ExternalEventQueue''' + def static String getInterfacePackageName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name.toLowerCase»_interfaces''' def static String getCompositeStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' def static String getStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' def static String getRegionName(String scxmlElementName) '''«scxmlElementName»Region''' diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend index 8abbf727a..d56701d86 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend @@ -43,14 +43,14 @@ class PortTransformer extends AtomicElementTransformer { // We assume that the statechart's default interface already exists at this point. protected def createDefaultPort() { - val defaultInterface = traceability.getDefaultInterface + val defaultInterface = interfaceTransformer.getOrCreateDefaultInterface val defaultInterfaceRealization = createInterfaceRealization defaultInterfaceRealization.realizationMode = RealizationMode.PROVIDED defaultInterfaceRealization.interface = defaultInterface val defaultPort = createPort - defaultPort.name = getDefaultPortName + defaultPort.name = getDefaultPortName(traceability.getTypeName()) defaultPort.interfaceRealization = defaultInterfaceRealization return defaultPort diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend index 999bcdfbc..586c613f3 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend @@ -19,19 +19,19 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { // Root element of the SCXML statechart model to transform protected final ScxmlScxmlType scxmlRoot + protected final String fileURI // Contained elements invoking SCXML substatecharts protected List invokes - new(ScxmlScxmlType scxmlRoot) { - this(scxmlRoot, - new CompositeTraceability(scxmlRoot) - ) + new(ScxmlScxmlType scxmlRoot, String fileURI) { + this(scxmlRoot, new CompositeTraceability(scxmlRoot), fileURI) } - new(ScxmlScxmlType scxmlRoot, CompositeTraceability traceability) { + new(ScxmlScxmlType scxmlRoot, CompositeTraceability traceability, String fileURI) { super(traceability) this.scxmlRoot = scxmlRoot + this.fileURI = fileURI val portTraceability = traceability.createStatechartTraceability(scxmlRoot) this.portTransformer = new PortTransformer(portTraceability) @@ -48,6 +48,9 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { invokes = getAllInvokes(scxmlRoot) if (invokes.empty) { + val statechartTraceability = traceability.createStatechartTraceability(scxmlRoot) + traceability.putTraceability(fileURI, statechartTraceability) + return scxmlRoot.transformAtomic } else { @@ -77,6 +80,7 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { protected def transformAtomic(ScxmlScxmlType scxmlRoot) { val statechartTraceability = traceability.getTraceability(scxmlRoot) + val statechartTransformer = new ScxmlToGammaStatechartTransformer(scxmlRoot, statechartTraceability) statechartTransformer.execute diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 434bb242a..4d529a9ae 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -211,9 +211,15 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { internalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING internalEventQueue.priority = BigInteger.TWO internalEventQueue.capacity = expressionUtil.toIntegerLiteral(4) - + + val allStatechartPorts = StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart) + //val allInternalPorts = allStatechartPorts.filter[it | StatechartModelDerivedFeatures.isInternal(it)] + //val allExternalPorts = allStatechartPorts.filter[it | !StatechartModelDerivedFeatures.isInternal(it)] + val allInternalPorts = allStatechartPorts + val allExternalPorts = allStatechartPorts + // TODO Add only internal ports - for (port : StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart)) { + for (port : allInternalPorts) { val reference = statechartModelFactory.createAnyPortEventReference reference.port = port internalEventQueue.eventReferences += reference @@ -230,7 +236,7 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { externalEventQueue.capacity = expressionUtil.toIntegerLiteral(4) // TODO Add only external ports - for (port : StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart)) { + for (port : allExternalPorts) { val reference = statechartModelFactory.createAnyPortEventReference reference.port = port externalEventQueue.eventReferences += reference diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend index 7fd63a740..b77c4c031 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend @@ -76,6 +76,10 @@ class StatechartTraceability { return scxmlRoot } + def getTypeName() { + return scxmlRoot.name + } + def setAdapter(AsynchronousAdapter adapter) { this.adapter = adapter } @@ -351,6 +355,7 @@ class StatechartTraceability { def getAllInterfaces() { var allInterfaces = interfaces.values.toList + allInterfaces += defaultInterfacePorts.keySet.toList if (getDefaultInterface !== null) { allInterfaces += getDefaultInterface } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend index 4252ae125..b46efa478 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -29,8 +29,10 @@ class TriggerTransformer extends AtomicElementTransformer { var gammaInterface = null as Interface var gammaPort = null as Port + var isDefault = false if (tokens.size == 1) { + isDefault = true gammaInterface = getOrCreateDefaultInterface() gammaPort = getOrCreateDefaultPort() } @@ -40,15 +42,25 @@ class TriggerTransformer extends AtomicElementTransformer { if (tokens.size >= 3) { val portName = tokens.head - gammaPort = getOrTransformPortByName(gammaInterface, portName, RealizationMode.PROVIDED) + gammaPort = getOrTransformPortByName(gammaInterface, portName, RealizationMode.REQUIRED) } else { + isDefault = true gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) } } val eventName = tokens.last - val gammaEvent = getOrTransformInEvent(gammaInterface, eventName) + + // If a port is specified, the event will be an out event on an interface + // realized in required mode by the port receiving the event. + // In the case of default interfaces and ports, realization mode is provided + // and trigger events flow in. + val gammaEvent = if (isDefault) { + getOrTransformInEvent(gammaInterface, eventName) + } else { + getOrTransformOutEvent(gammaInterface, eventName) + } val gammaEventReference = createPortEventReference gammaEventReference.port = gammaPort From 3cbf1ca1519b8cb4ec404c56ac5523389316ce05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Tue, 6 Dec 2022 04:42:17 +0100 Subject: [PATCH 21/30] Fix internal event selection in message queues --- .../plugin.xml | 4 +- .../commandhandler/CommandHandler.java | 7 +++ .../transformation/ActionTransformer.xtend | 12 +++-- .../CompositeTraceability.xtend | 20 +++++++- .../transformation/EventTransformer.xtend | 18 ++++++- .../gamma/scxml/transformation/Namings.xtend | 1 + .../ScxmlToGammaCompositeTransformer.xtend | 20 ++++++-- .../ScxmlToGammaStatechartTransformer.xtend | 24 +++++----- .../StatechartTraceability.xtend | 47 +++++++++++++++++++ .../transformation/TriggerTransformer.xtend | 4 +- 10 files changed, 131 insertions(+), 26 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml index ac52a69d3..031ac3acd 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/plugin.xml @@ -2,7 +2,7 @@ - + + label="Generate Gamma Component" style="push"> diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 19e566c60..45128ff08 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -19,6 +19,7 @@ import org.eclipse.ui.handlers.HandlerUtil; import ac.soton.scxml.ScxmlScxmlType; +import hu.bme.mit.gamma.expression.model.ConstantDeclaration; import hu.bme.mit.gamma.scxml.transformation.CompositeTraceability; import hu.bme.mit.gamma.scxml.transformation.Namings; import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaCompositeTransformer; @@ -72,6 +73,9 @@ public Object execute(ExecutionEvent event) throws ExecutionException { gammaInterfaces.remove(0); gammaInterfacePackage.getInterfaces().addAll(gammaInterfaces); + List gammaConstants = new ArrayList(traceability.getConstantDeclarations()); + gammaInterfacePackage.getConstantDeclarations().addAll(gammaConstants); + // Pack and serialize asynchronous component AsynchronousComponent rootComponent = traceability.getRootComponent(); Package gammaCompositePackage = statechartUtil.wrapIntoPackage(rootComponent); @@ -84,8 +88,11 @@ public Object execute(ExecutionEvent event) throws ExecutionException { StatechartLanguageSerializer packageSerializer = new StatechartLanguageSerializer(); logger.log(Level.INFO, "Start serializing Gamma packages..."); + //String declarationsPackageFileName = extensionlessFileName + "Declarations.gsm"; + //ecoreUtil.normalSave(gammaInterfacePackage, parentPath, declarationsPackageFileName); String declarationsPackageFileName = extensionlessFileName + "Declarations.gcd"; packageSerializer.serialize(gammaInterfacePackage, parentPath, declarationsPackageFileName); + //String compositePackageFileName = extensionlessFileName + ".gsm"; //ecoreUtil.normalSave(gammaCompositePackage, parentPath, compositePackageFileName); String compositePackageFileName = extensionlessFileName + ".gcd"; diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index a3417373b..acdb4daea 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -108,9 +108,15 @@ class ActionTransformer extends AtomicElementTransformer { val eventName = tokens.last - // The action raises an event out on an interface provided by a port - // either it is a default interface or not. - val gammaEvent = getOrTransformOutEvent(gammaInterface, eventName) + // If a port is specified, the event will be an out event on an interface + // realized in provided mode by the port receiving the event. + // In the case of default interfaces and ports, realization mode is also provided, + // but the trigger events are internal. + val gammaEvent = if (isDefault) { + getOrTransformInternalEvent(gammaInterface, eventName) + } else { + getOrTransformOutEvent(gammaInterface, eventName) + } // Event parameters are currently not supported. val gammaRaise = createRaiseEventAction(gammaPort, gammaEvent, newArrayList) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend index 30f3cadd1..4aad41d03 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -2,11 +2,13 @@ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlInvokeType import ac.soton.scxml.ScxmlScxmlType +import hu.bme.mit.gamma.expression.model.ConstantDeclaration import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent import hu.bme.mit.gamma.statechart.composite.AsynchronousComponentInstance import hu.bme.mit.gamma.statechart.interface_.Event import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port +import java.util.List import java.util.Map import static com.google.common.base.Preconditions.checkNotNull @@ -19,6 +21,9 @@ class CompositeTraceability { // Resulting root component protected AsynchronousComponent rootComponent + // Default message quque capacity + protected ConstantDeclaration queueCapacity + // TODO Add interfaces, events, ports, bindings and channels // (Needed for the declarations package and serialization of the components package.) @@ -28,6 +33,7 @@ class CompositeTraceability { // Global mappings: Interfaces, events, declarations protected final Map interfaces = newHashMap + protected final Map, Event> internalEvents = newHashMap protected final Map, Event> inEvents = newHashMap protected final Map, Event> outEvents = newHashMap @@ -48,6 +54,14 @@ class CompositeTraceability { this.rootComponent = rootComponent } + def getQueueCapacityDeclaration() { + return queueCapacity + } + + def setQueueCapacity(ConstantDeclaration capacity) { + this.queueCapacity = capacity + } + // String URI of the SCXML statechart definition source - Statechart Traceability def putTraceability(String statechartUri, StatechartTraceability statechartTraceability) { checkNotNull(statechartUri) @@ -144,6 +158,10 @@ class CompositeTraceability { // + def getConstantDeclarations() { + return List.of(queueCapacity) + } + def getInterfaces() { val statechartTraceabilities = statecharts.values return (interfaces.values @@ -162,7 +180,7 @@ class CompositeTraceability { def createStatechartTraceability(ScxmlScxmlType scxmlRoot) { return new StatechartTraceability(scxmlRoot, - interfaces, inEvents, outEvents + interfaces, queueCapacity, internalEvents, inEvents, outEvents ) } } \ No newline at end of file diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend index 1bf4aca74..7d3e7b18a 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend @@ -1,15 +1,31 @@ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.statechart.interface_.EventDirection +import hu.bme.mit.gamma.statechart.interface_.Interface import static hu.bme.mit.gamma.scxml.transformation.Namings.* -import hu.bme.mit.gamma.statechart.interface_.Interface class EventTransformer extends AtomicElementTransformer { new(StatechartTraceability traceability) { super(traceability) } + def getOrTransformInternalEvent(Interface gammaInterface, String eventName) { + if (traceability.containsInternalEvent(gammaInterface -> eventName)) { + return traceability.getInternalEvent(gammaInterface -> eventName) + } + else { + return transformInternalEvent(gammaInterface, eventName) + } + } + + protected def transformInternalEvent(Interface gammaInterface, String eventName) { + val gammaEvent = transformEvent(gammaInterface, EventDirection.INTERNAL, eventName) + gammaEvent.name = getInternalEventName(eventName) + traceability.putInternalEvent(gammaInterface -> eventName, gammaEvent) + return gammaEvent + } + def getOrTransformInEvent(Interface gammaInterface, String eventName) { if (traceability.containsInEvent(gammaInterface -> eventName)) { return traceability.getInEvent(gammaInterface -> eventName) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index fc1cd3013..99b57af5a 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -16,6 +16,7 @@ class Namings { def static String getInterfaceName(String scxmlInterfaceName) '''«scxmlInterfaceName»''' def static String getPortName(String scxmlPortName) '''«scxmlPortName»''' + def static String getInternalEventName(String scxmlEventName) '''«scxmlEventName»''' def static String getInEventName(String scxmlEventName) '''«scxmlEventName»''' def static String getOutEventName(String scxmlEventName) '''«scxmlEventName»''' diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend index 586c613f3..4196ff0bb 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend @@ -45,6 +45,8 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { } protected def AsynchronousComponent transform(ScxmlScxmlType scxmlRoot) { + initQueueCapacity + invokes = getAllInvokes(scxmlRoot) if (invokes.empty) { @@ -71,6 +73,18 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { } } + private def initQueueCapacity() { + // Define default queue capacity + val queueCapacityDeclaration = createConstantDeclaration + queueCapacityDeclaration.name = "QUEUE_CAPACITY" + + val capacity = expressionUtil.toIntegerLiteral(4) + queueCapacityDeclaration.expression = capacity + queueCapacityDeclaration.type = createIntegerTypeDefinition + + traceability.setQueueCapacity(queueCapacityDeclaration) + } + private def loadSubcomponent(String path) { val fileURI = URI.createPlatformResourceURI(path, true); val documentRoot = ecoreUtil.normalLoad(fileURI); @@ -95,7 +109,7 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { for (invoke : invokes) { val statechartTraceability = traceability.getTraceability(invoke.src) - // TODO Extend to deeper composition hierarchy levels + // TODO Extend to deeper composition hierarchy levels later val gammaSubcomponentType = statechartTraceability.adapter as AsynchronousComponent val gammaSubcomponent = gammaSubcomponentType.instantiateAsynchronousComponent @@ -179,9 +193,7 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { return gammaPort } - // TODO protected def createBinding(ScxmlDataType bindingData) { - // Get binding endpoint data val bindingString = bindingData.expr.trim val tokens = bindingString.split("\\.|\\s*\\-\\s*") if (tokens.size != 3) { @@ -203,9 +215,7 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { return gammaPortBinding } - // TODO protected def createChannel(ScxmlDataType channelData) { - // Get channel endpoint data val channelString = channelData.expr.trim val tokens = channelString.split("\\.|\\s*\\-\\s*") if (tokens.size != 4) { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 4d529a9ae..977bfaab8 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -203,22 +203,21 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { controlSpecification.controlFunction = ControlFunction.RUN_ONCE adapter.controlSpecifications += controlSpecification - + // Create internal event queue - // TODO Check capacity and priority val internalEventQueue = compositeModelFactory.createMessageQueue internalEventQueue.name = getInternalEventQueueName(scxmlRoot) internalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING internalEventQueue.priority = BigInteger.TWO - internalEventQueue.capacity = expressionUtil.toIntegerLiteral(4) + + val internalCapacityReference = createDirectReferenceExpression + internalCapacityReference.declaration = traceability.queueCapacityDeclaration + internalEventQueue.capacity = internalCapacityReference val allStatechartPorts = StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart) - //val allInternalPorts = allStatechartPorts.filter[it | StatechartModelDerivedFeatures.isInternal(it)] - //val allExternalPorts = allStatechartPorts.filter[it | !StatechartModelDerivedFeatures.isInternal(it)] - val allInternalPorts = allStatechartPorts - val allExternalPorts = allStatechartPorts + val allInternalPorts = allStatechartPorts.filter[it | StatechartModelDerivedFeatures.isInternal(it)] + val allExternalPorts = allStatechartPorts.filter[it | !StatechartModelDerivedFeatures.isInternal(it)] - // TODO Add only internal ports for (port : allInternalPorts) { val reference = statechartModelFactory.createAnyPortEventReference reference.port = port @@ -228,14 +227,15 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { adapter.messageQueues += internalEventQueue // Create external event queue - // TODO Check capacity and priority val externalEventQueue = compositeModelFactory.createMessageQueue externalEventQueue.name = getExternalEventQueueName(scxmlRoot) externalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING externalEventQueue.priority = BigInteger.ONE - externalEventQueue.capacity = expressionUtil.toIntegerLiteral(4) - - // TODO Add only external ports + + val externalCapacityReference = createDirectReferenceExpression + externalCapacityReference.declaration = traceability.queueCapacityDeclaration + externalEventQueue.capacity = externalCapacityReference + for (port : allExternalPorts) { val reference = statechartModelFactory.createAnyPortEventReference reference.port = port diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend index b77c4c031..daaf11aab 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend @@ -8,6 +8,7 @@ import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType +import hu.bme.mit.gamma.expression.model.ConstantDeclaration import hu.bme.mit.gamma.expression.model.Declaration import hu.bme.mit.gamma.expression.model.VariableDeclaration import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter @@ -33,6 +34,7 @@ class StatechartTraceability { protected final ScxmlScxmlType scxmlRoot protected SynchronousStatechartDefinition statechart protected AsynchronousAdapter adapter + protected ConstantDeclaration queueCapacity protected final Map parallels = newHashMap protected final Map states = newHashMap @@ -55,6 +57,7 @@ class StatechartTraceability { // Global mappings (from composite traceability) protected final Map interfaces + protected final Map, Event> internalEvents protected final Map, Event> inEvents protected final Map, Event> outEvents @@ -63,11 +66,15 @@ class StatechartTraceability { // - Synchronous Statechart Definition new(ScxmlScxmlType scxmlRoot, Map interfaces, + ConstantDeclaration queueCapacity, + Map, Event> internalEvents, Map, Event> inEvents, Map, Event> outEvents ) { this.scxmlRoot = scxmlRoot this.interfaces = interfaces + this.queueCapacity = queueCapacity + this.internalEvents = internalEvents this.inEvents = inEvents this.outEvents = outEvents } @@ -87,6 +94,11 @@ class StatechartTraceability { def getAdapter() { return adapter } + + def getQueueCapacityDeclaration() { + checkNotNull(queueCapacity) + return queueCapacity + } def setStatechart(SynchronousStatechartDefinition gammaStatechart) { checkNotNull(gammaStatechart) @@ -381,6 +393,41 @@ class StatechartTraceability { return ports.containsKey(scxmlPortName) } + // Internal events by pairs of {Gamma interface; event name} + def putInternalEvent(Pair interfaceEvent, Event gammaEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) + checkNotNull(gammaEvent) + + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + internalEvents += (interface -> eventName) -> gammaEvent + } + + def getInternalEvent(Pair interfaceEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) + + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + val gammaEvent = internalEvents.get(interface -> eventName) + + checkNotNull(gammaEvent) + return gammaEvent + } + + def containsInternalEvent(Pair interfaceEvent) { + checkNotNull(interfaceEvent) + checkNotNull(interfaceEvent.key) + checkNotNull(interfaceEvent.value) + + val interface = interfaceEvent.key + val eventName = interfaceEvent.value + return internalEvents.containsKey(interface -> eventName) + } + // Input events by pairs of {Gamma interface; event name} def putInEvent(Pair interfaceEvent, Event gammaEvent) { checkNotNull(interfaceEvent) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend index b46efa478..4b44e59c9 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -55,9 +55,9 @@ class TriggerTransformer extends AtomicElementTransformer { // If a port is specified, the event will be an out event on an interface // realized in required mode by the port receiving the event. // In the case of default interfaces and ports, realization mode is provided - // and trigger events flow in. + // and trigger events are internal. val gammaEvent = if (isDefault) { - getOrTransformInEvent(gammaInterface, eventName) + getOrTransformInternalEvent(gammaInterface, eventName) } else { getOrTransformOutEvent(gammaInterface, eventName) } From cb4accc1187f0d8ec306141a7fb7a10d5526fcf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Tue, 6 Dec 2022 17:46:55 +0100 Subject: [PATCH 22/30] Update message queue control specifications --- .../CompositeTraceability.xtend | 2 +- .../ScxmlToGammaStatechartTransformer.xtend | 57 +++++++++++++------ 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend index 4aad41d03..aaca15bd5 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -21,7 +21,7 @@ class CompositeTraceability { // Resulting root component protected AsynchronousComponent rootComponent - // Default message quque capacity + // Default message queue capacity protected ConstantDeclaration queueCapacity // TODO Add interfaces, events, ports, bindings and channels diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 977bfaab8..3c1de518f 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -196,16 +196,33 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { protected def AsynchronousAdapter wrapIntoAdapter() { adapter = gammaStatechart.wrapIntoAdapter(getAdapterName(scxmlRoot)) - + + val allStatechartPorts = StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart) + val allInternalPorts = allStatechartPorts.filter[it | StatechartModelDerivedFeatures.isInternal(it)] + val allExternalPorts = allStatechartPorts.filter[it | !StatechartModelDerivedFeatures.isInternal(it)] + // Set control specification - val controlSpecification = compositeModelFactory.createControlSpecification - controlSpecification.trigger = interfaceModelFactory.createAnyTrigger - controlSpecification.controlFunction = ControlFunction.RUN_ONCE - - adapter.controlSpecifications += controlSpecification + // TODO Check if internal port event triggers should be added as control specification triggers. + for (port : allExternalPorts) { + val portEvents = StatechartModelDerivedFeatures.getInputEvents(port) + for (event : portEvents) { + val controlSpecification = createControlSpecification + controlSpecification.controlFunction = ControlFunction.RUN_ONCE + + val eventReference = createPortEventReference + eventReference.port = port + eventReference.event = event + + val trigger = createEventTrigger + trigger.eventReference = eventReference + controlSpecification.trigger = trigger + + adapter.controlSpecifications += controlSpecification + } + } // Create internal event queue - val internalEventQueue = compositeModelFactory.createMessageQueue + val internalEventQueue = createMessageQueue internalEventQueue.name = getInternalEventQueueName(scxmlRoot) internalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING internalEventQueue.priority = BigInteger.TWO @@ -214,20 +231,20 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { internalCapacityReference.declaration = traceability.queueCapacityDeclaration internalEventQueue.capacity = internalCapacityReference - val allStatechartPorts = StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart) - val allInternalPorts = allStatechartPorts.filter[it | StatechartModelDerivedFeatures.isInternal(it)] - val allExternalPorts = allStatechartPorts.filter[it | !StatechartModelDerivedFeatures.isInternal(it)] - for (port : allInternalPorts) { - val reference = statechartModelFactory.createAnyPortEventReference - reference.port = port - internalEventQueue.eventReferences += reference + val portEvents = StatechartModelDerivedFeatures.getInputEvents(port) + for (event : portEvents) { + val reference = createPortEventReference + reference.port = port + reference.event = event + internalEventQueue.eventReferences += reference + } } adapter.messageQueues += internalEventQueue // Create external event queue - val externalEventQueue = compositeModelFactory.createMessageQueue + val externalEventQueue = createMessageQueue externalEventQueue.name = getExternalEventQueueName(scxmlRoot) externalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING externalEventQueue.priority = BigInteger.ONE @@ -237,9 +254,13 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { externalEventQueue.capacity = externalCapacityReference for (port : allExternalPorts) { - val reference = statechartModelFactory.createAnyPortEventReference - reference.port = port - externalEventQueue.eventReferences += reference + val portEvents = StatechartModelDerivedFeatures.getInputEvents(port) + for (event : portEvents) { + val reference = createPortEventReference + reference.port = port + reference.event = event + externalEventQueue.eventReferences += reference + } } adapter.messageQueues.add(externalEventQueue) From 2852fa1ae6693a8bfa3efa2b394a668d7c185c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Mon, 27 Feb 2023 21:46:01 +0100 Subject: [PATCH 23/30] Add copyright notices --- .../transformation/commandhandler/CommandHandler.java | 10 ++++++++++ .../scxml/transformation/AbstractTransformer.xtend | 10 ++++++++++ .../gamma/scxml/transformation/ActionTransformer.xtend | 10 ++++++++++ .../transformation/AtomicElementTransformer.xtend | 10 ++++++++++ .../transformation/CompositeElementTransformer.xtend | 10 ++++++++++ .../scxml/transformation/CompositeTraceability.xtend | 10 ++++++++++ .../gamma/scxml/transformation/DataTransformer.xtend | 10 ++++++++++ .../gamma/scxml/transformation/EventTransformer.xtend | 10 ++++++++++ .../scxml/transformation/InterfaceTransformer.xtend | 10 ++++++++++ .../bme/mit/gamma/scxml/transformation/Namings.xtend | 10 ++++++++++ .../gamma/scxml/transformation/PortTransformer.xtend | 10 ++++++++++ .../ScxmlGammaExpressionTransformer.xtend | 10 ++++++++++ .../ScxmlToGammaCompositeTransformer.xtend | 10 ++++++++++ .../ScxmlToGammaStatechartTransformer.xtend | 10 ++++++++++ .../scxml/transformation/StatechartTraceability.xtend | 10 ++++++++++ .../scxml/transformation/TriggerTransformer.xtend | 10 ++++++++++ .../parse/ScxmlGammaExpressionLanguageParser.java | 10 ++++++++++ .../transformation/parse/ScxmlGammaLanguageParser.java | 10 ++++++++++ 18 files changed, 180 insertions(+) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 45128ff08..58d71686b 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation.commandhandler; import java.io.IOException; diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend index 6b5f95729..c3ed023c2 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.action.model.ActionModelFactory diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index acdb4daea..e2f8c364f 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlAssignType diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend index e570efb79..50e835307 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation abstract class AtomicElementTransformer extends AbstractTransformer { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend index 2507d3552..63150144a 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation abstract class CompositeElementTransformer extends AbstractTransformer { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend index aaca15bd5..bb50bc81e 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlInvokeType diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend index dc85254bf..e2720d480 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlDataType diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend index 7d3e7b18a..3d823e7ac 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/EventTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.statechart.interface_.EventDirection diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend index 1f2bb7b45..41b325c3c 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/InterfaceTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import static com.google.common.base.Preconditions.checkState diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index 99b57af5a..f712b8503 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlFinalType diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend index d56701d86..58414fc48 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/PortTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.statechart.interface_.Interface diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend index 73f8a5f4e..17faa4494 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlGammaExpressionTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation class ScxmlGammaExpressionTransformer extends AtomicElementTransformer { diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend index 4196ff0bb..3104668fc 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlDataType diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 3c1de518f..602dc2224 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.HistoryTypeDatatype diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend index daaf11aab..3b8e2c5c3 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlDataType diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend index 4b44e59c9..87e52a3c7 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.statechart.interface_.Interface diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java index 7fb9f42aa..7846ab653 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation.parse; import java.io.StringReader; diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java index ca16b84fa..5ca6bc8f8 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java @@ -1,3 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2023 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation.parse; import hu.bme.mit.gamma.expression.language.parser.antlr.ExpressionLanguageParser; From d07d4d911e60850f67bcdea81ef7c24cb5ca9216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Thu, 2 Mar 2023 15:57:54 +0100 Subject: [PATCH 24/30] Fix creating event passings in message queues --- .../ScxmlToGammaStatechartTransformer.xtend | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 602dc2224..b6cc1ffd9 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -247,7 +247,9 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { val reference = createPortEventReference reference.port = port reference.event = event - internalEventQueue.eventReferences += reference + + val eventPassing = createEventPassing(reference) + internalEventQueue.eventPassings += eventPassing } } @@ -269,7 +271,9 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { val reference = createPortEventReference reference.port = port reference.event = event - externalEventQueue.eventReferences += reference + + val eventPassing = createEventPassing(reference) + externalEventQueue.eventPassings += eventPassing } } From c06edd8fe5be922cdc8a57813c0b1134c16734da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Tue, 27 Feb 2024 00:36:17 +0100 Subject: [PATCH 25/30] Remove unnecessary scxml launch config from repo --- .../Launch Runtime Eclipse with Scxml.launch | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 plugins/core/hu.bme.mit.gamma.property.language/.launch/Launch Runtime Eclipse with Scxml.launch diff --git a/plugins/core/hu.bme.mit.gamma.property.language/.launch/Launch Runtime Eclipse with Scxml.launch b/plugins/core/hu.bme.mit.gamma.property.language/.launch/Launch Runtime Eclipse with Scxml.launch deleted file mode 100644 index e1bec6db0..000000000 --- a/plugins/core/hu.bme.mit.gamma.property.language/.launch/Launch Runtime Eclipse with Scxml.launch +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 5f506e036aa9cb8a6b218b6bd0757193b0567e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Mon, 7 Oct 2024 21:08:22 +0200 Subject: [PATCH 26/30] WIP Restructure statechart and invoke transformation --- .../commandhandler/CommandHandler.java | 72 +++-- .../transformation/AbstractTransformer.xtend | 18 +- .../transformation/ActionTransformer.xtend | 133 +++++---- .../CompositeElementTransformer.xtend | 16 +- .../CompositeTraceability.xtend | 124 ++++---- .../ScxmlToGammaCompositeTransformer.xtend | 265 ++---------------- .../ScxmlToGammaStatechartTransformer.xtend | 250 +++++++++++++++-- .../StatechartTraceability.xtend | 123 ++++---- 8 files changed, 512 insertions(+), 489 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 58d71686b..35891a758 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -22,8 +22,6 @@ import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.handlers.HandlerUtil; @@ -33,7 +31,6 @@ import hu.bme.mit.gamma.scxml.transformation.CompositeTraceability; import hu.bme.mit.gamma.scxml.transformation.Namings; import hu.bme.mit.gamma.scxml.transformation.ScxmlToGammaCompositeTransformer; -import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent; import hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures; import hu.bme.mit.gamma.statechart.interface_.Component; import hu.bme.mit.gamma.statechart.interface_.Interface; @@ -44,8 +41,8 @@ import hu.bme.mit.gamma.util.GammaEcoreUtil; public class CommandHandler extends AbstractHandler { - - protected final FileUtil fileUtil= FileUtil.INSTANCE; + + protected final FileUtil fileUtil = FileUtil.INSTANCE; protected final GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE; protected final StatechartUtil statechartUtil = StatechartUtil.INSTANCE; protected final Logger logger = Logger.getLogger("GammaLogger"); @@ -65,59 +62,60 @@ public Object execute(ExecutionEvent event) throws ExecutionException { String extensionlessFileName = fileUtil.getExtensionlessName(fileName); String parentPath = parentFolder.getFullPath().toString(); String path = file.getFullPath().toString(); - URI fileURI = URI.createPlatformResourceURI(path, true); - - // Retrieve SCXML document root to transform - EObject object = ecoreUtil.normalLoad(fileURI); - ScxmlScxmlType scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(object, ScxmlScxmlType.class); - + // Model processing - ScxmlToGammaCompositeTransformer compositeTransformer = - new ScxmlToGammaCompositeTransformer(scxmlRoot, path); - CompositeTraceability traceability = compositeTransformer.execute(); - - // Interfaces and type declarations have to be explicitly serialized in another package - List gammaInterfaces = new ArrayList(traceability.getInterfaces()); + ScxmlToGammaCompositeTransformer compositeTransformer = new ScxmlToGammaCompositeTransformer( + path); + CompositeTraceability compositeTraceability = compositeTransformer.execute(); + + // Interfaces and type declarations have to be explicitly serialized in another + // package + List gammaInterfaces = new ArrayList( + compositeTraceability.getInterfaces()); Package gammaInterfacePackage = statechartUtil.wrapIntoPackage(gammaInterfaces.get(0)); + ScxmlScxmlType scxmlRoot = compositeTraceability.getScxmlRoot(); gammaInterfacePackage.setName(Namings.getInterfacePackageName(scxmlRoot)); gammaInterfaces.remove(0); gammaInterfacePackage.getInterfaces().addAll(gammaInterfaces); - - List gammaConstants = new ArrayList(traceability.getConstantDeclarations()); + + List gammaConstants = new ArrayList( + compositeTraceability.getConstantDeclarations()); gammaInterfacePackage.getConstantDeclarations().addAll(gammaConstants); - + // Pack and serialize asynchronous component - AsynchronousComponent rootComponent = traceability.getRootComponent(); + Component rootComponent = compositeTraceability.getRootComponent(); Package gammaCompositePackage = statechartUtil.wrapIntoPackage(rootComponent); - Collection components = traceability.getComponents(); + Collection components = compositeTraceability.getComponents(); gammaCompositePackage.getComponents().addAll(components); - gammaCompositePackage.getImports().addAll( - StatechartModelDerivedFeatures.getImportablePackages(gammaCompositePackage)); + gammaCompositePackage.getImports() + .addAll(StatechartModelDerivedFeatures.getImportablePackages(gammaCompositePackage)); gammaCompositePackage.getImports().remove(gammaCompositePackage); - + StatechartLanguageSerializer packageSerializer = new StatechartLanguageSerializer(); logger.log(Level.INFO, "Start serializing Gamma packages..."); - - //String declarationsPackageFileName = extensionlessFileName + "Declarations.gsm"; - //ecoreUtil.normalSave(gammaInterfacePackage, parentPath, declarationsPackageFileName); + + // String declarationsPackageFileName = extensionlessFileName + + // "Declarations.gsm"; + // ecoreUtil.normalSave(gammaInterfacePackage, parentPath, + // declarationsPackageFileName); String declarationsPackageFileName = extensionlessFileName + "Declarations.gcd"; packageSerializer.serialize(gammaInterfacePackage, parentPath, declarationsPackageFileName); - - //String compositePackageFileName = extensionlessFileName + ".gsm"; - //ecoreUtil.normalSave(gammaCompositePackage, parentPath, compositePackageFileName); + + // String compositePackageFileName = extensionlessFileName + ".gsm"; + // ecoreUtil.normalSave(gammaCompositePackage, parentPath, + // compositePackageFileName); String compositePackageFileName = extensionlessFileName + ".gcd"; packageSerializer.serialize(gammaCompositePackage, parentPath, compositePackageFileName); - + logger.log(Level.INFO, "The SCXML - Gamma statechart transformation has finished."); - + } } } - } - catch (IOException e) { - e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); } return null; } - + } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend index c3ed023c2..2883f9c68 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend @@ -1,11 +1,11 @@ /******************************************************************************** * Copyright (c) 2023 Contributors to the Gamma project - * + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation @@ -18,27 +18,29 @@ import hu.bme.mit.gamma.expression.util.ExpressionUtil import hu.bme.mit.gamma.scxml.transformation.parse.ScxmlGammaExpressionLanguageParser import hu.bme.mit.gamma.statechart.composite.CompositeModelFactory import hu.bme.mit.gamma.statechart.interface_.InterfaceModelFactory +import hu.bme.mit.gamma.statechart.phase.PhaseModelFactory import hu.bme.mit.gamma.statechart.statechart.StatechartModelFactory import hu.bme.mit.gamma.statechart.util.StatechartUtil import hu.bme.mit.gamma.util.GammaEcoreUtil import java.util.logging.Logger abstract class AbstractTransformer { - + protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE protected final extension StatechartUtil statechartUtil = StatechartUtil.INSTANCE protected final extension ActionUtil actionUtil = ActionUtil.INSTANCE protected final extension ExpressionUtil expressionUtil = ExpressionUtil.INSTANCE - + protected final extension InterfaceModelFactory interfaceModelFactory = InterfaceModelFactory.eINSTANCE protected final extension CompositeModelFactory compositeModelFactory = CompositeModelFactory.eINSTANCE protected final extension StatechartModelFactory statechartModelFactory = StatechartModelFactory.eINSTANCE + protected final extension PhaseModelFactory phaseModelFactory = PhaseModelFactory.eINSTANCE protected final extension ActionModelFactory actionModelFactory = ActionModelFactory.eINSTANCE protected final extension ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE - + protected final ScxmlGammaExpressionLanguageParser expressionLanguageParser = new ScxmlGammaExpressionLanguageParser() protected final ExpressionTypeDeterminator2 expressionTypeDeterminator = ExpressionTypeDeterminator2.INSTANCE - + protected final Logger logger = Logger.getLogger("GammaLogger") - -} \ No newline at end of file + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index e2f8c364f..5714b43b3 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -1,22 +1,24 @@ /******************************************************************************** * Copyright (c) 2023 Contributors to the Gamma project - * + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlAssignType import ac.soton.scxml.ScxmlIfType +import ac.soton.scxml.ScxmlInvokeType import ac.soton.scxml.ScxmlOnentryType import ac.soton.scxml.ScxmlOnexitType import ac.soton.scxml.ScxmlRaiseType import hu.bme.mit.gamma.action.model.Action import hu.bme.mit.gamma.expression.model.VariableDeclaration +import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port import hu.bme.mit.gamma.statechart.interface_.RealizationMode @@ -24,24 +26,24 @@ import java.util.logging.Level import org.eclipse.emf.ecore.EObject class ActionTransformer extends AtomicElementTransformer { - + protected final extension PortTransformer portTransformer protected final extension InterfaceTransformer interfaceTransformer protected final extension EventTransformer eventTransformer protected final extension ScxmlGammaExpressionTransformer expressionTransformer - + new(StatechartTraceability traceability) { super(traceability) - + this.portTransformer = new PortTransformer(traceability) this.interfaceTransformer = new InterfaceTransformer(traceability) this.eventTransformer = new EventTransformer(traceability) this.expressionTransformer = new ScxmlGammaExpressionTransformer(traceability) } - + def Action transformOnentry(ScxmlOnentryType scxmlOnentry) { logger.log(Level.INFO, "Transforming element (" + scxmlOnentry + ")") - + // TODO Get list of all children actions, not just -s val scxmlActions = scxmlOnentry.assign + scxmlOnentry.raise if (!scxmlActions.nullOrEmpty) { @@ -50,10 +52,10 @@ class ActionTransformer extends AtomicElementTransformer { } return null } - + def Action transformOnexit(ScxmlOnexitType scxmlOnexit) { logger.log(Level.INFO, "Transforming element (" + scxmlOnexit + ")") - + // TODO Get list of all children actions, not just -s val scxmlActions = scxmlOnexit.assign + scxmlOnexit.raise if (!scxmlActions.nullOrEmpty) { @@ -62,107 +64,136 @@ class ActionTransformer extends AtomicElementTransformer { } return null } - + def dispatch Action transformAction(ScxmlAssignType scxmlAssign) { logger.log(Level.INFO, "Transforming element (" + scxmlAssign + ")") - + val varLoc = scxmlAssign.location val variable = traceability.getVariable(varLoc) - + val expr = scxmlAssign.expr if (expr !== null) { val expression = expressionLanguageParser.parse(expr, traceability.variables) val gammaAssign = actionUtil.createAssignment(variable as VariableDeclaration, expression) return gammaAssign } - + // TODO Assignment by child content if expr is not present val gammaAssign = createEmptyStatement - + return gammaAssign } - + def dispatch Action transformAction(ScxmlRaiseType scxmlRaise) { logger.log(Level.INFO, "Transforming element (" + scxmlRaise + ")") - + val eventString = scxmlRaise.event val tokens = eventString.split("\\.") if (tokens.size < 1 || tokens.size > 3) { - throw new IllegalArgumentException("Event descriptor " + eventString - + " does not contain exactly 1, 2 or 3 dot separated tokens." + throw new IllegalArgumentException( + "Event descriptor " + eventString + " does not contain exactly 1, 2 or 3 dot separated tokens." ) } - + var gammaInterface = null as Interface var gammaPort = null as Port var isDefault = false - + if (tokens.size == 1) { isDefault = true gammaInterface = getOrCreateDefaultInterface() gammaPort = getOrCreateDefaultPort() - } - else { + } else { val interfaceName = tokens.get(tokens.size - 2) gammaInterface = getOrTransformInterfaceByName(interfaceName) - + if (tokens.size >= 3) { val portName = tokens.head gammaPort = getOrTransformPortByName(gammaInterface, portName, RealizationMode.PROVIDED) - } - else { + } else { isDefault = true gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) } } - + val eventName = tokens.last - + // If a port is specified, the event will be an out event on an interface // realized in provided mode by the port receiving the event. // In the case of default interfaces and ports, realization mode is also provided, // but the trigger events are internal. val gammaEvent = if (isDefault) { - getOrTransformInternalEvent(gammaInterface, eventName) - } else { - getOrTransformOutEvent(gammaInterface, eventName) - } - + getOrTransformInternalEvent(gammaInterface, eventName) + } else { + getOrTransformOutEvent(gammaInterface, eventName) + } + // Event parameters are currently not supported. val gammaRaise = createRaiseEventAction(gammaPort, gammaEvent, newArrayList) return gammaRaise } - + def dispatch Action transformAction(ScxmlIfType scxmlIf) { logger.log(Level.INFO, "Transforming element (" + scxmlIf + ")") - + // TODO /* - val gammaIf = createIfStatement - val cond = scxmlIf.cond - if (!cond.nullOrEmpty) { - val condExpression = expressionLanguageParser.parse(cond, traceability.variables) - val thenExpression = scxmlIf. - val elseExpression = scxmlIf. - - val gammaConditional = createConditional - gammaIf.conditionals += - } - */ - + * val gammaIf = createIfStatement + * val cond = scxmlIf.cond + * if (!cond.nullOrEmpty) { + * val condExpression = expressionLanguageParser.parse(cond, traceability.variables) + * val thenExpression = scxmlIf. + * val elseExpression = scxmlIf. + * + * val gammaConditional = createConditional + * gammaIf.conditionals += + * } + */ val gammaIf = createEmptyStatement return gammaIf } - + + // TODO check return type (Action vs other) + // TODO use global section of traceability object to store component types, interfaces etc. + def dispatch Action transformAction(ScxmlInvokeType scxmlInvoke) { + logger.log(Level.INFO, "Transforming element (" + scxmlInvoke + ")") + + // TODO invoked statechart type transformation should be ready at this point, + // or be done lazily by the get call. Anyway, ActionTransformer is + // not responsible for invoking contained statechart type transformation. + val invokedTypeURI = scxmlInvoke.type + + // TODO get invoked type traceability + // TODO check component type + val invokedTypeTraceability = traceability.compositeTraceability.getTraceability(invokedTypeURI) + val gammaSubcomponentType = invokedTypeTraceability.adapter as AsynchronousComponent + + val gammaSubcomponent = gammaSubcomponentType.instantiateAsynchronousComponent + gammaSubcomponent.name = scxmlInvoke.id + + val missionPhaseAnnotation = createMissionPhaseStateAnnotation + missionPhaseAnnotation.component = gammaSubcomponent + + // TODO Side effect: find state to put the phase annotation onto + // return missionPhaseAnnotation + // TODO State, transition + // Put transformed invoke to stable target state + // val rootState = ecoreUtil.getContainerOfType(scxmlInvoke, ScxmlScxmlType); + // val gammaRootState = traceability.getTraceability(rootState) + // TODO Assignment by child content if expr is not present + val gammaEmptyAction = createEmptyStatement + return gammaEmptyAction + } + def Action transformBlock(Iterable actions) { if (actions.empty) { return createBlock } - + val gammaActions = actions.map[it.transformAction].toList val gammaBlock = actionUtil.wrap(gammaActions) - + return gammaBlock } - -} \ No newline at end of file + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend index 63150144a..d15b69cf9 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend @@ -1,20 +1,20 @@ /******************************************************************************** * Copyright (c) 2023 Contributors to the Gamma project - * + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation abstract class CompositeElementTransformer extends AbstractTransformer { - - protected final CompositeTraceability traceability - - new(CompositeTraceability traceability) { - this.traceability = traceability + + protected final CompositeTraceability compositeTraceability + + new(CompositeTraceability compositeTraceability) { + this.compositeTraceability = compositeTraceability } -} \ No newline at end of file +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend index bb50bc81e..ca8c7174b 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -1,11 +1,11 @@ /******************************************************************************** * Copyright (c) 2023 Contributors to the Gamma project - * + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation @@ -15,6 +15,7 @@ import ac.soton.scxml.ScxmlScxmlType import hu.bme.mit.gamma.expression.model.ConstantDeclaration import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent import hu.bme.mit.gamma.statechart.composite.AsynchronousComponentInstance +import hu.bme.mit.gamma.statechart.interface_.Component import hu.bme.mit.gamma.statechart.interface_.Event import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port @@ -24,173 +25,186 @@ import java.util.Map import static com.google.common.base.Preconditions.checkNotNull class CompositeTraceability { - - // Root element of the composite SCXML statechart model to transform. - protected final ScxmlScxmlType scxmlRoot - + + // URI of the root SCXML statechart model to transform + protected final String rootFileURI + // Resulting root component - protected AsynchronousComponent rootComponent - + protected Component rootComponent + // Default message queue capacity protected ConstantDeclaration queueCapacity - + // TODO Add interfaces, events, ports, bindings and channels // (Needed for the declarations package and serialization of the components package.) - protected final Map statecharts = newHashMap protected final Map instances = newHashMap protected final Map ports = newHashMap - + // Global mappings: Interfaces, events, declarations protected final Map interfaces = newHashMap protected final Map, Event> internalEvents = newHashMap protected final Map, Event> inEvents = newHashMap protected final Map, Event> outEvents = newHashMap - + // - Asynchronous Component - new(ScxmlScxmlType scxmlRoot) { - this.scxmlRoot = scxmlRoot + new(String rootFileURI) { + this.rootFileURI = rootFileURI + } + + // Creates a traceability object for the Gamma transformation of + // the SCXML statechart model found at rootFileURI. + def createStatechartTraceability(String rootFileURI) { + return new StatechartTraceability( + this, + rootFileURI, + interfaces, + queueCapacity, + internalEvents, + inEvents, + outEvents + ) } + // TODO Get from statecharts or instances map by rootFileURI string, if needed def getScxmlRoot() { - return scxmlRoot + val rootTraceability = getTraceability(rootFileURI) + val rootScxmlElement = rootTraceability.scxmlRoot + checkNotNull(rootScxmlElement) + return rootScxmlElement } - + def getRootComponent() { + val rootTraceability = getTraceability(rootFileURI) + + // TODO Which kind of root Gamma component should we return? statechart / adapter / other? + val rootComponent = rootTraceability.statechart + checkNotNull(rootComponent) return rootComponent } - + def setRootComponent(AsynchronousComponent rootComponent) { this.rootComponent = rootComponent } - + def getQueueCapacityDeclaration() { return queueCapacity } - + def setQueueCapacity(ConstantDeclaration capacity) { this.queueCapacity = capacity } - + // String URI of the SCXML statechart definition source - Statechart Traceability def putTraceability(String statechartUri, StatechartTraceability statechartTraceability) { checkNotNull(statechartUri) checkNotNull(statechartTraceability) statecharts += statechartUri -> statechartTraceability } - + def getTraceability(String statechartUri) { checkNotNull(statechartUri) val statechartTraceability = statecharts.get(statechartUri) checkNotNull(statechartTraceability) return statechartTraceability } - + // TODO Simplify map structure and getter. def getTraceabilityById(String scxmlInvokeId) { checkNotNull(scxmlInvokeId) - val invoke = instances.keySet.findFirst[invoke | invoke.id == scxmlInvokeId] + val invoke = instances.keySet.findFirst[invoke|invoke.id == scxmlInvokeId] checkNotNull(invoke) - val statechartTraceability = statecharts.filter[source, _ | source == invoke.src].values.head + val statechartTraceability = statecharts.filter[source, _|source == invoke.src].values.head checkNotNull(statechartTraceability) return statechartTraceability } - + def getTraceability(ScxmlScxmlType scxmlRoot) { checkNotNull(scxmlRoot) val statechartTraceability = statecharts.values.findFirst[it.scxmlRoot === scxmlRoot] checkNotNull(statechartTraceability) return statechartTraceability } - + def containsTraceability(String statechartUri) { checkNotNull(statechartUri) return statecharts.containsKey(statechartUri) } - + // - Asynchronous Component Instance def putComponentInstance(ScxmlInvokeType scxmlInvoke, AsynchronousComponentInstance instance) { checkNotNull(scxmlInvoke) checkNotNull(instance) instances += scxmlInvoke -> instance } - + def getComponentInstance(ScxmlInvokeType scxmlInvoke) { checkNotNull(scxmlInvoke) val instance = instances.get(scxmlInvoke) checkNotNull(instance) return instance } - + def getComponentInstance(String scxmlInvokeId) { checkNotNull(scxmlInvokeId) - val instance = instances.filter[invoke, _ | invoke.id == scxmlInvokeId].values.head + val instance = instances.filter[invoke, _|invoke.id == scxmlInvokeId].values.head checkNotNull(instance) return instance } - + // Ports by string identifier (for event strings like 'port.interface.event) def putPort(String scxmlPortName, Port gammaPort) { checkNotNull(scxmlPortName) checkNotNull(gammaPort) ports += scxmlPortName -> gammaPort } - + def getPort(String scxmlPortName) { checkNotNull(scxmlPortName) val gammaPort = ports.get(scxmlPortName) checkNotNull(gammaPort) return gammaPort } - + def containsPort(String scxmlPortName) { checkNotNull(scxmlPortName) return ports.containsKey(scxmlPortName) } - + // - def getInEvents() { return inEvents } - + def getOutEvents() { return outEvents } - + def getInstances() { return instances } - + def getStatecharts() { return statecharts.values.toList } - + // - def getConstantDeclarations() { return List.of(queueCapacity) } - + def getInterfaces() { val statechartTraceabilities = statecharts.values - return (interfaces.values - + statechartTraceabilities.map[it.defaultInterface] - + statechartTraceabilities.map[it.defaultInterfacePorts.keySet].flatten + return (interfaces.values + statechartTraceabilities.map[it.defaultInterface] + statechartTraceabilities.map [ + it.defaultInterfacePorts.keySet + ].flatten ).toSet } - + def getComponents() { val statechartTraceabilities = statecharts.values - return (instances.values.map[it.getType] - + statechartTraceabilities.map[it.getAdapter] - + statechartTraceabilities.map[it.getStatechart] + return (instances.values.map[it.getType] + statechartTraceabilities.map[it.getAdapter] + + statechartTraceabilities.map[it.getStatechart] ).toSet } - - def createStatechartTraceability(ScxmlScxmlType scxmlRoot) { - return new StatechartTraceability(scxmlRoot, - interfaces, queueCapacity, internalEvents, inEvents, outEvents - ) - } -} \ No newline at end of file +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend index 3104668fc..3e00f6935 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend @@ -1,263 +1,40 @@ /******************************************************************************** * Copyright (c) 2023 Contributors to the Gamma project - * + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation -import ac.soton.scxml.ScxmlDataType -import ac.soton.scxml.ScxmlInvokeType -import ac.soton.scxml.ScxmlScxmlType -import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent -import hu.bme.mit.gamma.statechart.interface_.RealizationMode -import java.util.List -import org.eclipse.emf.common.util.URI +import hu.bme.mit.gamma.statechart.interface_.Component -import static ac.soton.scxml.ScxmlModelDerivedFeatures.* -import static hu.bme.mit.gamma.scxml.transformation.Namings.* - -// TODO Check features of both composite and atomic components. -// Transform these features for both kinds of statecharts. class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { - - protected final extension PortTransformer portTransformer - + // Root element of the SCXML statechart model to transform - protected final ScxmlScxmlType scxmlRoot - protected final String fileURI - - // Contained elements invoking SCXML substatecharts - protected List invokes - - new(ScxmlScxmlType scxmlRoot, String fileURI) { - this(scxmlRoot, new CompositeTraceability(scxmlRoot), fileURI) + protected final String rootFileURI + + new(String rootFileURI) { + this(new CompositeTraceability(rootFileURI), rootFileURI) } - - new(ScxmlScxmlType scxmlRoot, CompositeTraceability traceability, String fileURI) { - super(traceability) - this.scxmlRoot = scxmlRoot - this.fileURI = fileURI - - val portTraceability = traceability.createStatechartTraceability(scxmlRoot) - this.portTransformer = new PortTransformer(portTraceability) + + new(CompositeTraceability compositeTraceability, String rootFileURI) { + super(compositeTraceability) + this.rootFileURI = rootFileURI } - + + // Entry point for the SCXML to Gamma hierarchical statechart transformation def execute() { - val rootComponent = scxmlRoot.transform - traceability.rootComponent = rootComponent as AsynchronousComponent - - return traceability - } - - protected def AsynchronousComponent transform(ScxmlScxmlType scxmlRoot) { - initQueueCapacity - - invokes = getAllInvokes(scxmlRoot) - - if (invokes.empty) { - val statechartTraceability = traceability.createStatechartTraceability(scxmlRoot) - traceability.putTraceability(fileURI, statechartTraceability) - - return scxmlRoot.transformAtomic - } - else { - for (invoke : invokes) { - var src = invoke.src // TODO Check src | srcexpr - - if (!traceability.containsTraceability(src)) { - val subcomponentRoot = loadSubcomponent(src) - - val newStatechartTraceability = traceability.createStatechartTraceability(subcomponentRoot) - traceability.putTraceability(src, newStatechartTraceability) - - subcomponentRoot.transformAtomic - } - } - - return scxmlRoot.transformComposite - } - } - - private def initQueueCapacity() { - // Define default queue capacity - val queueCapacityDeclaration = createConstantDeclaration - queueCapacityDeclaration.name = "QUEUE_CAPACITY" - - val capacity = expressionUtil.toIntegerLiteral(4) - queueCapacityDeclaration.expression = capacity - queueCapacityDeclaration.type = createIntegerTypeDefinition - - traceability.setQueueCapacity(queueCapacityDeclaration) - } - - private def loadSubcomponent(String path) { - val fileURI = URI.createPlatformResourceURI(path, true); - val documentRoot = ecoreUtil.normalLoad(fileURI); - val scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(documentRoot, ScxmlScxmlType); - return scxmlRoot - } - - protected def transformAtomic(ScxmlScxmlType scxmlRoot) { - val statechartTraceability = traceability.getTraceability(scxmlRoot) - - val statechartTransformer = new ScxmlToGammaStatechartTransformer(scxmlRoot, statechartTraceability) - statechartTransformer.execute - - return statechartTraceability.getAdapter - } - - protected def transformComposite(ScxmlScxmlType scxmlRoot) { - val gammaComposite = createScheduledAsynchronousCompositeComponent - gammaComposite.name = getCompositeStatechartName(scxmlRoot) - - // Instantiate transformed invoked child statecharts - for (invoke : invokes) { - val statechartTraceability = traceability.getTraceability(invoke.src) - - // TODO Extend to deeper composition hierarchy levels later - val gammaSubcomponentType = statechartTraceability.adapter as AsynchronousComponent - - val gammaSubcomponent = gammaSubcomponentType.instantiateAsynchronousComponent - gammaSubcomponent.name = invoke.id - gammaComposite.components += gammaSubcomponent - - traceability.putComponentInstance(invoke, gammaSubcomponent) - } - - // Create ports, port bindings and channels in the composite component - val datamodels = scxmlRoot.datamodel - if (datamodels !== null) { - val datamodel = datamodels.head - if (datamodel !== null) { - val dataElements = getDataElements(datamodel) - - // TODO Move string literal parts of names to Namings - val portDataElements = dataElements.filter [ it | - it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("pro_port_") || - it.id.startsWith("req_port_") - ] - for (portData : portDataElements) { - val gammaPort = portData.getOrCreatePort - gammaComposite.ports += gammaPort - } - - val bindingDataElements = dataElements.filter [ it | - it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("binding_") - ] - for (binding : bindingDataElements) { - val gammaPortBinding = binding.createBinding - gammaComposite.portBindings += gammaPortBinding - } - - val channelDataElements = dataElements.filter [ it | - it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("channel_") - ] - for (channel : channelDataElements) { - val gammaChannel = channel.createChannel - gammaComposite.channels += gammaChannel - } - } - } + val rootStatechartTraceability = compositeTraceability.createStatechartTraceability(rootFileURI) - return gammaComposite - } - - protected def getOrCreatePort(ScxmlDataType portData) { - val isProvided = portData.id.startsWith("pro_port_") - val realizationMode = isProvided ? RealizationMode.PROVIDED : RealizationMode.REQUIRED - - // Get port name and interface name from port descriptor string - val portString = portData.expr.trim - val tokens = portString.split("\\.") - if (tokens.size < 1 || tokens.size > 2) { - throw new IllegalArgumentException( - "Port descriptor " + portString + " does not contain exactly 1 or 2 dot separated tokens." - ) - } - - var scxmlInterfaceName = "" - var scxmlPortName = "" + // Execute root statechart transformation. + // The object rootStatechartTraceability is populated with data during transformation. + val rootStatechartTransformer = new ScxmlToGammaStatechartTransformer(rootStatechartTraceability) + rootStatechartTransformer.execute() - if (tokens.size == 1) { - scxmlInterfaceName = portString - scxmlPortName = portString - } else { - scxmlInterfaceName = tokens.get(tokens.size - 1) - scxmlPortName = tokens.head - } - // - - val gammaPort = portTransformer.getOrTransformPort( - scxmlPortName, - scxmlInterfaceName, - realizationMode - ) - - traceability.putPort(scxmlPortName, gammaPort) - - return gammaPort - } - - protected def createBinding(ScxmlDataType bindingData) { - val bindingString = bindingData.expr.trim - val tokens = bindingString.split("\\.|\\s*\\-\\s*") - if (tokens.size != 3) { - throw new IllegalArgumentException( - "Binding descriptor " + bindingString + " does not contain exactly 3 dot separated tokens." - ) - } - - val sourcePortName = tokens.get(0) - val targetInstanceName = tokens.get(1) - val targetPortName = tokens.get(2) - - // - - val gammaSourcePort = traceability.getPort(sourcePortName) - val gammaInstancePortReference = createInstancePortReference(targetInstanceName, targetPortName) - - val gammaPortBinding = createPortBinding(gammaSourcePort, gammaInstancePortReference) - return gammaPortBinding - } - - protected def createChannel(ScxmlDataType channelData) { - val channelString = channelData.expr.trim - val tokens = channelString.split("\\.|\\s*\\-\\s*") - if (tokens.size != 4) { - throw new IllegalArgumentException( - "Channel descriptor " + channelString + " does not contain exactly 4 dot separated tokens." - ) - } - - val sourceInstanceName = tokens.get(0) - val sourcePortName = tokens.get(1) - val targetInstanceName = tokens.get(2) - val targetPortName = tokens.get(3) - - // - - val sourceInstancePortReference = createInstancePortReference(sourceInstanceName, sourcePortName) - val targetInstancePortReference = createInstancePortReference(targetInstanceName, targetPortName) - - val gammaChannel = createChannel(sourceInstancePortReference, targetInstancePortReference) - return gammaChannel - } - - private def createInstancePortReference(String instanceName, String scxmlPortName) { - val instance = traceability.getComponentInstance(instanceName) - - // TODO Make it more performant to get statechart traceability - // by instance invokeId or source URI. - val statechartTraceability = traceability.getTraceabilityById(instanceName) - val port = statechartTraceability.getPort(scxmlPortName) - - - val instancePortReference = createInstancePortReference(instance, port) - return instancePortReference + return compositeTraceability } -} \ No newline at end of file +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index b6cc1ffd9..467cbadb4 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -1,11 +1,11 @@ /******************************************************************************** * Copyright (c) 2023 Contributors to the Gamma project - * + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation @@ -15,12 +15,14 @@ import ac.soton.scxml.ScxmlDataType import ac.soton.scxml.ScxmlFinalType import ac.soton.scxml.ScxmlHistoryType import ac.soton.scxml.ScxmlInitialType +import ac.soton.scxml.ScxmlInvokeType import ac.soton.scxml.ScxmlParallelType import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType import ac.soton.scxml.TransitionTypeDatatype import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter +import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent import hu.bme.mit.gamma.statechart.composite.ControlFunction import hu.bme.mit.gamma.statechart.composite.DiscardStrategy import hu.bme.mit.gamma.statechart.derivedfeatures.StatechartModelDerivedFeatures @@ -35,7 +37,9 @@ import hu.bme.mit.gamma.statechart.statechart.SynchronousStatechartDefinition import hu.bme.mit.gamma.statechart.statechart.Transition import hu.bme.mit.gamma.statechart.statechart.TransitionPriority import java.math.BigInteger +import java.util.List import java.util.logging.Level +import org.eclipse.emf.common.util.URI import static ac.soton.scxml.ScxmlModelDerivedFeatures.* import static hu.bme.mit.gamma.scxml.transformation.Namings.* @@ -44,37 +48,167 @@ import static hu.bme.mit.gamma.scxml.transformation.Namings.* // TODO History, parallel class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { + // Reference to the composite transformation traceability model + protected final CompositeTraceability compositeTraceability + protected final extension ActionTransformer actionTransformer protected final extension DataTransformer dataTransformer protected final extension PortTransformer portTransformer protected final extension TriggerTransformer triggerTransformer // Root element of the SCXML statechart model to transform - protected final ScxmlScxmlType scxmlRoot + protected ScxmlScxmlType scxmlRoot + + // Contained elements invoking SCXML substatecharts + protected List invokes // Asynchronous wrapper component around the synchronous statechart definition protected AsynchronousAdapter adapter // Root element of the Gamma statechart definition as the transformation result - protected final SynchronousStatechartDefinition gammaStatechart + protected SynchronousStatechartDefinition gammaStatechart - new(ScxmlScxmlType scxmlRoot, StatechartTraceability traceability) { + new(StatechartTraceability traceability) { super(traceability) - this.scxmlRoot = scxmlRoot - this.adapter = null - this.gammaStatechart = createSynchronousStatechartDefinition => [ - it.name = getStatechartName(scxmlRoot) - ] + compositeTraceability = traceability.compositeTraceability + /* TODO Load and set scxmlRoot, create default StDef + * scxmlRoot + * this.gammaStatechart = createSynchronousStatechartDefinition => [ + * it.name = getStatechartName(scxmlRoot) + * ] + */ this.actionTransformer = new ActionTransformer(traceability) this.dataTransformer = new DataTransformer(traceability) this.portTransformer = new PortTransformer(traceability) this.triggerTransformer = new TriggerTransformer(traceability) } - // Transformation of the SCXML root element and its contents recursively - def execute() { + // TODO This will be the execute() method, combine with former statechart transformer execute() + protected def AsynchronousComponent execute() { + initQueueCapacity + + // TODO Check if not already transformed (at caller side or in this transformation method) + val fileURI = traceability.fileURI + val scxmlRoot = loadSubcomponent(fileURI) + traceability.scxmlRoot = scxmlRoot + + gammaStatechart = createSynchronousStatechartDefinition => [ + it.name = getStatechartName(scxmlRoot) + ] + traceability.statechart = gammaStatechart + + // TODO First, transform all invoked statechart types + // (recursively, through transformation calls to types of contained components) + // Then transform individual statecharts with invoke actions, referencing invoked types + // Note: circular references in invoke chains are not supported. + invokes = getAllInvokes(scxmlRoot) + + for (invoke : invokes) { + // TODO Check src | srcexpr + val invokedSrc = invoke.src + + if (!compositeTraceability.containsTraceability(invokedSrc)) { + // Create (and store reference to) new statechart type transformation traceability + val invokedStatechartTraceability = compositeTraceability.createStatechartTraceability(invokedSrc) + compositeTraceability.putTraceability(invokedSrc, invokedStatechartTraceability) + + // Execute root statechart transformation. + // The object rootStatechartTraceability is populated with trace data during transformation. + val invokedStatechartTransformer = new ScxmlToGammaStatechartTransformer(invokedStatechartTraceability) + invokedStatechartTransformer.execute() + } + } + + // Transform statechart after invoked statechart type transformations have finished + // TODO Transform control, action, data and communication elements + return scxmlRoot.transformStatechart + } + + private def loadSubcomponent(String path) { + val fileURI = URI.createPlatformResourceURI(path, true); + val documentRoot = ecoreUtil.normalLoad(fileURI); + + val scxmlRoot = ecoreUtil.getFirstOfAllContentsOfType(documentRoot, ScxmlScxmlType); + return scxmlRoot + } + + private def initQueueCapacity() { + // Define default queue capacity + val queueCapacityDeclaration = createConstantDeclaration + queueCapacityDeclaration.name = "QUEUE_CAPACITY" + + val capacity = expressionUtil.toIntegerLiteral(4) + queueCapacityDeclaration.expression = capacity + queueCapacityDeclaration.type = createIntegerTypeDefinition + + compositeTraceability.setQueueCapacity(queueCapacityDeclaration) + } + + protected def transformStatechart(ScxmlScxmlType scxmlRoot) { + val gammaComposite = createScheduledAsynchronousCompositeComponent + gammaComposite.name = getCompositeStatechartName(scxmlRoot) + + // Instantiate transformed invoked child statecharts + for (invoke : invokes) { + val statechartTraceability = compositeTraceability.getTraceability(invoke.src) + + // TODO Extend to deeper composition hierarchy levels later + val gammaSubcomponentType = statechartTraceability.adapter as AsynchronousComponent + + val gammaSubcomponent = gammaSubcomponentType.instantiateAsynchronousComponent + gammaSubcomponent.name = invoke.id + gammaComposite.components += gammaSubcomponent + + compositeTraceability.putComponentInstance(invoke, gammaSubcomponent) + } + + // Create ports, port bindings and channels in the composite component + val datamodels = scxmlRoot.datamodel + if (datamodels !== null) { + val datamodel = datamodels.head + if (datamodel !== null) { + val dataElements = getDataElements(datamodel) + + // TODO Move string literal parts of names to Namings + val portDataElements = dataElements.filter [ it | + it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("pro_port_") || + it.id.startsWith("req_port_") + ] + for (portData : portDataElements) { + val gammaPort = portData.getOrCreatePort + gammaComposite.ports += gammaPort + } + + val bindingDataElements = dataElements.filter [ it | + it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("binding_") + ] + for (binding : bindingDataElements) { + val gammaPortBinding = binding.createBinding + gammaComposite.portBindings += gammaPortBinding + } + + val channelDataElements = dataElements.filter [ it | + it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("channel_") + ] + for (channel : channelDataElements) { + val gammaChannel = channel.createChannel + gammaComposite.channels += gammaChannel + } + } + } + + // TODO Merge methods logically + transformStatechartInnerElements + + return gammaComposite + } + + // TODO Merge this statechart transformation with 'composite' transformation method + // Transformation of the SCXML root element and its contents recursively. + // Invoked types are assumed to be already transformed by this point. + def transformStatechartInnerElements() { traceability.setStatechart(gammaStatechart) logger.log(Level.INFO, "Transforming root element (" + scxmlRoot.name + ")") @@ -85,13 +219,13 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { gammaStatechart.orthogonalRegionSchedulingOrder = OrthogonalRegionSchedulingOrder.SEQUENTIAL gammaStatechart.transitionPriority = TransitionPriority.ORDER_BASED; gammaStatechart.guardEvaluation = GuardEvaluation.BEGINNING_OF_STEP - + val datamodels = scxmlRoot.datamodel if (datamodels !== null) { val datamodel = datamodels.head if (datamodel !== null) { val dataElements = getDataElements(datamodel) - + // TODO Move string literal parts of names to Namings val portDataElements = dataElements.filter [ it | it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("pro_port_") || @@ -195,22 +329,80 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { scxmlPortName = tokens.head } // - val gammaPort = portTransformer.getOrTransformPort( scxmlPortName, scxmlInterfaceName, realizationMode ) + + // TODO Put port into composite or statechart traceability? + compositeTraceability.putPort(scxmlPortName, gammaPort) + return gammaPort } + protected def createBinding(ScxmlDataType bindingData) { + val bindingString = bindingData.expr.trim + val tokens = bindingString.split("\\.|\\s*\\-\\s*") + if (tokens.size != 3) { + throw new IllegalArgumentException( + "Binding descriptor " + bindingString + " does not contain exactly 3 dot separated tokens." + ) + } + + val sourcePortName = tokens.get(0) + val targetInstanceName = tokens.get(1) + val targetPortName = tokens.get(2) + + // + val gammaSourcePort = compositeTraceability.getPort(sourcePortName) + val gammaInstancePortReference = createInstancePortReference(targetInstanceName, targetPortName) + + val gammaPortBinding = createPortBinding(gammaSourcePort, gammaInstancePortReference) + return gammaPortBinding + } + + protected def createChannel(ScxmlDataType channelData) { + val channelString = channelData.expr.trim + val tokens = channelString.split("\\.|\\s*\\-\\s*") + if (tokens.size != 4) { + throw new IllegalArgumentException( + "Channel descriptor " + channelString + " does not contain exactly 4 dot separated tokens." + ) + } + + val sourceInstanceName = tokens.get(0) + val sourcePortName = tokens.get(1) + val targetInstanceName = tokens.get(2) + val targetPortName = tokens.get(3) + + // + val sourceInstancePortReference = createInstancePortReference(sourceInstanceName, sourcePortName) + val targetInstancePortReference = createInstancePortReference(targetInstanceName, targetPortName) + + val gammaChannel = createChannel(sourceInstancePortReference, targetInstancePortReference) + return gammaChannel + } + + private def createInstancePortReference(String instanceName, String scxmlPortName) { + val instance = compositeTraceability.getComponentInstance(instanceName) + + // TODO Make it more performant to get statechart traceability + // by instance invokeId or source URI. + val statechartTraceability = compositeTraceability.getTraceabilityById(instanceName) + val port = statechartTraceability.getPort(scxmlPortName) + + val instancePortReference = createInstancePortReference(instance, port) + return instancePortReference + } + protected def AsynchronousAdapter wrapIntoAdapter() { adapter = gammaStatechart.wrapIntoAdapter(getAdapterName(scxmlRoot)) - + val allStatechartPorts = StatechartModelDerivedFeatures.getAllPortsWithInput(gammaStatechart) - val allInternalPorts = allStatechartPorts.filter[it | StatechartModelDerivedFeatures.isInternal(it)] - val allExternalPorts = allStatechartPorts.filter[it | !StatechartModelDerivedFeatures.isInternal(it)] - + val allInternalPorts = allStatechartPorts.filter[it|StatechartModelDerivedFeatures.isInternal(it)] + val allExternalPorts = allStatechartPorts.filter[it|!StatechartModelDerivedFeatures.isInternal(it)] + // Set control specification // TODO Check if internal port event triggers should be added as control specification triggers. for (port : allExternalPorts) { @@ -218,36 +410,36 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { for (event : portEvents) { val controlSpecification = createControlSpecification controlSpecification.controlFunction = ControlFunction.RUN_ONCE - + val eventReference = createPortEventReference eventReference.port = port eventReference.event = event - + val trigger = createEventTrigger trigger.eventReference = eventReference controlSpecification.trigger = trigger - + adapter.controlSpecifications += controlSpecification } } - + // Create internal event queue val internalEventQueue = createMessageQueue internalEventQueue.name = getInternalEventQueueName(scxmlRoot) internalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING internalEventQueue.priority = BigInteger.TWO - + val internalCapacityReference = createDirectReferenceExpression internalCapacityReference.declaration = traceability.queueCapacityDeclaration internalEventQueue.capacity = internalCapacityReference - + for (port : allInternalPorts) { val portEvents = StatechartModelDerivedFeatures.getInputEvents(port) for (event : portEvents) { val reference = createPortEventReference reference.port = port reference.event = event - + val eventPassing = createEventPassing(reference) internalEventQueue.eventPassings += eventPassing } @@ -260,18 +452,18 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { externalEventQueue.name = getExternalEventQueueName(scxmlRoot) externalEventQueue.eventDiscardStrategy = DiscardStrategy.INCOMING externalEventQueue.priority = BigInteger.ONE - + val externalCapacityReference = createDirectReferenceExpression externalCapacityReference.declaration = traceability.queueCapacityDeclaration externalEventQueue.capacity = externalCapacityReference - + for (port : allExternalPorts) { val portEvents = StatechartModelDerivedFeatures.getInputEvents(port) for (event : portEvents) { val reference = createPortEventReference reference.port = port reference.event = event - + val eventPassing = createEventPassing(reference) externalEventQueue.eventPassings += eventPassing } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend index 3b8e2c5c3..fa1fb5679 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend @@ -1,11 +1,11 @@ /******************************************************************************** * Copyright (c) 2023 Contributors to the Gamma project - * + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation @@ -40,12 +40,18 @@ import static com.google.common.base.Preconditions.checkNotNull class StatechartTraceability { + // Reference to the composite transformation traceability model + protected final CompositeTraceability compositeTraceability + + // URI of the root SCXML statechart model to transform + protected final String fileURI + // Root element of the atomic SCXML statechart model to transform. - protected final ScxmlScxmlType scxmlRoot + protected ScxmlScxmlType scxmlRoot protected SynchronousStatechartDefinition statechart protected AsynchronousAdapter adapter protected ConstantDeclaration queueCapacity - + protected final Map parallels = newHashMap protected final Map states = newHashMap protected final Map finals = newHashMap @@ -53,18 +59,18 @@ class StatechartTraceability { protected final Map historyStates = newHashMap protected final Map transitions = newHashMap protected final Set initialTransitions = newHashSet - + protected final Map dataElements = newHashMap - + // Works only if variables are globally unique and have a global scope protected final Map variables = newHashMap - + // Internal mappings (internal to the statechart) protected Port defaultPort protected Interface defaultInterface protected final Map defaultInterfacePorts = newHashMap protected final Map ports = newHashMap - + // Global mappings (from composite traceability) protected final Map interfaces protected final Map, Event> internalEvents @@ -72,16 +78,19 @@ class StatechartTraceability { protected final Map, Event> outEvents protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE - + // - Synchronous Statechart Definition - new(ScxmlScxmlType scxmlRoot, + new( + CompositeTraceability compositeTraceability, + String rootFileURI, Map interfaces, ConstantDeclaration queueCapacity, Map, Event> internalEvents, Map, Event> inEvents, Map, Event> outEvents ) { - this.scxmlRoot = scxmlRoot + this.compositeTraceability = compositeTraceability + this.fileURI = rootFileURI this.interfaces = interfaces this.queueCapacity = queueCapacity this.internalEvents = internalEvents @@ -92,19 +101,19 @@ class StatechartTraceability { def getScxmlRoot() { return scxmlRoot } - + def getTypeName() { return scxmlRoot.name } - + def setAdapter(AsynchronousAdapter adapter) { this.adapter = adapter } - + def getAdapter() { return adapter } - + def getQueueCapacityDeclaration() { checkNotNull(queueCapacity) return queueCapacity @@ -240,7 +249,7 @@ class StatechartTraceability { checkNotNull(gammaHistory) return gammaHistory as StateNode } - + // Retrieves the mapped Gamma StateNode for an arbitrary transition target state id def getStateNodeById(String scxmlStateNodeId) { val gammaState = states.entrySet.findFirst[entry|entry.key.id == scxmlStateNodeId]?.value @@ -274,24 +283,24 @@ class StatechartTraceability { checkNotNull(gammaTransition) return gammaTransition } - + // Transitions from initial states of Gamma compound states // specified by scxml initial attributes or document order def putInitialTransition(Transition gammaTransition) { checkNotNull(gammaTransition) initialTransitions += gammaTransition } - + def getInitialTransitions() { return initialTransitions } - + // - VariableDeclaration def put(ScxmlDataType scxmlData, VariableDeclaration gammaDeclaration) { checkNotNull(scxmlData) checkNotNull(gammaDeclaration) dataElements += scxmlData -> gammaDeclaration - + put(scxmlData.id, gammaDeclaration) } @@ -301,7 +310,7 @@ class StatechartTraceability { checkNotNull(gammaDeclaration) return gammaDeclaration } - + // Variable Declarations by String identifier private def put(String scxmlVariableName, VariableDeclaration gammaDeclaration) { checkNotNull(scxmlVariableName) @@ -315,66 +324,66 @@ class StatechartTraceability { checkNotNull(gammaDeclaration) return gammaDeclaration } - + // Default port and interface (for event strings like 'event') def getDefaultInterface() { return defaultInterface } - + def setDefaultInterface(Interface defaultInterface) { this.defaultInterface = defaultInterface } - + def getDefaultPort() { return defaultPort } - + def setDefaultPort(Port defaultPort) { this.defaultPort = defaultPort } - + // Default ports of interfaces (for event strings like 'interface.event') def putDefaultInterfacePort(Interface gammaInterface, Port gammaPort) { checkNotNull(gammaInterface) checkNotNull(gammaPort) defaultInterfacePorts += gammaInterface -> gammaPort } - + def getDefaultInterfacePort(Interface gammaInterface) { checkNotNull(gammaInterface) val gammaPort = defaultInterfacePorts.get(gammaInterface) checkNotNull(gammaPort) return gammaPort } - + def containsDefaultInterfacePort(Interface gammaInterface) { checkNotNull(gammaInterface) return defaultInterfacePorts.containsKey(gammaInterface) } - + // Interfaces by string identifier (for event strings like '[port.]interface.event) def putInterface(String scxmlInterfaceName, Interface gammaInterface) { checkNotNull(scxmlInterfaceName) checkNotNull(gammaInterface) interfaces += scxmlInterfaceName -> gammaInterface } - + def getInterface(String scxmlInterfaceName) { checkNotNull(scxmlInterfaceName) val gammaInterface = interfaces.get(scxmlInterfaceName) checkNotNull(gammaInterface) return gammaInterface } - + def containsInterface(String scxmlInterfaceName) { checkNotNull(scxmlInterfaceName) return interfaces.containsKey(scxmlInterfaceName) } - + def getInterfaces() { return interfaces; } - + def getAllInterfaces() { var allInterfaces = interfaces.values.toList allInterfaces += defaultInterfacePorts.keySet.toList @@ -383,126 +392,126 @@ class StatechartTraceability { } return allInterfaces } - + // Ports by string identifier (for event strings like 'port.interface.event) def putPort(String scxmlPortName, Port gammaPort) { checkNotNull(scxmlPortName) checkNotNull(gammaPort) ports += scxmlPortName -> gammaPort } - + def getPort(String scxmlPortName) { checkNotNull(scxmlPortName) val gammaPort = ports.get(scxmlPortName) checkNotNull(gammaPort) return gammaPort } - + def containsPort(String scxmlPortName) { checkNotNull(scxmlPortName) return ports.containsKey(scxmlPortName) } - + // Internal events by pairs of {Gamma interface; event name} def putInternalEvent(Pair interfaceEvent, Event gammaEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) checkNotNull(gammaEvent) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value internalEvents += (interface -> eventName) -> gammaEvent } - + def getInternalEvent(Pair interfaceEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value val gammaEvent = internalEvents.get(interface -> eventName) - + checkNotNull(gammaEvent) return gammaEvent } - + def containsInternalEvent(Pair interfaceEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value return internalEvents.containsKey(interface -> eventName) } - + // Input events by pairs of {Gamma interface; event name} def putInEvent(Pair interfaceEvent, Event gammaEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) checkNotNull(gammaEvent) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value inEvents += (interface -> eventName) -> gammaEvent } - + def getInEvent(Pair interfaceEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value val gammaEvent = inEvents.get(interface -> eventName) - + checkNotNull(gammaEvent) return gammaEvent } - + def containsInEvent(Pair interfaceEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value return inEvents.containsKey(interface -> eventName) } - + // Output events by pairs of {port name; event name} def putOutEvent(Pair interfaceEvent, Event gammaEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) checkNotNull(gammaEvent) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value outEvents += (interface -> eventName) -> gammaEvent } - + def getOutEvent(Pair interfaceEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value val gammaEvent = outEvents.get(interface -> eventName) - + checkNotNull(gammaEvent) return gammaEvent } - + def containsOutEvent(Pair interfaceEvent) { checkNotNull(interfaceEvent) checkNotNull(interfaceEvent.key) checkNotNull(interfaceEvent.value) - + val interface = interfaceEvent.key val eventName = interfaceEvent.value return outEvents.containsKey(interface -> eventName) From 23a4d1321abfe4042163f5cef67074320b7dabcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Wed, 11 Dec 2024 18:25:33 +0100 Subject: [PATCH 27/30] Fix composite transformation errors --- .../commandhandler/CommandHandler.java | 6 +++--- .../transformation/CompositeTraceability.xtend | 12 ++++++------ .../ScxmlToGammaCompositeTransformer.xtend | 17 +++++++++++++++-- .../ScxmlToGammaStatechartTransformer.xtend | 18 ++++-------------- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 35891a758..7784d76a9 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -72,10 +72,10 @@ public Object execute(ExecutionEvent event) throws ExecutionException { // package List gammaInterfaces = new ArrayList( compositeTraceability.getInterfaces()); - Package gammaInterfacePackage = statechartUtil.wrapIntoPackage(gammaInterfaces.get(0)); + gammaInterfaces.removeIf(i -> i == null); ScxmlScxmlType scxmlRoot = compositeTraceability.getScxmlRoot(); - gammaInterfacePackage.setName(Namings.getInterfacePackageName(scxmlRoot)); - gammaInterfaces.remove(0); + Package gammaInterfacePackage = statechartUtil.createPackage( + Namings.getInterfacePackageName(scxmlRoot)); gammaInterfacePackage.getInterfaces().addAll(gammaInterfaces); List gammaConstants = new ArrayList( diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend index ca8c7174b..4fd7da972 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -13,7 +13,6 @@ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlInvokeType import ac.soton.scxml.ScxmlScxmlType import hu.bme.mit.gamma.expression.model.ConstantDeclaration -import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent import hu.bme.mit.gamma.statechart.composite.AsynchronousComponentInstance import hu.bme.mit.gamma.statechart.interface_.Component import hu.bme.mit.gamma.statechart.interface_.Event @@ -51,7 +50,7 @@ class CompositeTraceability { new(String rootFileURI) { this.rootFileURI = rootFileURI } - + // Creates a traceability object for the Gamma transformation of // the SCXML statechart model found at rootFileURI. def createStatechartTraceability(String rootFileURI) { @@ -76,14 +75,14 @@ class CompositeTraceability { def getRootComponent() { val rootTraceability = getTraceability(rootFileURI) - + // TODO Which kind of root Gamma component should we return? statechart / adapter / other? val rootComponent = rootTraceability.statechart checkNotNull(rootComponent) return rootComponent } - def setRootComponent(AsynchronousComponent rootComponent) { + def setRootComponent(Component rootComponent) { this.rootComponent = rootComponent } @@ -203,8 +202,9 @@ class CompositeTraceability { def getComponents() { val statechartTraceabilities = statecharts.values - return (instances.values.map[it.getType] + statechartTraceabilities.map[it.getAdapter] + - statechartTraceabilities.map[it.getStatechart] + return (instances.values.map[it.getType] + /* TODO Serialize async adapters */ + /* statechartTraceabilities.map[it.getAdapter] + */ + statechartTraceabilities.map[it.getStatechart] ).toSet } } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend index 3e00f6935..d42bdd4ab 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend @@ -10,8 +10,6 @@ ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation -import hu.bme.mit.gamma.statechart.interface_.Component - class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { // Root element of the SCXML statechart model to transform @@ -28,6 +26,9 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { // Entry point for the SCXML to Gamma hierarchical statechart transformation def execute() { + // Initialize constants + initQueueCapacity + val rootStatechartTraceability = compositeTraceability.createStatechartTraceability(rootFileURI) // Execute root statechart transformation. @@ -37,4 +38,16 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { return compositeTraceability } + + private def initQueueCapacity() { + // Define default queue capacity + val queueCapacityDeclaration = createConstantDeclaration + queueCapacityDeclaration.name = "QUEUE_CAPACITY" + + val capacity = expressionUtil.toIntegerLiteral(4) + queueCapacityDeclaration.expression = capacity + queueCapacityDeclaration.type = createIntegerTypeDefinition + + compositeTraceability.setQueueCapacity(queueCapacityDeclaration) + } } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 467cbadb4..8df60ef09 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -87,11 +87,13 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { // TODO This will be the execute() method, combine with former statechart transformer execute() protected def AsynchronousComponent execute() { - initQueueCapacity + + // Put statechart traceability in composite traceability object + compositeTraceability.putTraceability(traceability.fileURI, traceability) // TODO Check if not already transformed (at caller side or in this transformation method) val fileURI = traceability.fileURI - val scxmlRoot = loadSubcomponent(fileURI) + scxmlRoot = loadSubcomponent(fileURI) traceability.scxmlRoot = scxmlRoot gammaStatechart = createSynchronousStatechartDefinition => [ @@ -134,18 +136,6 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { return scxmlRoot } - private def initQueueCapacity() { - // Define default queue capacity - val queueCapacityDeclaration = createConstantDeclaration - queueCapacityDeclaration.name = "QUEUE_CAPACITY" - - val capacity = expressionUtil.toIntegerLiteral(4) - queueCapacityDeclaration.expression = capacity - queueCapacityDeclaration.type = createIntegerTypeDefinition - - compositeTraceability.setQueueCapacity(queueCapacityDeclaration) - } - protected def transformStatechart(ScxmlScxmlType scxmlRoot) { val gammaComposite = createScheduledAsynchronousCompositeComponent gammaComposite.name = getCompositeStatechartName(scxmlRoot) From c913c5711f90ac6b97476a039a38dcfd2bb106d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Thu, 13 Mar 2025 13:42:22 +0100 Subject: [PATCH 28/30] Transform if actions, preprocess Gamma expressions --- .../transformation/ActionTransformer.xtend | 39 +++++++++---------- .../ScxmlToGammaStatechartTransformer.xtend | 10 ++++- .../ScxmlGammaExpressionLanguageParser.java | 34 +++++++++++++--- 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index 5714b43b3..d04b74c90 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -25,6 +25,8 @@ import hu.bme.mit.gamma.statechart.interface_.RealizationMode import java.util.logging.Level import org.eclipse.emf.ecore.EObject +import static ac.soton.scxml.ScxmlModelDerivedFeatures.* + class ActionTransformer extends AtomicElementTransformer { protected final extension PortTransformer portTransformer @@ -43,9 +45,8 @@ class ActionTransformer extends AtomicElementTransformer { def Action transformOnentry(ScxmlOnentryType scxmlOnentry) { logger.log(Level.INFO, "Transforming element (" + scxmlOnentry + ")") - - // TODO Get list of all children actions, not just -s - val scxmlActions = scxmlOnentry.assign + scxmlOnentry.raise + + val scxmlActions = getOnentryActions(scxmlOnentry) if (!scxmlActions.nullOrEmpty) { val gammaEntryAction = scxmlActions.transformBlock; return gammaEntryAction @@ -55,9 +56,8 @@ class ActionTransformer extends AtomicElementTransformer { def Action transformOnexit(ScxmlOnexitType scxmlOnexit) { logger.log(Level.INFO, "Transforming element (" + scxmlOnexit + ")") - - // TODO Get list of all children actions, not just -s - val scxmlActions = scxmlOnexit.assign + scxmlOnexit.raise + + val scxmlActions = getOnexitActions(scxmlOnexit) if (!scxmlActions.nullOrEmpty) { val gammaExitAction = scxmlActions.transformBlock; return gammaExitAction @@ -136,20 +136,19 @@ class ActionTransformer extends AtomicElementTransformer { def dispatch Action transformAction(ScxmlIfType scxmlIf) { logger.log(Level.INFO, "Transforming element (" + scxmlIf + ")") - // TODO - /* - * val gammaIf = createIfStatement - * val cond = scxmlIf.cond - * if (!cond.nullOrEmpty) { - * val condExpression = expressionLanguageParser.parse(cond, traceability.variables) - * val thenExpression = scxmlIf. - * val elseExpression = scxmlIf. - * - * val gammaConditional = createConditional - * gammaIf.conditionals += - * } - */ - val gammaIf = createEmptyStatement + val gammaIf = createIfStatement + val cond = scxmlIf.cond + if (!cond.nullOrEmpty) { + val condExpression = expressionLanguageParser.parse(cond, traceability.variables) + + val thenStatements = getIfThenActions(scxmlIf); + val gammaThenStatements = thenStatements.transformBlock + + val gammaConditional = createBranch + gammaConditional.guard = condExpression + gammaConditional.action = gammaThenStatements + gammaIf.conditionals += gammaConditional + } return gammaIf } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index 8df60ef09..b73024afc 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -584,14 +584,20 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { val onentryActions = scxmlState.onentry for (onentryAction : onentryActions) { if (onentryAction !== null) { - gammaState.entryActions += onentryAction.transformOnentry + val gammaOnEntryActions = onentryAction.transformOnentry + if (gammaOnEntryActions !== null) { + gammaState.entryActions += gammaOnEntryActions + } } } val onexitActions = scxmlState.onexit for (onexitAction : onexitActions) { if (onexitAction !== null) { - gammaState.exitActions += onexitAction.transformOnexit + val gammaOnExitActions = onexitAction.transformOnexit + if (gammaOnExitActions !== null) { + gammaState.exitActions += gammaOnExitActions + } } } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java index 7846ab653..dd34c1a62 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java @@ -27,21 +27,31 @@ import hu.bme.mit.gamma.expression.model.OpaqueExpression; import hu.bme.mit.gamma.expression.model.VariableDeclaration; +import static java.util.Map.entry; + // TODO rename, e.g. Custom... public class ScxmlGammaExpressionLanguageParser { - - ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE; - private Injector injector = new ExpressionLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); + private static final Map preprocessRules = Map.ofEntries( + entry("!", "not"), + entry("&&", "and"), + entry("||", "or") + ); + + private final ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE; + + private final Injector injector = new ExpressionLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); // Works only if variables in the scope are globally unique and have a global scope public Expression parse(String expression, Map scope) { + String preprocessedExpression = preprocessExpression(expression); + ScxmlGammaLanguageParser parser = injector.getInstance(ScxmlGammaLanguageParser.class); - StringReader reader = new StringReader(expression); + StringReader reader = new StringReader(preprocessedExpression); IParseResult result = parser.parse(reader); if (result.hasSyntaxErrors()) { - return createOpaqueExpression(expression); + return createOpaqueExpression(preprocessedExpression); } try { @@ -63,6 +73,20 @@ public Expression parse(String expression, Map scop return createOpaqueExpression(expression); } + + private String preprocessExpression(String expression) { + var preprocessedExpression = preprocess(expression, preprocessRules); + return preprocessedExpression; + } + + private String preprocess(String expression, Map preprocess) { + String preprocessedExpression = expression; + for (String key : preprocess.keySet()) { + String value = preprocess.get(key); + preprocessedExpression = preprocessedExpression.replace(key, value); + } + return preprocessedExpression; + } private Expression createOpaqueExpression(String expression) { OpaqueExpression opaqueExpression = expressionModelFactory.createOpaqueExpression(); From 43905706076121028f0823d4d392d9079840c53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Thu, 13 Mar 2025 14:14:06 +0100 Subject: [PATCH 29/30] Add basic send action transformation --- .../transformation/ActionTransformer.xtend | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index d04b74c90..68ac68fe6 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -26,6 +26,7 @@ import java.util.logging.Level import org.eclipse.emf.ecore.EObject import static ac.soton.scxml.ScxmlModelDerivedFeatures.* +import ac.soton.scxml.ScxmlSendType class ActionTransformer extends AtomicElementTransformer { @@ -45,7 +46,7 @@ class ActionTransformer extends AtomicElementTransformer { def Action transformOnentry(ScxmlOnentryType scxmlOnentry) { logger.log(Level.INFO, "Transforming element (" + scxmlOnentry + ")") - + val scxmlActions = getOnentryActions(scxmlOnentry) if (!scxmlActions.nullOrEmpty) { val gammaEntryAction = scxmlActions.transformBlock; @@ -56,7 +57,7 @@ class ActionTransformer extends AtomicElementTransformer { def Action transformOnexit(ScxmlOnexitType scxmlOnexit) { logger.log(Level.INFO, "Transforming element (" + scxmlOnexit + ")") - + val scxmlActions = getOnexitActions(scxmlOnexit) if (!scxmlActions.nullOrEmpty) { val gammaExitAction = scxmlActions.transformBlock; @@ -129,6 +130,46 @@ class ActionTransformer extends AtomicElementTransformer { } // Event parameters are currently not supported. + // TODO Support payload + val gammaRaise = createRaiseEventAction(gammaPort, gammaEvent, newArrayList) + return gammaRaise + } + + // TODO actions + // TODO Is traceability entry needed? + def dispatch Action transformAction(ScxmlSendType scxmlSend) { + logger.log(Level.INFO, "Transforming element (" + scxmlSend + ")") + + // TODO Check nulls / empty substrings + val eventString = scxmlSend.event + val targetInterfacePortString = scxmlSend.targetexpr + val eventTargetString = targetInterfacePortString + "." + eventString + + val tokens = eventTargetString.split("\\.") + if (tokens.size < 2 || tokens.size > 3) { + throw new IllegalArgumentException( + "Event descriptor " + eventString + " does not contain exactly 2 or 3 dot separated tokens." + ) + } + + var gammaInterface = null as Interface + var gammaPort = null as Port + + val interfaceName = tokens.get(tokens.size - 2) + gammaInterface = getOrTransformInterfaceByName(interfaceName) + + if (tokens.size >= 3) { + val portName = tokens.head + gammaPort = getOrTransformPortByName(gammaInterface, portName, RealizationMode.PROVIDED) + } else { + gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) + } + + val eventName = tokens.last + val gammaEvent = getOrTransformOutEvent(gammaInterface, eventName) + + // Event parameters are currently not supported. + // TODO Support payload val gammaRaise = createRaiseEventAction(gammaPort, gammaEvent, newArrayList) return gammaRaise } From c6169f1cef5db64a3849930109a97cb0c68cabf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Radnai?= Date: Mon, 16 Feb 2026 00:46:54 +0100 Subject: [PATCH 30/30] Update adaptive statechart transformation and expression linking --- ...hartExpressionLanguageParserAndLinker.java | 1 + .../commandhandler/CommandHandler.java | 12 +- .../META-INF/MANIFEST.MF | 6 +- .../transformation/AbstractTransformer.xtend | 14 +- .../transformation/ActionTransformer.xtend | 247 ++++++++++++++++-- .../AtomicElementTransformer.xtend | 8 +- .../CompositeElementTransformer.xtend | 2 +- .../CompositeTraceability.xtend | 31 ++- .../transformation/DataTransformer.xtend | 21 +- .../gamma/scxml/transformation/Namings.xtend | 21 +- .../ScxmlToGammaCompositeTransformer.xtend | 2 +- .../ScxmlToGammaStatechartTransformer.xtend | 71 +++-- .../StatechartTraceability.xtend | 103 +++++++- .../transformation/TriggerTransformer.xtend | 50 ++-- .../ScxmlGammaExpressionLanguageLinker.xtend | 106 ++++++++ .../ScxmlGammaExpressionLanguageParser.java | 167 +++++++----- .../parse/ScxmlGammaLanguageParser.java | 24 -- 17 files changed, 676 insertions(+), 210 deletions(-) create mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageLinker.xtend delete mode 100644 plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java diff --git a/plugins/core/hu.bme.mit.gamma.statechart.language/src/hu/bme/mit/gamma/statechart/language/parser/StatechartExpressionLanguageParserAndLinker.java b/plugins/core/hu.bme.mit.gamma.statechart.language/src/hu/bme/mit/gamma/statechart/language/parser/StatechartExpressionLanguageParserAndLinker.java index 872849143..34d99e63e 100644 --- a/plugins/core/hu.bme.mit.gamma.statechart.language/src/hu/bme/mit/gamma/statechart/language/parser/StatechartExpressionLanguageParserAndLinker.java +++ b/plugins/core/hu.bme.mit.gamma.statechart.language/src/hu/bme/mit/gamma/statechart/language/parser/StatechartExpressionLanguageParserAndLinker.java @@ -26,6 +26,7 @@ protected Injector getInjector() { return new StatechartLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); } + @Override protected Class getParserClass() { return CustomStatechartExpressionLanguageParser.class; } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java index 7784d76a9..0d99f7576 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation.commandhandler/src/hu/bme/mit/gamma/scxml/transformation/commandhandler/CommandHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project + * Copyright (c) 2023-2025 Contributors to the Gamma project * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -64,12 +64,10 @@ public Object execute(ExecutionEvent event) throws ExecutionException { String path = file.getFullPath().toString(); // Model processing - ScxmlToGammaCompositeTransformer compositeTransformer = new ScxmlToGammaCompositeTransformer( - path); + ScxmlToGammaCompositeTransformer compositeTransformer = new ScxmlToGammaCompositeTransformer(path); CompositeTraceability compositeTraceability = compositeTransformer.execute(); - // Interfaces and type declarations have to be explicitly serialized in another - // package + // Interfaces and type declarations have to be explicitly serialized in another package List gammaInterfaces = new ArrayList( compositeTraceability.getInterfaces()); gammaInterfaces.removeIf(i -> i == null); @@ -94,8 +92,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { StatechartLanguageSerializer packageSerializer = new StatechartLanguageSerializer(); logger.log(Level.INFO, "Start serializing Gamma packages..."); - // String declarationsPackageFileName = extensionlessFileName + - // "Declarations.gsm"; + // String declarationsPackageFileName = extensionlessFileName + "Declarations.gsm"; // ecoreUtil.normalSave(gammaInterfacePackage, parentPath, // declarationsPackageFileName); String declarationsPackageFileName = extensionlessFileName + "Declarations.gcd"; @@ -108,7 +105,6 @@ public Object execute(ExecutionEvent event) throws ExecutionException { packageSerializer.serialize(gammaCompositePackage, parentPath, compositePackageFileName); logger.log(Level.INFO, "The SCXML - Gamma statechart transformation has finished."); - } } } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF index ec6fd76e9..d0482add8 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/META-INF/MANIFEST.MF @@ -13,9 +13,11 @@ Require-Bundle: ac.soton.scxml, org.eclipse.xtend.lib.macro, hu.bme.mit.gamma.expression.language, com.google.inject;bundle-version="3.0.0", - hu.bme.mit.gamma.expression.model + hu.bme.mit.gamma.expression.model, + org.eclipse.xtext Export-Package: hu.bme.mit.gamma.scxml.transformation -Import-Package: org.antlr.runtime, +Import-Package: hu.bme.mit.gamma.statechart.language.parser, + org.antlr.runtime, org.eclipse.xtext, org.eclipse.xtext.nodemodel, org.eclipse.xtext.parser, diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend index 2883f9c68..dbe2a473c 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AbstractTransformer.xtend @@ -1,20 +1,19 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project - * + * Copyright (c) 2023-2025 Contributors to the Gamma project + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation import hu.bme.mit.gamma.action.model.ActionModelFactory -import hu.bme.mit.gamma.action.util.ActionUtil import hu.bme.mit.gamma.expression.model.ExpressionModelFactory import hu.bme.mit.gamma.expression.util.ExpressionTypeDeterminator2 -import hu.bme.mit.gamma.expression.util.ExpressionUtil +import hu.bme.mit.gamma.scxml.transformation.parse.ScxmlGammaExpressionLanguageLinker import hu.bme.mit.gamma.scxml.transformation.parse.ScxmlGammaExpressionLanguageParser import hu.bme.mit.gamma.statechart.composite.CompositeModelFactory import hu.bme.mit.gamma.statechart.interface_.InterfaceModelFactory @@ -28,8 +27,8 @@ abstract class AbstractTransformer { protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE protected final extension StatechartUtil statechartUtil = StatechartUtil.INSTANCE - protected final extension ActionUtil actionUtil = ActionUtil.INSTANCE - protected final extension ExpressionUtil expressionUtil = ExpressionUtil.INSTANCE +// protected final extension ActionUtil actionUtil = ActionUtil.INSTANCE +// protected final extension ExpressionUtil expressionUtil = ExpressionUtil.INSTANCE protected final extension InterfaceModelFactory interfaceModelFactory = InterfaceModelFactory.eINSTANCE protected final extension CompositeModelFactory compositeModelFactory = CompositeModelFactory.eINSTANCE @@ -39,6 +38,7 @@ abstract class AbstractTransformer { protected final extension ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE protected final ScxmlGammaExpressionLanguageParser expressionLanguageParser = new ScxmlGammaExpressionLanguageParser() + protected final ScxmlGammaExpressionLanguageLinker expressionLanguageLinker = new ScxmlGammaExpressionLanguageLinker() protected final ExpressionTypeDeterminator2 expressionTypeDeterminator = ExpressionTypeDeterminator2.INSTANCE protected final Logger logger = Logger.getLogger("GammaLogger") diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend index 68ac68fe6..d9501efca 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ActionTransformer.xtend @@ -15,18 +15,23 @@ import ac.soton.scxml.ScxmlIfType import ac.soton.scxml.ScxmlInvokeType import ac.soton.scxml.ScxmlOnentryType import ac.soton.scxml.ScxmlOnexitType +import ac.soton.scxml.ScxmlParamType import ac.soton.scxml.ScxmlRaiseType +import ac.soton.scxml.ScxmlSendType +import ac.soton.scxml.ScxmlStateType import hu.bme.mit.gamma.action.model.Action +import hu.bme.mit.gamma.expression.model.Expression import hu.bme.mit.gamma.expression.model.VariableDeclaration -import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent +import hu.bme.mit.gamma.statechart.composite.ComponentInstance import hu.bme.mit.gamma.statechart.interface_.Interface import hu.bme.mit.gamma.statechart.interface_.Port import hu.bme.mit.gamma.statechart.interface_.RealizationMode +import hu.bme.mit.gamma.statechart.phase.History +import java.util.function.Function import java.util.logging.Level import org.eclipse.emf.ecore.EObject import static ac.soton.scxml.ScxmlModelDerivedFeatures.* -import ac.soton.scxml.ScxmlSendType class ActionTransformer extends AtomicElementTransformer { @@ -74,12 +79,15 @@ class ActionTransformer extends AtomicElementTransformer { val expr = scxmlAssign.expr if (expr !== null) { - val expression = expressionLanguageParser.parse(expr, traceability.variables) - val gammaAssign = actionUtil.createAssignment(variable as VariableDeclaration, expression) + val expression = expressionLanguageParser.preprocessAndParse( + expr, + expressionLanguageLinker.getLinker(traceability) + ) + val gammaAssign = createAssignment(variable as VariableDeclaration, expression) return gammaAssign } - // TODO Assignment by child content if expr is not present + // TODO Assignment by element's child content if expr is not present. val gammaAssign = createEmptyStatement return gammaAssign @@ -117,7 +125,7 @@ class ActionTransformer extends AtomicElementTransformer { } } - val eventName = tokens.last + val eventName = tokens.lastOrNull // If a port is specified, the event will be an out event on an interface // realized in provided mode by the port receiving the event. @@ -129,8 +137,6 @@ class ActionTransformer extends AtomicElementTransformer { getOrTransformOutEvent(gammaInterface, eventName) } - // Event parameters are currently not supported. - // TODO Support payload val gammaRaise = createRaiseEventAction(gammaPort, gammaEvent, newArrayList) return gammaRaise } @@ -138,7 +144,7 @@ class ActionTransformer extends AtomicElementTransformer { // TODO actions // TODO Is traceability entry needed? def dispatch Action transformAction(ScxmlSendType scxmlSend) { - logger.log(Level.INFO, "Transforming element (" + scxmlSend + ")") + logger.info("Transforming element (" + scxmlSend + ")") // TODO Check nulls / empty substrings val eventString = scxmlSend.event @@ -165,12 +171,62 @@ class ActionTransformer extends AtomicElementTransformer { gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) } - val eventName = tokens.last + val eventName = tokens.lastOrNull val gammaEvent = getOrTransformOutEvent(gammaInterface, eventName) - // Event parameters are currently not supported. - // TODO Support payload - val gammaRaise = createRaiseEventAction(gammaPort, gammaEvent, newArrayList) + // Event elements + // TODO Refactor, extract param and argument transformer method + // TODO Named parameter support + // In the Gamma event, the order of the parameters and arguments matters, they are not named. + // Currently, every event parameter of the same event has to be specified, in exact order. + val gammaArgumentNames = newArrayList + val gammaArgumentExpressions = newArrayList + val arguments = scxmlSend.getContentsOfType(ScxmlParamType) + for (argument : arguments) { + val argName = argument.name + val argExpr = argument.expr + + if (argExpr !== null) { + val argExpression = expressionLanguageParser.preprocessAndParse( + argExpr, + expressionLanguageLinker.getLinker(traceability) + ) + gammaArgumentNames += argName + gammaArgumentExpressions += argExpression + + val argType = expressionTypeDeterminator.getType(argExpression) + + // TODO Traceability; event+param -> event+param + // existsParameter(event, param) + // getOrCreateParameter(event, param): creates if not exists, then returns + if (!gammaEvent.parameterDeclarations.exists[it.name == argName]) { + val gammaEventParameterDeclaration = argType.createParameterDeclaration(argName) + gammaEvent.parameterDeclarations += gammaEventParameterDeclaration + + // TODO Refactor into getOrCreate event parameter method + if (!traceability.containsEventParameter(argName)) { + traceability.putEventParameter(argName, gammaEventParameterDeclaration) + } + } + } + } + + // TODO Reorder event arguments according to parameter names in event + // TODO Mix named and indexed parameter passing + // TODO Name -> Find argument by name + // No name -> get index of element in parent's children list + // Parametric(parameterized)Element-ekre meg lehet csinálni + val orderedGammaArguments = newArrayList + for (eventParameter : gammaEvent.parameterDeclarations) { + val index = gammaArgumentNames.indexOf(eventParameter.name) + /*if (index < 0) { + val index = ecoreUtil.getIndex(0) + }*/ + val argumentExpression = gammaArgumentExpressions.get(index) + orderedGammaArguments += argumentExpression + } + + val gammaRaise = createRaiseEventAction(gammaPort, gammaEvent, orderedGammaArguments) return gammaRaise } @@ -180,7 +236,10 @@ class ActionTransformer extends AtomicElementTransformer { val gammaIf = createIfStatement val cond = scxmlIf.cond if (!cond.nullOrEmpty) { - val condExpression = expressionLanguageParser.parse(cond, traceability.variables) + val condExpression = expressionLanguageParser.preprocessAndParse( + cond, + expressionLanguageLinker.getLinker(traceability) + ) val thenStatements = getIfThenActions(scxmlIf); val gammaThenStatements = thenStatements.transformBlock @@ -198,29 +257,68 @@ class ActionTransformer extends AtomicElementTransformer { def dispatch Action transformAction(ScxmlInvokeType scxmlInvoke) { logger.log(Level.INFO, "Transforming element (" + scxmlInvoke + ")") - // TODO invoked statechart type transformation should be ready at this point, - // or be done lazily by the get call. Anyway, ActionTransformer is + // TODO invoked statechart type transformation should already be done at this point, + // or be done lazily by the get call. Either way, ActionTransformer is // not responsible for invoking contained statechart type transformation. - val invokedTypeURI = scxmlInvoke.type + val invokedTypeSourceURI = scxmlInvoke.src // TODO get invoked type traceability // TODO check component type - val invokedTypeTraceability = traceability.compositeTraceability.getTraceability(invokedTypeURI) - val gammaSubcomponentType = invokedTypeTraceability.adapter as AsynchronousComponent + val invokedTypeTraceability = traceability.compositeTraceability.getTraceability(invokedTypeSourceURI) + val gammaSubcomponentType = invokedTypeTraceability.statechart /*adapter as AsynchronousComponent*/ - val gammaSubcomponent = gammaSubcomponentType.instantiateAsynchronousComponent + val gammaSubcomponent = gammaSubcomponentType.instantiateComponent gammaSubcomponent.name = scxmlInvoke.id - val missionPhaseAnnotation = createMissionPhaseStateAnnotation - missionPhaseAnnotation.component = gammaSubcomponent + val missionPhaseStateAnnotation = createMissionPhaseStateAnnotation + + val invokeParameters = scxmlInvoke.param + + // TODO Pass arguments by subcomponent parameter names + val arguments = invokeParameters.filter[it.name == "_argument"] + /* arguments.forEach [ it | + * val gammaArgument = it.expr.transformArgument + * gammaSubcomponent.arguments += gammaArgument + * ] */ + val parameters = gammaSubcomponentType.parameterDeclarations + for (parameter : parameters) { + val argument = arguments.findFirst[it.name == parameter.name] + val gammaArgument = argument.expr.transformArgument + gammaSubcomponent.arguments += gammaArgument + } + + missionPhaseStateAnnotation.component = gammaSubcomponent + + val portBindings = invokeParameters.filter[it.name == "_port_binding"] + portBindings.forEach [ it | + val gammaPortBinding = transformPortBinding(gammaSubcomponent, it.expr) + missionPhaseStateAnnotation.portBindings += gammaPortBinding + ] + + val variableBindings = invokeParameters.filter[it.name == "_variable_binding"] + variableBindings.forEach [ it | + val gammaVariableBinding = transformVariableBinding(gammaSubcomponent, it.expr) + missionPhaseStateAnnotation.variableBindings += gammaVariableBinding + ] + + val history = invokeParameters.findFirst[it.name == "_history"] + if (history !== null) { + val gammaHistory = switch history.expr { + case "shallow": History.SHALLOW_HISTORY + case "deep": History.DEEP_HISTORY + case "no", + default: History.NO_HISTORY + } + missionPhaseStateAnnotation.history = gammaHistory + } - // TODO Side effect: find state to put the phase annotation onto - // return missionPhaseAnnotation // TODO State, transition // Put transformed invoke to stable target state - // val rootState = ecoreUtil.getContainerOfType(scxmlInvoke, ScxmlScxmlType); - // val gammaRootState = traceability.getTraceability(rootState) // TODO Assignment by child content if expr is not present + val parentState = scxmlInvoke.getContainerOfType(ScxmlStateType) + val gammaState = traceability.getState(parentState) + gammaState.annotations += missionPhaseStateAnnotation + val gammaEmptyAction = createEmptyStatement return gammaEmptyAction } @@ -231,9 +329,104 @@ class ActionTransformer extends AtomicElementTransformer { } val gammaActions = actions.map[it.transformAction].toList - val gammaBlock = actionUtil.wrap(gammaActions) + val gammaBlock = gammaActions.wrap return gammaBlock } + // TODO Connect statechart arguments with statechart parameters by name + private def Expression transformArgument(String argumentSpec) { + val argumentString = argumentSpec.trim + val tokens = argumentString.split("\\.|\\s*\\=\\s*") + if (tokens.size != 2) { + throw new IllegalArgumentException( + "Argument descriptor " + argumentString + " does not contain exactly 2 dot separated tokens." + ) + } + // TODO Trim tokens + // TODO Use parameter name to determine the order of statechart arguments + val targetParameterName = tokens.get(0) + val scxmlArgumentExpression = tokens.get(1) + + // TODO Expression parsing + val gammaArgumentExpression = expressionLanguageParser.preprocessAndParse( + scxmlArgumentExpression, + expressionLanguageLinker.getLinker(traceability) + ) + + return gammaArgumentExpression + } + + // TODO Reuse code - port/variable bindings + // TODO? Pattern, Matcher, regexes etc. + private def transformPortBinding(ComponentInstance instance, String portBindingSpec) { + val bindingString = portBindingSpec.trim + val tokens = bindingString.split("\\.|\\s*\\-\\s*") + if (tokens.size != 3) { + throw new IllegalArgumentException( + "Binding descriptor " + bindingString + " does not contain exactly 3 dot separated tokens." + ) + } + // TODO Trim tokens + val sourcePortName = tokens.get(0) + val targetInstanceName = tokens.get(1) + val targetPortName = tokens.get(2) + + // TODO Throw exception if port does not exist or ambiguous + val gammaSourcePort = traceability.getPort(sourcePortName) + val gammaInstancePortReference = createInstancePortReference(instance, targetInstanceName, targetPortName) + + val gammaPortBinding = createPortBinding(gammaSourcePort, gammaInstancePortReference) + return gammaPortBinding + } + + private def createInstancePortReference(ComponentInstance instance, String instanceName, String scxmlPortName) { + // val instance = traceability.compositeTraceability.getComponentInstance(instanceName) + // TODO Make it more performant to get statechart traceability + // by instance invokeId or source URI. + val statechartTraceability = traceability.compositeTraceability.getTraceabilityById(instanceName) + val port = statechartTraceability.getPort(scxmlPortName) + + val instancePortReference = createInstancePortReference(instance, port) + return instancePortReference + } + + private def transformVariableBinding(ComponentInstance instance, String variableBindingSpec) { + val bindingString = variableBindingSpec.trim + val tokens = bindingString.split("\\.|\\s*\\-\\s*") + if (tokens.size != 3) { + throw new IllegalArgumentException( + "Binding descriptor " + bindingString + " does not contain exactly 3 dot separated tokens." + ) + } + + val sourceVariableName = tokens.get(0) + val targetInstanceName = tokens.get(1) + val targetVariableName = tokens.get(2) + + // TODO Throw exception if port does not exist or ambiguous + val gammaSourceVariable = traceability.getVariable(sourceVariableName) + val gammaInstanceVariableReference = createInstanceVariableReference(instance, targetInstanceName, + targetVariableName) + + val gammaVariableBinding = createVariableBinding + gammaVariableBinding.instanceVariableReference = gammaInstanceVariableReference + gammaVariableBinding.statechartVariable = gammaSourceVariable + return gammaVariableBinding + } + + private def createInstanceVariableReference(ComponentInstance instance, String instanceName, + String scxmlVariableName) { + // val instance = traceability.compositeTraceability.getComponentInstance(instanceName) + // TODO Make it more performant to get statechart traceability + // by instance invokeId or source URI. + val statechartTraceability = traceability.compositeTraceability.getTraceabilityById(instanceName) + val variable = statechartTraceability.getVariable(scxmlVariableName) + + val instanceVariableReference = createInstanceVariableReference + instanceVariableReference.instance = instance + instanceVariableReference.variable = variable + return instanceVariableReference + } + } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend index 50e835307..2be9e9f9c 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/AtomicElementTransformer.xtend @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project + * Copyright (c) 2023-2025 Contributors to the Gamma project * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -11,10 +11,10 @@ package hu.bme.mit.gamma.scxml.transformation abstract class AtomicElementTransformer extends AbstractTransformer { - + protected final StatechartTraceability traceability - + new(StatechartTraceability traceability) { this.traceability = traceability } -} \ No newline at end of file +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend index d15b69cf9..54e898a30 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeElementTransformer.xtend @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project + * Copyright (c) 2023-2025 Contributors to the Gamma project * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend index 4fd7da972..d530b3653 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/CompositeTraceability.xtend @@ -1,11 +1,11 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project - * + * Copyright (c) 2023-2025 Contributors to the Gamma project + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation @@ -13,6 +13,7 @@ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlInvokeType import ac.soton.scxml.ScxmlScxmlType import hu.bme.mit.gamma.expression.model.ConstantDeclaration +import hu.bme.mit.gamma.expression.model.ParameterDeclaration import hu.bme.mit.gamma.statechart.composite.AsynchronousComponentInstance import hu.bme.mit.gamma.statechart.interface_.Component import hu.bme.mit.gamma.statechart.interface_.Event @@ -45,6 +46,8 @@ class CompositeTraceability { protected final Map, Event> internalEvents = newHashMap protected final Map, Event> inEvents = newHashMap protected final Map, Event> outEvents = newHashMap + protected final Map allEvents = newHashMap + protected final Map allEventParameters = newHashMap // - Asynchronous Component new(String rootFileURI) { @@ -61,7 +64,9 @@ class CompositeTraceability { queueCapacity, internalEvents, inEvents, - outEvents + outEvents, + allEvents, + allEventParameters ) } @@ -171,6 +176,7 @@ class CompositeTraceability { } // + def getInEvents() { return inEvents } @@ -188,23 +194,28 @@ class CompositeTraceability { } // + def getConstantDeclarations() { return List.of(queueCapacity) } def getInterfaces() { val statechartTraceabilities = statecharts.values - return (interfaces.values + statechartTraceabilities.map[it.defaultInterface] + statechartTraceabilities.map [ - it.defaultInterfacePorts.keySet - ].flatten + return ( + interfaces.values + + statechartTraceabilities.map[it.defaultInterface] + + statechartTraceabilities.map[it.defaultInterfacePorts.keySet].flatten ).toSet } def getComponents() { val statechartTraceabilities = statecharts.values - return (instances.values.map[it.getType] + /* TODO Serialize async adapters */ - /* statechartTraceabilities.map[it.getAdapter] + */ - statechartTraceabilities.map[it.getStatechart] + return ( + instances.values.map[it.getType] + + /* TODO Serialize async adapters */ + /* statechartTraceabilities.map[it.getAdapter] + */ + statechartTraceabilities.map[it.getStatechart] ).toSet } + } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend index e2720d480..91e0a55ea 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/DataTransformer.xtend @@ -11,6 +11,7 @@ package hu.bme.mit.gamma.scxml.transformation import ac.soton.scxml.ScxmlDataType +import hu.bme.mit.gamma.expression.model.ParameterDeclaration import hu.bme.mit.gamma.expression.model.VariableDeclaration import java.util.logging.Level @@ -19,8 +20,24 @@ class DataTransformer extends AtomicElementTransformer { new(StatechartTraceability traceability) { super(traceability) } + + // Note: the type of the parameter declaration is inferred from the provided expr of the element. + def ParameterDeclaration transformParameter(ScxmlDataType scxmlData) { + logger.log(Level.INFO, "Transforming element (" + scxmlData + ")") + + val id = scxmlData.id + val expr = scxmlData.expr + val expression = expressionLanguageParser.parse(expr, traceability.variables) + val type = expressionTypeDeterminator.getType(expression) + + val gammaDeclaration = createParameterDeclaration(type, id); + + traceability.put(scxmlData, gammaDeclaration) + + return gammaDeclaration + } - def VariableDeclaration transform(ScxmlDataType scxmlData) { + def VariableDeclaration transformVariable(ScxmlDataType scxmlData) { logger.log(Level.INFO, "Transforming element (" + scxmlData + ")") val id = scxmlData.id @@ -28,7 +45,7 @@ class DataTransformer extends AtomicElementTransformer { val expression = expressionLanguageParser.parse(expr, traceability.variables) val type = expressionTypeDeterminator.getType(expression) - val gammaDeclaration = expressionUtil.createVariableDeclaration(type, id, expression); + val gammaDeclaration = createVariableDeclaration(type, id, expression); traceability.put(scxmlData, gammaDeclaration) diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend index f712b8503..8c418ff9e 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/Namings.xtend @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project + * Copyright (c) 2023-2025 Contributors to the Gamma project * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -17,35 +17,34 @@ import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType class Namings { - - // TODO check default names differ from user defined interface and port names - // at the end of the transformation + + // TODO check default names differ from user defined interface and port names at the end of the transformation def static String getDefaultPortName(String instanceName) '''«instanceName»_DefaultPort''' def static String getDefaultInterfaceName(String instanceName) '''«instanceName»_DefaultInterface''' def static String getDefaultInterfacePortName(String scxmlInterfaceName) '''«scxmlInterfaceName»_DefaultPort''' def static String getInterfaceName(String scxmlInterfaceName) '''«scxmlInterfaceName»''' def static String getPortName(String scxmlPortName) '''«scxmlPortName»''' - + def static String getInternalEventName(String scxmlEventName) '''«scxmlEventName»''' def static String getInEventName(String scxmlEventName) '''«scxmlEventName»''' def static String getOutEventName(String scxmlEventName) '''«scxmlEventName»''' - + def static String getAdapterName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»Adapter''' def static String getInternalEventQueueName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»InternalEventQueue''' def static String getExternalEventQueueName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»ExternalEventQueue''' - + def static String getInterfacePackageName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name.toLowerCase»_interfaces''' def static String getCompositeStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' def static String getStatechartName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»''' def static String getRegionName(String scxmlElementName) '''«scxmlElementName»Region''' - + def static String getParallelName(ScxmlParallelType scxmlParallel) '''«scxmlParallel.id»''' def static String getStateName(ScxmlStateType scxmlState) '''«scxmlState.id»''' def static String getFinalName(ScxmlFinalType scxmlFinal) '''«scxmlFinal.id»''' - + def static String getInitialName(ScxmlStateType scxmlParentState) '''«scxmlParentState.id»Initial''' def static String getInitialName(ScxmlScxmlType scxmlRoot) '''«scxmlRoot.name»Initial''' def static String getShallowHistoryName(ScxmlHistoryType scxmlHistoryState) '''«scxmlHistoryState.id»ShallowHistory''' def static String getDeepHistoryName(ScxmlHistoryType scxmlHistoryState) '''«scxmlHistoryState.id»DeepHistory''' - -} \ No newline at end of file + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend index d42bdd4ab..41dbd8d7a 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaCompositeTransformer.xtend @@ -44,7 +44,7 @@ class ScxmlToGammaCompositeTransformer extends CompositeElementTransformer { val queueCapacityDeclaration = createConstantDeclaration queueCapacityDeclaration.name = "QUEUE_CAPACITY" - val capacity = expressionUtil.toIntegerLiteral(4) + val capacity = toIntegerLiteral(4) queueCapacityDeclaration.expression = capacity queueCapacityDeclaration.type = createIntegerTypeDefinition diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend index b73024afc..c4159bc54 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/ScxmlToGammaStatechartTransformer.xtend @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project + * Copyright (c) 2023-2025 Contributors to the Gamma project * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -21,6 +21,7 @@ import ac.soton.scxml.ScxmlScxmlType import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType import ac.soton.scxml.TransitionTypeDatatype +import hu.bme.mit.gamma.expression.model.Expression import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter import hu.bme.mit.gamma.statechart.composite.AsynchronousComponent import hu.bme.mit.gamma.statechart.composite.ControlFunction @@ -38,6 +39,7 @@ import hu.bme.mit.gamma.statechart.statechart.Transition import hu.bme.mit.gamma.statechart.statechart.TransitionPriority import java.math.BigInteger import java.util.List +import java.util.function.Function import java.util.logging.Level import org.eclipse.emf.common.util.URI @@ -144,7 +146,7 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { for (invoke : invokes) { val statechartTraceability = compositeTraceability.getTraceability(invoke.src) - // TODO Extend to deeper composition hierarchy levels later + // TODO Extend to deeper composition hierarchy levels, not just one-level adapter children val gammaSubcomponentType = statechartTraceability.adapter as AsynchronousComponent val gammaSubcomponent = gammaSubcomponentType.instantiateAsynchronousComponent @@ -188,13 +190,13 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { } } } - + // TODO Merge methods logically transformStatechartInnerElements return gammaComposite } - + // TODO Merge this statechart transformation with 'composite' transformation method // Transformation of the SCXML root element and its contents recursively. // Invoked types are assumed to be already transformed by this point. @@ -207,7 +209,7 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { // TODO Check settings! gammaStatechart.schedulingOrder = SchedulingOrder.BOTTOM_UP gammaStatechart.orthogonalRegionSchedulingOrder = OrthogonalRegionSchedulingOrder.SEQUENTIAL - gammaStatechart.transitionPriority = TransitionPriority.ORDER_BASED; + gammaStatechart.transitionPriority = TransitionPriority.ORDER_BASED gammaStatechart.guardEvaluation = GuardEvaluation.BEGINNING_OF_STEP val datamodels = scxmlRoot.datamodel @@ -217,18 +219,30 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { val dataElements = getDataElements(datamodel) // TODO Move string literal parts of names to Namings - val portDataElements = dataElements.filter [ it | - it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("pro_port_") || - it.id.startsWith("req_port_") + val portDataElements = dataElements.filter[ + it.eContainer.eContainer instanceof ScxmlScxmlType && + (it.id.startsWith("pro_port_") || it.id.startsWith("req_port_")) ] for (portData : portDataElements) { val gammaPort = portData.getOrCreatePort gammaStatechart.ports += gammaPort } - val variableDataElements = dataElements.filter[it|!portDataElements.contains(it)] + // TODO Transform constants, prefix: "const_" + // TODO Extract to method + val parameterDataElements = dataElements.filter[ + it.eContainer.eContainer instanceof ScxmlScxmlType && it.id.startsWith("param_") + ] + for (parameterData : parameterDataElements) { + val gammaParameterDeclaration = dataTransformer.transformParameter(parameterData) + gammaStatechart.parameterDeclarations += gammaParameterDeclaration + } + + val variableDataElements = dataElements.filter[ + !portDataElements.contains(it) && !parameterDataElements.contains(it) + ] for (variableData : variableDataElements) { - val gammaVariableDeclaration = dataTransformer.transform(variableData) + val gammaVariableDeclaration = dataTransformer.transformVariable(variableData) gammaStatechart.variableDeclarations += gammaVariableDeclaration } } @@ -435,7 +449,9 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { } } - adapter.messageQueues += internalEventQueue + if (!internalEventQueue.eventPassings.empty) { + adapter.messageQueues += internalEventQueue + } // Create external event queue val externalEventQueue = createMessageQueue @@ -458,8 +474,10 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { externalEventQueue.eventPassings += eventPassing } } - - adapter.messageQueues.add(externalEventQueue) + + if (!externalEventQueue.eventPassings.empty) { + adapter.messageQueues += externalEventQueue + } return adapter } @@ -525,6 +543,8 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { val gammaState = createState => [ it.name = getStateName(scxmlState) ] + + traceability.put(scxmlState, gammaState) if (isCompoundState(scxmlState)) { val region = createRegion => [ @@ -584,9 +604,9 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { val onentryActions = scxmlState.onentry for (onentryAction : onentryActions) { if (onentryAction !== null) { - val gammaOnEntryActions = onentryAction.transformOnentry - if (gammaOnEntryActions !== null) { - gammaState.entryActions += gammaOnEntryActions + val gammaOnEntryAction = onentryAction.transformOnentry + if (gammaOnEntryAction !== null) { + gammaState.entryActions += gammaOnEntryAction } } } @@ -594,14 +614,18 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { val onexitActions = scxmlState.onexit for (onexitAction : onexitActions) { if (onexitAction !== null) { - val gammaOnExitActions = onexitAction.transformOnexit - if (gammaOnExitActions !== null) { - gammaState.exitActions += gammaOnExitActions + val gammaOnExitAction = onexitAction.transformOnexit + if (gammaOnExitAction !== null) { + gammaState.exitActions += gammaOnExitAction } } } - - traceability.put(scxmlState, gammaState) + + // Transform invoke actions + val invokeActions = scxmlState.invoke + for (invokeAction : invokeActions) { + invokeAction?.transformAction + } return gammaState } @@ -692,7 +716,10 @@ class ScxmlToGammaStatechartTransformer extends AtomicElementTransformer { // Transform guard if present val guardStr = transition.cond if (!guardStr.nullOrEmpty) { - val gammaGuardExpression = expressionLanguageParser.parse(guardStr, traceability.variables) + val gammaGuardExpression = expressionLanguageParser.preprocessAndParse( + guardStr, + expressionLanguageLinker.getLinker(traceability) + ) gammaTransition.guard = gammaGuardExpression } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend index fa1fb5679..68a394b51 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/StatechartTraceability.xtend @@ -1,11 +1,11 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project - * + * Copyright (c) 2023-2025 Contributors to the Gamma project + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation @@ -20,6 +20,7 @@ import ac.soton.scxml.ScxmlStateType import ac.soton.scxml.ScxmlTransitionType import hu.bme.mit.gamma.expression.model.ConstantDeclaration import hu.bme.mit.gamma.expression.model.Declaration +import hu.bme.mit.gamma.expression.model.ParameterDeclaration import hu.bme.mit.gamma.expression.model.VariableDeclaration import hu.bme.mit.gamma.statechart.composite.AsynchronousAdapter import hu.bme.mit.gamma.statechart.interface_.Event @@ -61,8 +62,8 @@ class StatechartTraceability { protected final Set initialTransitions = newHashSet protected final Map dataElements = newHashMap - - // Works only if variables are globally unique and have a global scope + protected final Map parameters = newHashMap + // The variables map works only if variables are globally unique and have a global scope protected final Map variables = newHashMap // Internal mappings (internal to the statechart) @@ -76,6 +77,8 @@ class StatechartTraceability { protected final Map, Event> internalEvents protected final Map, Event> inEvents protected final Map, Event> outEvents + protected final Map allEvents + protected final Map allEventParameters protected final extension GammaEcoreUtil ecoreUtil = GammaEcoreUtil.INSTANCE @@ -87,7 +90,9 @@ class StatechartTraceability { ConstantDeclaration queueCapacity, Map, Event> internalEvents, Map, Event> inEvents, - Map, Event> outEvents + Map, Event> outEvents, + Map allEvents, + Map allEventParameters ) { this.compositeTraceability = compositeTraceability this.fileURI = rootFileURI @@ -96,6 +101,8 @@ class StatechartTraceability { this.internalEvents = internalEvents this.inEvents = inEvents this.outEvents = outEvents + this.allEvents = allEvents + this.allEventParameters = allEventParameters } def getScxmlRoot() { @@ -295,6 +302,22 @@ class StatechartTraceability { return initialTransitions } + // - ParameterDeclaration + def put(ScxmlDataType scxmlData, ParameterDeclaration gammaDeclaration) { + checkNotNull(scxmlData) + checkNotNull(gammaDeclaration) + dataElements += scxmlData -> gammaDeclaration + + put(scxmlData.id, gammaDeclaration) + } + + def getParameter(ScxmlDataType scxmlData) { + checkNotNull(scxmlData) + val gammaDeclaration = dataElements.get(scxmlData) + checkNotNull(gammaDeclaration) + return gammaDeclaration + } + // - VariableDeclaration def put(ScxmlDataType scxmlData, VariableDeclaration gammaDeclaration) { checkNotNull(scxmlData) @@ -311,6 +334,25 @@ class StatechartTraceability { return gammaDeclaration } + // Parameter Declarations by String identifier + private def put(String scxmlParameterName, ParameterDeclaration gammaDeclaration) { + checkNotNull(scxmlParameterName) + checkNotNull(gammaDeclaration) + parameters += scxmlParameterName -> gammaDeclaration + } + + def containsParameter(String scxmlParameterName) { + checkNotNull(scxmlParameterName) + return parameters.containsKey(scxmlParameterName) + } + + def getParameter(String scxmlParameterName) { + checkNotNull(scxmlParameterName) + val gammaDeclaration = parameters.get(scxmlParameterName) + checkNotNull(gammaDeclaration) + return gammaDeclaration + } + // Variable Declarations by String identifier private def put(String scxmlVariableName, VariableDeclaration gammaDeclaration) { checkNotNull(scxmlVariableName) @@ -318,6 +360,11 @@ class StatechartTraceability { variables += scxmlVariableName -> gammaDeclaration } + def containsVariable(String scxmlVariableName) { + checkNotNull(scxmlVariableName) + return variables.containsKey(scxmlVariableName) + } + def getVariable(String scxmlVariableName) { checkNotNull(scxmlVariableName) val gammaDeclaration = variables.get(scxmlVariableName) @@ -422,6 +469,8 @@ class StatechartTraceability { val interface = interfaceEvent.key val eventName = interfaceEvent.value internalEvents += (interface -> eventName) -> gammaEvent + + putEvent(eventName, gammaEvent) } def getInternalEvent(Pair interfaceEvent) { @@ -457,6 +506,8 @@ class StatechartTraceability { val interface = interfaceEvent.key val eventName = interfaceEvent.value inEvents += (interface -> eventName) -> gammaEvent + + putEvent(eventName, gammaEvent) } def getInEvent(Pair interfaceEvent) { @@ -492,6 +543,8 @@ class StatechartTraceability { val interface = interfaceEvent.key val eventName = interfaceEvent.value outEvents += (interface -> eventName) -> gammaEvent + + putEvent(eventName, gammaEvent) } def getOutEvent(Pair interfaceEvent) { @@ -517,4 +570,42 @@ class StatechartTraceability { return outEvents.containsKey(interface -> eventName) } + // Events by string identifier + def putEvent(String scxmlEventName, Event gammaEvent) { + checkNotNull(scxmlEventName) + checkNotNull(gammaEvent) + allEvents += scxmlEventName -> gammaEvent + } + + def getEvent(String scxmlEventName) { + checkNotNull(scxmlEventName) + val gammaEvent = allEvents.get(scxmlEventName) + checkNotNull(gammaEvent) + return gammaEvent + } + + def containsEvent(String scxmlEventName) { + checkNotNull(scxmlEventName) + return allEvents.containsKey(scxmlEventName) + } + + // Event parameters by string identifier + def putEventParameter(String scxmlEventParameterName, ParameterDeclaration gammaEventParameter) { + checkNotNull(scxmlEventParameterName) + checkNotNull(gammaEventParameter) + allEventParameters += scxmlEventParameterName -> gammaEventParameter + } + + def getEventParameter(String scxmlEventParameterName) { + checkNotNull(scxmlEventParameterName) + val gammaEventParameter = allEventParameters.get(scxmlEventParameterName) + checkNotNull(gammaEventParameter) + return gammaEventParameter + } + + def containsEventParameter(String scxmlEventParameterName) { + checkNotNull(scxmlEventParameterName) + return allEventParameters.containsKey(scxmlEventParameterName) + } + } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend index 87e52a3c7..264cc24ed 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/TriggerTransformer.xtend @@ -1,11 +1,11 @@ /******************************************************************************** * Copyright (c) 2023 Contributors to the Gamma project - * + * * 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 - * + * * SPDX-License-Identifier: EPL-1.0 ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation @@ -15,70 +15,68 @@ import hu.bme.mit.gamma.statechart.interface_.Port import hu.bme.mit.gamma.statechart.interface_.RealizationMode class TriggerTransformer extends AtomicElementTransformer { - + protected final extension PortTransformer portTransformer protected final extension InterfaceTransformer interfaceTransformer protected final extension EventTransformer eventTransformer - + new(StatechartTraceability traceability) { super(traceability) - + this.portTransformer = new PortTransformer(traceability) this.interfaceTransformer = new InterfaceTransformer(traceability) this.eventTransformer = new EventTransformer(traceability) } - + // TODO sanitize and check eventString def transformTrigger(String eventString) { val tokens = eventString.split("\\.") if (tokens.size < 1 || tokens.size > 3) { - throw new IllegalArgumentException("Event descriptor " + eventString - + " does not contain exactly 1, 2 or 3 dot separated tokens." + throw new IllegalArgumentException( + "Event descriptor " + eventString + " does not contain exactly 1, 2 or 3 dot separated tokens." ) } - + var gammaInterface = null as Interface var gammaPort = null as Port var isDefault = false - + if (tokens.size == 1) { isDefault = true gammaInterface = getOrCreateDefaultInterface() gammaPort = getOrCreateDefaultPort() - } - else { + } else { val interfaceName = tokens.get(tokens.size - 2) gammaInterface = getOrTransformInterfaceByName(interfaceName) - + if (tokens.size >= 3) { val portName = tokens.head gammaPort = getOrTransformPortByName(gammaInterface, portName, RealizationMode.REQUIRED) - } - else { + } else { isDefault = true gammaPort = getOrTransformDefaultInterfacePort(gammaInterface) } } - - val eventName = tokens.last - + + val eventName = tokens.lastOrNull + // If a port is specified, the event will be an out event on an interface // realized in required mode by the port receiving the event. // In the case of default interfaces and ports, realization mode is provided // and trigger events are internal. val gammaEvent = if (isDefault) { - getOrTransformInternalEvent(gammaInterface, eventName) - } else { - getOrTransformOutEvent(gammaInterface, eventName) - } - + getOrTransformInternalEvent(gammaInterface, eventName) + } else { + getOrTransformOutEvent(gammaInterface, eventName) + } + val gammaEventReference = createPortEventReference gammaEventReference.port = gammaPort gammaEventReference.event = gammaEvent - + val gammaEventTrigger = createEventTrigger gammaEventTrigger.eventReference = gammaEventReference return gammaEventTrigger } - -} \ No newline at end of file + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageLinker.xtend b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageLinker.xtend new file mode 100644 index 000000000..52be970fc --- /dev/null +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageLinker.xtend @@ -0,0 +1,106 @@ +/******************************************************************************** + * Copyright (c) 2025 Contributors to the Gamma project + * + * 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 + * + * SPDX-License-Identifier: EPL-1.0 + ********************************************************************************/ + +package hu.bme.mit.gamma.scxml.transformation.parse; + +import hu.bme.mit.gamma.expression.model.ExpressionModelFactory +import hu.bme.mit.gamma.scxml.transformation.StatechartTraceability +import hu.bme.mit.gamma.statechart.util.StatechartUtil +import java.util.List +import java.util.function.Function +import org.eclipse.emf.ecore.EObject +import org.eclipse.xtext.nodemodel.ILeafNode + +class ScxmlGammaExpressionLanguageLinker { + + protected final extension StatechartUtil statechartUtil = StatechartUtil.INSTANCE + protected final extension ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE + + def Function getLinker(StatechartTraceability traceability) { + return new Function { + List tokenList = newArrayList + +// TODO Goal: set references +// TODO Resolve with reflective API, EObject, EClass +// Get eStructuralFeature name from CrossReference +// Get eStructuralFeature from EClass +// semanticElement.setEStructuralFeature(object) + +// TODO ILeafNode parameter +// Get type (gamma type), id (text, scxml id) +// scxml elements with this id +// filter gamma type matches +// OR: filter by type, then filter by id +// 0 elements -> IllegalArgumentException, user scxml model error +// 1 element -> OK, return EObject +// 2+ element -> random selection from options: throw exception +// or post prcessing step after full model transformation: resolve scoping globally +// heuristic: getLevel in tree -> select safer options: global"er" reference +// or properly implement scoping (direct reference expressions) + override apply(ILeafNode node) { + val id = node.text + val grammarElement = node.getGrammarElement + val reference = node.getSemanticElement + + tokenList += id + + // statechart parameter reference + if (traceability.containsParameter(id)) { + val parameterDeclaration = traceability.getParameter(id) + return statechartUtil.createReferenceExpression(parameterDeclaration) + } + + // variable reference + if (traceability.containsVariable(id)) { + val variableDeclaration = traceability.getVariable(id) + return statechartUtil.createReferenceExpression(variableDeclaration) + } + + // port + if (traceability.containsPort(id)) { + val port = traceability.getPort(id) + return port + } + + // event + if (traceability.containsEvent(id)) { + val event = traceability.getEvent(id) + return event + } + + // event parameter + if (traceability.containsEventParameter(id)) { + val eventParameter = traceability.getEventParameter(id) + return eventParameter + } + + /* TODO? Alternative resolution method: get port event parameter reference by token list + * + * if (traceability.containsPort(tokenList.get(0))) { + * val port = traceability.getPort(tokenList.get(0)) + * val interface = port.interfaceRealization.interface + * if (interface !== null && tokenList.length >= 2) { + * val event = interface.events.findFirst[it.event.name == tokenList.get(1)].event + * if (event !== null && tokenList.length >= 3) { + * val parameter = event.parameterDeclarations.findFirst[it.name == tokenList.get(2)] + * if (parameter !== null) { + * return createEventParameterReference(port, parameter) + * } + * } + * } + }*/ + + return null + } + } + } + +} diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java index dd34c1a62..342324862 100644 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java +++ b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaExpressionLanguageParser.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project + * Copyright (c) 2025 Contributors to the Gamma project * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -10,88 +10,137 @@ ********************************************************************************/ package hu.bme.mit.gamma.scxml.transformation.parse; +import static java.util.Map.entry; + import java.io.StringReader; import java.util.Map; -import java.util.NoSuchElementException; +import java.util.function.Function; +import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.CrossReference; -import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.nodemodel.ICompositeNode; +import org.eclipse.xtext.nodemodel.ILeafNode; import org.eclipse.xtext.parser.IParseResult; -import com.google.inject.Injector; - -import hu.bme.mit.gamma.expression.language.ExpressionLanguageStandaloneSetup; import hu.bme.mit.gamma.expression.model.DirectReferenceExpression; +import hu.bme.mit.gamma.expression.model.EnumerationLiteralExpression; import hu.bme.mit.gamma.expression.model.Expression; -import hu.bme.mit.gamma.expression.model.ExpressionModelFactory; import hu.bme.mit.gamma.expression.model.OpaqueExpression; -import hu.bme.mit.gamma.expression.model.VariableDeclaration; +import hu.bme.mit.gamma.expression.model.ParameterDeclaration; +import hu.bme.mit.gamma.expression.model.TypeReference; +import hu.bme.mit.gamma.statechart.interface_.Event; +import hu.bme.mit.gamma.statechart.interface_.EventParameterReferenceExpression; +import hu.bme.mit.gamma.statechart.interface_.Port; +import hu.bme.mit.gamma.statechart.language.parser.StatechartExpressionLanguageParserAndLinker; -import static java.util.Map.entry; +public class ScxmlGammaExpressionLanguageParser extends StatechartExpressionLanguageParserAndLinker { -// TODO rename, e.g. Custom... -public class ScxmlGammaExpressionLanguageParser { - - private static final Map preprocessRules = Map.ofEntries( + private static final Map defaultScxmlPreprocessRules = Map.ofEntries( entry("!", "not"), entry("&&", "and"), - entry("||", "or") - ); - - private final ExpressionModelFactory expressionModelFactory = ExpressionModelFactory.eINSTANCE; - - private final Injector injector = new ExpressionLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); - - // Works only if variables in the scope are globally unique and have a global scope - public Expression parse(String expression, Map scope) { - String preprocessedExpression = preprocessExpression(expression); - - ScxmlGammaLanguageParser parser = injector.getInstance(ScxmlGammaLanguageParser.class); - StringReader reader = new StringReader(preprocessedExpression); + entry("||", "or")); + + public Expression preprocessAndParse(String expression, Function scope) { + return super.preprocessAndParse2(expression, scope, defaultScxmlPreprocessRules); + } + + @Override + public Expression parse2(String expression, Function scope) { + String trimmedExpression = javaUtil.deparenthesize(expression); + StringReader reader = new StringReader(trimmedExpression); + IParseResult result = parser.parse(reader); if (result.hasSyntaxErrors()) { - return createOpaqueExpression(preprocessedExpression); + return util.createOpaqueExpression(expression); } try { - for (INode node : result.getRootNode().getLeafNodes()) { - if (node.getGrammarElement() instanceof CrossReference) { - final DirectReferenceExpression refExpr = (DirectReferenceExpression) node.getSemanticElement(); - - VariableDeclaration decl = scope.get(node.getText()); - if (decl != null) { - refExpr.setDeclaration(decl); - } else { - throw new NoSuchElementException(); + String typeReferenceId = null; + + ICompositeNode rootNode = result.getRootNode(); + for (ILeafNode node : rootNode.getLeafNodes()) { + EObject grammarElement = node.getGrammarElement(); + System.out.println("ScxmlGammaExpressionParser: " + node.getText()); + if (grammarElement instanceof CrossReference) { + EObject reference = node.getSemanticElement(); + + String text = node.getText(); + // TODO grammarElement.type.classifier + EObject parsedReference = scope.apply(node); + if (parsedReference == null) { + parsedReference = util.createOpaqueExpression(text); + } + + // TODO + // grammarelement.eContainer().getFeature() // e.g. "port" + // parsedReference.eClass().getEStructuralFeature(featureName); + + EObject container = reference.eContainer(); + + /* + * TODO Save EObject (scope) list, define matchable sequences e.g. + * port.event::param, port.event, port.any, variable, parameter etc. If match, + * then resolve with correct types + * + * TODO Implement scoping, inject scope provider + */ + + /// Direct reference expressions (variable, parameter) + if (reference instanceof DirectReferenceExpression ref) { + if (parsedReference instanceof DirectReferenceExpression ref2) { + ref.setDeclaration(ref2.getDeclaration()); + } + } + /// + + /// Event parameter reference expressions + if (reference instanceof EventParameterReferenceExpression ref) { + if (parsedReference instanceof Port port) { + ref.setPort(port); + } + if (parsedReference instanceof Event event) { + ref.setEvent(event); + } + if (parsedReference instanceof ParameterDeclaration eventParameter) { + ref.setParameter(eventParameter); + } } + /// + + /* TODO Fix commented section if needed + * if (container == null) { // Replace would not work as it is a single element + * return (Expression) parsedReference; } + */ + + /// Unparsable enum literals (e.g., state references) + if (parsedReference instanceof OpaqueExpression) { // I.e., 'parsedReference' was 'null' + if (reference instanceof TypeReference && container instanceof EnumerationLiteralExpression) { + typeReferenceId = text; + continue; // Next node is the literal id + } else if (reference instanceof EnumerationLiteralExpression) { + String enumId = typeReferenceId + "::" + text; + parsedReference = util.createOpaqueExpression(enumId); + + if (container == null) { + // Replace would not work as it is a single element + return (Expression) parsedReference; + } else { + ecoreUtil.replace(parsedReference, reference); + } + } + } + /// + + // TODO Fix commented section if needed + // ecoreUtil.replace(parsedReference, reference); } } - return (Expression) result.getRootASTElement(); - } catch (NoSuchElementException e) { - } - return createOpaqueExpression(expression); - } - - private String preprocessExpression(String expression) { - var preprocessedExpression = preprocess(expression, preprocessRules); - return preprocessedExpression; - } - - private String preprocess(String expression, Map preprocess) { - String preprocessedExpression = expression; - for (String key : preprocess.keySet()) { - String value = preprocess.get(key); - preprocessedExpression = preprocessedExpression.replace(key, value); + return (Expression) result.getRootASTElement(); + } catch (Exception e) { + return util.createOpaqueExpression(expression); } - return preprocessedExpression; - } - - private Expression createOpaqueExpression(String expression) { - OpaqueExpression opaqueExpression = expressionModelFactory.createOpaqueExpression(); - opaqueExpression.setExpression(expression); - return opaqueExpression; } } diff --git a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java b/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java deleted file mode 100644 index 5ca6bc8f8..000000000 --- a/plugins/scxml/hu.bme.mit.gamma.scxml.transformation/src/hu/bme/mit/gamma/scxml/transformation/parse/ScxmlGammaLanguageParser.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Contributors to the Gamma project - * - * 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 - * - * SPDX-License-Identifier: EPL-1.0 - ********************************************************************************/ -package hu.bme.mit.gamma.scxml.transformation.parse; - -import hu.bme.mit.gamma.expression.language.parser.antlr.ExpressionLanguageParser; - -// TODO rename -public class ScxmlGammaLanguageParser extends ExpressionLanguageParser { - - // Set default rule to "Expression" from "ExpressionPackage" - @Override - protected String getDefaultRuleName() { - return "Expression"; - } - -}