From 9184fac05944183f309c737c51e69b799aedffa1 Mon Sep 17 00:00:00 2001 From: Chrissi <christopher@hbsc-werner.de> Date: Sun, 25 Aug 2019 18:34:48 +0200 Subject: [PATCH] =?UTF-8?q?Refactoring=20+=20Erweiterung=20f=C3=BCr=20Einl?= =?UTF-8?q?esen=20von=20EMF=20Modellen=20f=C3=BCr=20RSYNC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model_sync/generator/Generator.scala | 67 ++++++------ .../SModelCombiRefMethodService.scala | 2 - ...elGetterSetterAllPreparationService.scala} | 10 +- ...elGetterSetterAttrPreparationService.scala | 16 +++ ...ationalCompartmentPreparationService.scala | 20 ++++ .../SModelSUMCorePreparationService.scala | 26 ----- .../generator/SModelSUMReadEMFService.scala | 4 +- .../generator/io/SClassWriter.scala | 12 ++- .../generator/io/SModelFSWriter.scala | 9 +- ...sicTypeGetterSetterGeneratingVisitor.scala | 22 ++-- .../sync/GetterSetterGeneratingVisitor.scala | 45 ++++---- .../sync/InstanceCombiGenerator.scala | 9 -- .../sync/SumModelReadingVisitor.scala | 101 ++++++++++++++---- .../generator/sync/SyncEnhancingVisitor.scala | 18 ++-- .../generator/test/ApplicationTest.scala | 4 +- .../generator/ui/SyncUiVisitor.scala | 21 ++-- 16 files changed, 231 insertions(+), 155 deletions(-) rename src/main/scala/org/rosi_project/model_sync/generator/{SModelAllGetterSetterPreparationService.scala => SModelGetterSetterAllPreparationService.scala} (56%) create mode 100644 src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAttrPreparationService.scala create mode 100644 src/main/scala/org/rosi_project/model_sync/generator/SModelRelationalCompartmentPreparationService.scala delete mode 100644 src/main/scala/org/rosi_project/model_sync/generator/SModelSUMCorePreparationService.scala diff --git a/src/main/scala/org/rosi_project/model_sync/generator/Generator.scala b/src/main/scala/org/rosi_project/model_sync/generator/Generator.scala index 9067dc9..1473fa0 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/Generator.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/Generator.scala @@ -32,7 +32,7 @@ class Generator(config: GeneratorConfig) { } //read the ecore models - var ecoreModels: Map[String, ClassAndInstance] = Map.empty + var ecoreModels: Map[String, ClassAndInstance] = Map.empty try { config.sources.foreach(s => { ecoreModels = ecoreModels + (s -> (new EcoreLoader loadEcore s)) @@ -47,52 +47,47 @@ class Generator(config: GeneratorConfig) { sModels = sModels + ((new SModelGenerator convert (ec._2.pkg, ec._1)) -> ec._2) }) - //create the new classes for rsum and rsync - if (config.create == Creation.rolesync) { - sModels.foreach(sm => { + sModels.foreach(sm => { + /*general stuff, that should always be created */ + //create relational compartments (are only write out if not rolesync) + new SModelRelationalCompartmentPreparationService prepareModel (sm._1) + + //create the new classes for rsum and rsync + if (config.create == Creation.rolesync) { //instance generation for rsync if (sm._2.obj != null) { - new SModelSyncInstanceService prepareModel(sm._1, sm._2) + new SModelSyncInstanceService prepareModel (sm._1, sm._2) } - new SModelAllGetterSetterPreparationService prepareModel (sm._1) - new SModelOnlySyncService prepareModel (sm._1) - new SModelSyncUiPreparationService prepareModel (sm._1, config.getModelConfigFromEcore(sm._1.getSourceName)) - }) - } - if (config.create == Creation.rolesum) { - sModels.foreach(sm => { - //create core stuff - new SModelSUMCorePreparationService prepareModel (sm._1) - //remove references - new SModelSUMRemoveRefService prepareModel (sm._1) - //create view and query stuff - new SModelSUMPreparationService prepareModel (sm._1) - }) - } - if (config.create == Creation.rolecomb) { - sModels.foreach(sm => { - //create core stuff - new SModelSUMCorePreparationService prepareModel (sm._1) + //add getter and setter for all methods + new SModelGetterSetterAllPreparationService prepareModel (sm._1) + //create the EMF Ecore reading models + new SModelSUMReadEMFService prepareModel (sm._1, config) //add sync stuff new SModelOnlySyncService prepareModel (sm._1) + //add ui provider stuff + new SModelSyncUiPreparationService prepareModel (sm._1, config.getModelConfigFromEcore(sm._1.getSourceName)) + } else { + //add basic setter and getter + new SModelGetterSetterAttrPreparationService prepareModel (sm._1) + if (config.create == Creation.rolecomb) { + //add sync stuff + new SModelOnlySyncService prepareModel (sm._1) + } //create the EMF Ecore reading models - new SModelSUMReadEMFService prepareModel (sm._1) - + new SModelSUMReadEMFService prepareModel (sm._1, config) //instance generation for combi means rsum if (sm._2.obj != null) { - new SModelCombiInstanceService prepareModel(sm._1, sm._2) - } - else - { - //add ref methods - new SModelCombiRefMethodService prepareModel (sm._1) - //remove references - new SModelSUMRemoveRefService prepareModel (sm._1) + new SModelCombiInstanceService prepareModel (sm._1, sm._2) } + //add ref methods + new SModelCombiRefMethodService prepareModel (sm._1) + //remove references + new SModelSUMRemoveRefService prepareModel (sm._1) //create view and query stuff new SModelSUMPreparationService prepareModel (sm._1) - }) - } + } + + }) // write the model and create the JAR println("... Writing model") diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiRefMethodService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiRefMethodService.scala index 1e1e9d9..e83e649 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiRefMethodService.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiRefMethodService.scala @@ -18,8 +18,6 @@ class SModelCombiRefMethodService { */ def prepareModel(sModel: SModel): Unit = { val refMethodVisitor = new ReferenceMethodCreationVisitor - - //order is important !!!! sModel.accept(refMethodVisitor) } } \ No newline at end of file diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelAllGetterSetterPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAllPreparationService.scala similarity index 56% rename from src/main/scala/org/rosi_project/model_sync/generator/SModelAllGetterSetterPreparationService.scala rename to src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAllPreparationService.scala index cfe8d27..8978200 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/SModelAllGetterSetterPreparationService.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAllPreparationService.scala @@ -3,15 +3,13 @@ package org.rosi_project.model_sync.generator import org.rosi_project.model_sync.generator.acr_model.SModel import org.rosi_project.model_sync.generator.sync.GetterSetterGeneratingVisitor -/** Simple service to perform all the necessary adaptions of an [[SModel]] to make applicable for - * synchronization. +/** Simple service that adds getter and setter for Attributes and References. * - * @author Rico Bergmann + * @author Christopher Werner */ -class SModelAllGetterSetterPreparationService { +class SModelGetterSetterAllPreparationService { - /** Augments a [[SModel]] with the necessary methods and statements to make it usable in a - * synchronization context. + /** Adds getter and setter for Attributes and References. * * @param sModel the model to augment */ diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAttrPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAttrPreparationService.scala new file mode 100644 index 0000000..0826de0 --- /dev/null +++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAttrPreparationService.scala @@ -0,0 +1,16 @@ +package org.rosi_project.model_sync.generator + +import org.rosi_project.model_sync.generator.sync.BasicTypeGetterSetterGeneratingVisitor +import org.rosi_project.model_sync.generator.acr_model.SModel + +class SModelGetterSetterAttrPreparationService { + + /** Adds getter and setter for Attributes. + * + * @param sModel the model to augment + */ + def prepareModel(sModel: SModel): Unit = { + val getterSetterVisitor = new BasicTypeGetterSetterGeneratingVisitor + sModel.accept(getterSetterVisitor) + } +} \ No newline at end of file diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelRelationalCompartmentPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelRelationalCompartmentPreparationService.scala new file mode 100644 index 0000000..8efb208 --- /dev/null +++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelRelationalCompartmentPreparationService.scala @@ -0,0 +1,20 @@ +package org.rosi_project.model_sync.generator + +import org.rosi_project.model_sync.generator.acr_model.SModel +import org.rosi_project.model_sync.generator.sync._ + +/** Simple service to create relational compartments for each relation. + * + * @author Christopher Werner + */ +class SModelRelationalCompartmentPreparationService { + + /** Create relational compartments for each relation. + * + * @param sModel the model to augment + */ + def prepareModel(sModel: SModel): Unit = { + val relationCompartmentVisitor = new RelationCompartmentGeneratingVisitor + sModel.accept(relationCompartmentVisitor) + } +} \ No newline at end of file diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMCorePreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMCorePreparationService.scala deleted file mode 100644 index eb2d80c..0000000 --- a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMCorePreparationService.scala +++ /dev/null @@ -1,26 +0,0 @@ -package org.rosi_project.model_sync.generator - -import org.rosi_project.model_sync.generator.acr_model.SModel -import org.rosi_project.model_sync.generator.sync._ - -/** Simple service to perform all the necessary adaptions of an [[SModel]] to make applicable for - * single underlying model. - * - * @author Christopher Werner - */ -class SModelSUMCorePreparationService { - - /** Augments a [[SModel]] with the necessary methods and statements to make it usable in a - * single underlying model context. - * - * @param sModel the model to augment - */ - def prepareModel(sModel: SModel): Unit = { - val getterSetterVisitor = new BasicTypeGetterSetterGeneratingVisitor - val relationCompartmentVisitor = new RelationCompartmentGeneratingVisitor - - //order is important !!!! - sModel.accept(getterSetterVisitor) - sModel.accept(relationCompartmentVisitor) - } -} \ No newline at end of file diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMReadEMFService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMReadEMFService.scala index ca6f6a8..c23ffa0 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMReadEMFService.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMReadEMFService.scala @@ -13,8 +13,8 @@ class SModelSUMReadEMFService { * * @param sModel the model to augment */ - def prepareModel(sModel: SModel): Unit = { - val sumModelReadingVisitor = new SumModelReadingVisitor + def prepareModel(sModel: SModel, config: GeneratorConfig): Unit = { + val sumModelReadingVisitor = new SumModelReadingVisitor(config) sModel.accept(sumModelReadingVisitor) } } \ No newline at end of file diff --git a/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala b/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala index b89a9df..8609dbf 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala @@ -87,10 +87,14 @@ class SClassWriter(val modelClass: SClass) { * @return the `String` representation of `m` */ protected def stringifyMethod(m: SMethod): String = { - s"""${if (m.overrides) "override " else ""}${getVisibilityString(m.getVisibility)}def ${m.getName}(${m.params.map(param => s"${param.getName}: ${param.getDeepTypeName}").mkString(", ")}): ${m.getResultType} = { - | ${m.implementation.map(_.getContent).mkString("\n")} - |} - """.stripMargin + var result = s"""${if (m.overrides) "override " else ""}${getVisibilityString(m.getVisibility)}def ${m.getName}(${m.params.map(param => s"${param.getName}: ${param.getDeepTypeName}").mkString(", ")}): ${m.getResultType} """ + if (!m.implementation.isEmpty) { + result = result + s""" = { + | ${m.implementation.map(_.getContent).mkString("\n")} + |} + """ + } + result.stripMargin } /** diff --git a/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriter.scala b/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriter.scala index 535439a..b63bda8 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriter.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriter.scala @@ -9,6 +9,7 @@ import org.rosi_project.model_sync.generator.env.{FilesCompiler, JarPackager} import scala.reflect.io.{Directory, File, Path} import org.rosi_project.model_sync.generator.GeneratorConfig +import org.rosi_project.model_sync.generator.Creation /** The `FSWriter` writes a [[SModel]] as a single compiled ''JAR'' file to the File System. * @@ -60,10 +61,12 @@ class SModelFSWriter( override def visit(sModel: SModel): Unit = { sModel.getModelEnums.foreach(writeEnum(_)) sModel.getModelClasses.foreach(writeClass(_)) - sModel.getJoinClasses.foreach(writeClass(_)) - sModel.getRelationalCompartments.foreach(writeClass(_)) - sModel.getViewCompartments.foreach(writeClass(_)) sModel.getProviderClasses.foreach(writeClass(_)) + if (generatorConfig.create != Creation.rolesync) { + sModel.getJoinClasses.foreach(writeClass(_)) + sModel.getRelationalCompartments.foreach(writeClass(_)) + sModel.getViewCompartments.foreach(writeClass(_)) + } //println(s"... Wrote files (sources) $sFilesToCompile") println("... Starting compilation") diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/BasicTypeGetterSetterGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/BasicTypeGetterSetterGeneratingVisitor.scala index f74ec70..1bdfde2 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/sync/BasicTypeGetterSetterGeneratingVisitor.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/BasicTypeGetterSetterGeneratingVisitor.scala @@ -5,24 +5,26 @@ import org.rosi_project.model_sync.generator.acr_model._ class BasicTypeGetterSetterGeneratingVisitor extends SModelVisitor { override def visit(sModel: SModel): Unit = { - // pass + sModel.getModelClasses.foreach(cls => { + //add all getter and setter for each normal attribute + cls.getAttributes.foreach(attr => { + attr.setVisibility(MethodVisibility.protectedVis) + val getter = new SGetter(attr) + val setter = new SSetter(attr) + cls.addMethod(getter) + cls.addMethod(setter) + }) + }) } override def visit(sClass: SClass): Unit = { - //add all getter and setter for each normal attribute - sClass.getAttributes.foreach(attr => { - attr.setVisibility(MethodVisibility.protectedVis) - val getter = new SGetter(attr) - val setter = new SSetter(attr) - sClass.addMethod(getter) - sClass.addMethod(setter) - }) + // pass } override def visit(sAttr: SAttribute): Unit = { // pass } - + override def visit(sRef: SReference): Unit = { // pass } diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/GetterSetterGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/GetterSetterGeneratingVisitor.scala index 8577860..b9285aa 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/sync/GetterSetterGeneratingVisitor.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/GetterSetterGeneratingVisitor.scala @@ -3,38 +3,41 @@ package org.rosi_project.model_sync.generator.sync import org.rosi_project.model_sync.generator.acr_model._ import org.rosi_project.model_sync.generator.acr_model.types.GenericSequence -/** Service to extend [[SClass SClasses]] with getter and setter methods for all attributes. - * - * @author Rico Bergmann - */ +/** + * Service to extend [[SClass SClasses]] with getter and setter methods for all attributes. + * + * @author Rico Bergmann + */ class GetterSetterGeneratingVisitor extends SModelVisitor { override def visit(sModel: SModel): Unit = { - // pass + sModel.getModelClasses.foreach(cls => { + //add all getter and setter for all structural features + cls.getStructuralFeatures.foreach(attr => { + attr.setVisibility(MethodVisibility.protectedVis) + val getter = new SGetter(attr) + cls.addMethod(getter) + if (attr.getTypeElement.isInstanceOf[GenericSequence]) { + val adder = new SSetterAdd(attr, attr.getTypeElement.asInstanceOf[GenericSequence].typeParam) + cls.addMethod(adder) + val remover = new SSetterRemove(attr, attr.getTypeElement.asInstanceOf[GenericSequence].typeParam) + cls.addMethod(remover) + } else { + val setter = new SSetter(attr) + cls.addMethod(setter) + } + }) + }) } override def visit(sClass: SClass): Unit = { - sClass.getStructuralFeatures.foreach(attr => { - attr.setVisibility(MethodVisibility.protectedVis) - val getter = new SGetter(attr) - sClass.addMethod(getter) - if (attr.getTypeElement.isInstanceOf[GenericSequence]) { - val adder = new SSetterAdd(attr, attr.getTypeElement.asInstanceOf[GenericSequence].typeParam) - sClass.addMethod(adder) - val remover = new SSetterRemove(attr, attr.getTypeElement.asInstanceOf[GenericSequence].typeParam) - sClass.addMethod(remover) - } else { - val setter = new SSetter(attr) - sClass.addMethod(setter) - } - }) - + // pass } override def visit(sAttr: SAttribute): Unit = { // pass } - + override def visit(sRef: SReference): Unit = { // pass } diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.scala index 4843488..73a3118 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.scala @@ -79,12 +79,6 @@ class InstanceCombiGenerator(val clsins: ClassAndInstance) extends SModelVisitor }) }) - //remove references - sModel.getModelClasses.foreach(cls => { - //remove all references from the class - cls.setReferences(null) - }) - //construction of instances lines.foreach(l => { example.augmentConstructor(new SMethodStatement(l.getLine(), Set(l.usedType))) @@ -98,9 +92,6 @@ class InstanceCombiGenerator(val clsins: ClassAndInstance) extends SModelVisitor example.addParent(PredefTypes.App) sModel.addProviderClass(example) - //println("++++++++++++++++++++++++++++++++++++++++++++++") - // pass - } def setValues(eo: EObject, lines: Seq[InstanceLine]): String = { diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/SumModelReadingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/SumModelReadingVisitor.scala index 989aa9f..7131f58 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/sync/SumModelReadingVisitor.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/SumModelReadingVisitor.scala @@ -5,17 +5,23 @@ import org.rosi_project.model_sync.generator.PackageNames import org.rosi_project.model_sync.generator.acr_model.types.PredefEcoreTypes import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes import org.rosi_project.model_sync.generator.acr_model.types.GenericSequence +import org.rosi_project.model_sync.generator.GeneratorConfig +import org.rosi_project.model_sync.generator.Creation /** * Read EMF and Ecore models. * * @author Christopher Werner */ -class SumModelReadingVisitor() extends SModelVisitor { +class SumModelReadingVisitor(config: GeneratorConfig) extends SModelVisitor { override def visit(sModel: SModel): Unit = { //println("++++++++++++++++++++++++++++++++++++++++++++++") - val creator = new SClass("Creation" + sModel.getName, PackageNames.creationPkgName) + val creatorSum = new SClass("Creation" + sModel.getName + "Sum", PackageNames.creationPkgName) + val creatorSync = new SClass("Creation" + sModel.getName + "Sync", PackageNames.creationPkgName) + val creatorInterface = new SClass("ICreation" + sModel.getName, PackageNames.creationPkgName, SClassType.normalTrait) + creatorSum.addParent(creatorInterface) + creatorSync.addParent(creatorInterface) val loader = new SClass("Loader" + sModel.getName, PackageNames.creationPkgName) val loadEcore = new SMethod( @@ -35,10 +41,10 @@ class SumModelReadingVisitor() extends SModelVisitor { SMethodStatement(content = s"return ressourceModel.getContents().get(0)"))) loader.addMethod(loadEcore) - val createModelInstance = new SMethod( + val createModelInstanceSum = new SMethod( name = s"create${sModel.getName}Instance", result = PredefTypes.Unit, - params = Seq(SMethodParameter("obj", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creator)), + params = Seq(SMethodParameter("obj", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creatorInterface)), implementation = Seq( SMethodStatement(content = s"createObj(obj, creator)"), SMethodStatement(content = s"obj.eAllContents().asScala.foreach(o => {", usedTypes = Set(PredefTypes.ScalaConverter)), @@ -48,12 +54,12 @@ class SumModelReadingVisitor() extends SModelVisitor { SMethodStatement(content = s"obj.eAllContents().asScala.foreach(o => {"), SMethodStatement(content = s"createRef(o, creator)"), SMethodStatement(content = s"})"))) - loader.addMethod(createModelInstance) + loader.addMethod(createModelInstanceSum) val createObj = new SMethod( name = "createObj", result = PredefTypes.Unit, - params = Seq(SMethodParameter("obj", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creator)), + params = Seq(SMethodParameter("obj", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creatorInterface)), implementation = Seq.empty) var createObjImpl = Seq(SMethodStatement(content = s"var objName = obj.eClass.getName"), SMethodStatement(content = s"objName match {")) @@ -61,7 +67,7 @@ class SumModelReadingVisitor() extends SModelVisitor { val createRef = new SMethod( name = "createRef", result = PredefTypes.Unit, - params = Seq(SMethodParameter("o1", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creator)), + params = Seq(SMethodParameter("o1", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creatorInterface)), implementation = Seq.empty) var createRefImpl = Seq(SMethodStatement(content = s"o1.eClass().getEAllReferences.forEach(sf => {"), SMethodStatement(content = s"val sfName = sf.getName"), @@ -69,42 +75,96 @@ class SumModelReadingVisitor() extends SModelVisitor { SMethodStatement(content = s"val o1Name = o1.eClass().getName"), SMethodStatement(content = s"val o2Name = o2.eClass().getName")) - creator.augmentConstructor(SMethodStatement(content = s"var mapping: Map[EObject, Object] = Map.empty", usedTypes = Set(PredefEcoreTypes.EcoreObject))) + creatorSum.augmentConstructor(SMethodStatement(content = s"var mapping: Map[EObject, Object] = Map.empty", usedTypes = Set(PredefEcoreTypes.EcoreObject))) + creatorSync.augmentConstructor(SMethodStatement(content = s"var mapping: Map[EObject, Object] = Map.empty", usedTypes = Set(PredefEcoreTypes.EcoreObject))) sModel.getModelClasses.filter(c => !c.isAbstract && !c.isInterface).foreach(c => { - val method = new SMethod( + //method for trait + val methodTrait = new SMethod( + name = s"create${c.getName}", + result = PredefTypes.Unit, + params = c.getAttributeConstructorParameters :+ SMethodParameter("id", PredefEcoreTypes.EcoreObject), + implementation = Seq.empty) + creatorInterface.addMethod(methodTrait) + + //method for sync + val methodSum = new SMethod( + name = s"create${c.getName}", + result = PredefTypes.Unit, + params = c.getAttributeConstructorParameters :+ SMethodParameter("id", PredefEcoreTypes.EcoreObject), + implementation = Seq( + SMethodStatement(content = s"mapping += (id -> new ${c.getName}(${c.getAttributeConstructorParameters.map(m => m.getName).mkString(", ")}))", usedTypes = Set(c))), + overrides = true) + creatorSum.addMethod(methodSum) + + //method for sync + val methodSync = new SMethod( name = s"create${c.getName}", result = PredefTypes.Unit, params = c.getAttributeConstructorParameters :+ SMethodParameter("id", PredefEcoreTypes.EcoreObject), implementation = Seq( - SMethodStatement(content = s"mapping += (id -> new ${c.getName}(${c.getAttributeConstructorParameters.map(m => m.getName).mkString(", ")}))", usedTypes = Set(c)))) - creator.addMethod(method) + SMethodStatement(content = s"mapping += (id -> new ${c.getName}(${c.getAllConstructorParameters.map(m => if(m.getType.isInstanceOf[GenericSequence]) "Set.empty" else if (m.getType.isInstanceOf[SClass]) "null" else m.getName).mkString(", ")}))", usedTypes = Set(c))), //TODO + overrides = true) + creatorSync.addMethod(methodSync) - var s = c.getAttributeConstructorParameters.map(m => s"""obj.eGet(obj.eClass().getEStructuralFeature("${m.getName}"))${if(m.getTypeName == "Boolean") ".asInstanceOf[Boolean]" else ".toString()"} """).mkString(", ") + var s = c.getAttributeConstructorParameters.map(m => s"""obj.eGet(obj.eClass().getEStructuralFeature("${m.getName}"))${if (m.getTypeName == "Boolean") ".asInstanceOf[Boolean]" else ".toString()"} """).mkString(", ") if (s.isEmpty()) { s = "obj" } else { - s = s + ", obj" + s = s + ", obj" } createObjImpl = createObjImpl :+ SMethodStatement(content = s"""case "${c.getName}" => creator.create${c.getName}(${s})""") }) sModel.getRelationalCompartments.foreach(r => { var rc = r.asInstanceOf[SRelationalCompartmentClass] - val method = new SMethod( + //method for trait + val methodTrait = new SMethod( + name = s"create${r.getName}", + result = PredefTypes.Unit, + params = Seq(SMethodParameter("s", PredefEcoreTypes.EcoreObject), SMethodParameter("t", PredefEcoreTypes.EcoreObject)), + implementation = Seq.empty) + creatorInterface.addMethod(methodTrait) + + //sum method + val methodSum = new SMethod( name = s"create${r.getName}", result = PredefTypes.Unit, params = Seq(SMethodParameter("s", PredefEcoreTypes.EcoreObject), SMethodParameter("t", PredefEcoreTypes.EcoreObject)), implementation = Seq( SMethodStatement(content = s"val s1 = mapping.get(s).get.asInstanceOf[${rc.sClass.getName}]"), SMethodStatement(content = s"val t1 = mapping.get(t).get.asInstanceOf[${rc.tClass.getName}]"), - SMethodStatement(content = s"(new ${rc.getName}(s1, t1)).initialize()", usedTypes = Set(rc, rc.sClass, rc.tClass)))) + SMethodStatement(content = s"(new ${rc.getName}(s1, t1)).initialize()", usedTypes = Set(rc, rc.sClass, rc.tClass))), + overrides = true) + creatorSum.addMethod(methodSum) + + //sync method + val methodSync = new SMethod( + name = s"create${r.getName}", + result = PredefTypes.Unit, + params = Seq(SMethodParameter("s", PredefEcoreTypes.EcoreObject), SMethodParameter("t", PredefEcoreTypes.EcoreObject)), + implementation = Seq.empty, + overrides = true) + var implMethodSync = Seq(SMethodStatement(content = s"val s1 = mapping.get(s).get.asInstanceOf[${rc.sClass.getName}]", usedTypes = Set(rc, rc.sClass, rc.tClass)), + SMethodStatement(content = s"val t1 = mapping.get(t).get.asInstanceOf[${rc.tClass.getName}]")) if (rc.connectedRef.getTypeElement.isInstanceOf[GenericSequence]) { //add -> add method + implMethodSync = implMethodSync :+ SMethodStatement(content = s"s1.add${rc.connectedRef.getName.capitalize}(t1)") } else { //add -> set method + implMethodSync = implMethodSync :+ SMethodStatement(content = s"s1.set${rc.connectedRef.getName.capitalize}(t1)") } - creator.addMethod(method) + if (rc.connectedRef.hasOpposite) { + if (rc.connectedRef.oppositeRef.getTypeElement.isInstanceOf[GenericSequence]) { + //add -> add method + implMethodSync = implMethodSync :+ SMethodStatement(content = s"t1.add${rc.connectedRef.oppositeRef.getName.capitalize}(s1)") + } else { + //add -> set method + implMethodSync = implMethodSync :+ SMethodStatement(content = s"t1.set${rc.connectedRef.oppositeRef.getName.capitalize}(s1)") + } + } + methodSync.implementation = implMethodSync + creatorSync.addMethod(methodSync) createRefImpl = createRefImpl :+ SMethodStatement(content = s"""if (o1Name.contains("${rc.sClass.getName}") && sfName == "${rc.connectedRef.getName}" && o2Name.contains("${rc.tClass.getName}")) {""") createRefImpl = createRefImpl :+ SMethodStatement(content = s"creator.create${rc.getName}(o1, o2)") @@ -115,13 +175,18 @@ class SumModelReadingVisitor() extends SModelVisitor { createObjImpl = createObjImpl :+ SMethodStatement(content = "}") createObj.implementation = createObjImpl loader.addMethod(createObj) - + createRefImpl = createRefImpl :+ SMethodStatement(content = "})") createRef.implementation = createRefImpl loader.addMethod(createRef) //add the new classes as model classes - sModel.addProviderClass(creator) + if (config.create == Creation.rolesync) { + sModel.addProviderClass(creatorSync) + } else { + sModel.addProviderClass(creatorSum) + } + sModel.addProviderClass(creatorInterface) sModel.addProviderClass(loader) } diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/SyncEnhancingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/SyncEnhancingVisitor.scala index 02dab55..b4c550d 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/sync/SyncEnhancingVisitor.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/SyncEnhancingVisitor.scala @@ -17,15 +17,19 @@ import org.rosi_project.model_sync.generator.acr_model._ class SyncEnhancingVisitor() extends SModelVisitor { override def visit(sModel: SModel): Unit = { - // pass + sModel.getModelClasses.foreach(cls => { + //TODO: do not have in mind trait extends abstract extends trait hierarchy + if (cls.isAbsoluteRootClassOrInterface) { + cls.addParent(PredefSyncTypes.PLAYER_SYNC_STYPE) + } + cls.getMethods.foreach(m => { + extractSetterAttr(m).foreach(attr => m.augmentImplementation(SMethodStatement(s"+this $attr"))) + }) + }) } override def visit(sClass: SClass): Unit = { - //TODO: do not have in mind trait extends abstract extends trait hierarchy - if (sClass.isAbsoluteRootClassOrInterface && !sClass.isInstanceOf[SRelationalCompartmentClass]) { - //if (sClass.isRootClass && !sClass.isInterface && !sClass.isInstanceOf[SRelationalCompartmentClass]) { - sClass.addParent(PredefSyncTypes.PLAYER_SYNC_STYPE) - } + // pass } override def visit(sAttr: SAttribute): Unit = { @@ -37,7 +41,7 @@ class SyncEnhancingVisitor() extends SModelVisitor { } override def visit(sMethod: SMethod): Unit = { - extractSetterAttr(sMethod).foreach(attr => sMethod.augmentImplementation(SMethodStatement(s"+this $attr"))) + // pass } override def visit(sType: SType): Unit = { diff --git a/src/main/scala/org/rosi_project/model_sync/generator/test/ApplicationTest.scala b/src/main/scala/org/rosi_project/model_sync/generator/test/ApplicationTest.scala index e83db03..e9c860d 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/test/ApplicationTest.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/test/ApplicationTest.scala @@ -13,8 +13,8 @@ object ApplicationTest extends App { //runTestAML(Creation.rolesum) //TTC Case examples - runTTC2019(Creation.rolecomb) - //runTTC2019(Creation.rolesync) + //runTTC2019(Creation.rolecomb) + runTTC2019(Creation.rolesync) //runTTCLive2019(Creation.rolesync) //Run all tests diff --git a/src/main/scala/org/rosi_project/model_sync/generator/ui/SyncUiVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/ui/SyncUiVisitor.scala index 13bba39..26cc53a 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/ui/SyncUiVisitor.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/ui/SyncUiVisitor.scala @@ -8,9 +8,17 @@ import org.rosi_project.model_sync.generator.acr_model._ */ class SyncUiVisitor(val modelCfg: ModelConfig) extends SModelVisitor { - private var additionalSyncClasses: Seq[SClass] = Seq.empty - override def visit(sModel: SModel): Unit = { + var additionalSyncClasses: Seq[SClass] = Seq.empty + sModel.getModelClasses.foreach(cls => { + if (!cls.isAbstract && !cls.isInterface) { + additionalSyncClasses = additionalSyncClasses :+ new ConstructorTemplate(cls) + } + cls.getStructuralFeatures.foreach(struc => { + additionalSyncClasses = additionalSyncClasses :+ new ModifierTemplate(cls, struc) + }) + }) + additionalSyncClasses.foreach(sModel.addProviderClass) modelCfg.init.nested.foreach(_.foreach(model => sModel.addProviderClass(new InitialModelTemplate(model)))) @@ -20,18 +28,13 @@ class SyncUiVisitor(val modelCfg: ModelConfig) extends SModelVisitor { } override def visit(sClass: SClass): Unit = { - if (!sClass.isAbstract && !sClass.isInterface) { - additionalSyncClasses = additionalSyncClasses :+ new ConstructorTemplate(sClass) - } - sClass.getStructuralFeatures.foreach(struc => { - additionalSyncClasses = additionalSyncClasses :+ new ModifierTemplate(sClass, struc) - }) + // pass } override def visit(sAttr: SAttribute): Unit = { // pass } - + override def visit(sRef: SReference): Unit = { // pass } -- GitLab