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 9067dc95e5bc8700ab365bdc1b2cda0471783c64..1473fa09947980c6f24c01fe83d7e54a68b4618b 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 1e1e9d9c98d352de643d9e094d783c4d94236e8c..e83e64902196fc30fbee8052a520ec9240f52819 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 cfe8d27cdedc4581f83f6c9b8fb4b5cf84040cac..8978200b02c671162c24a2d813b21ae62ab2eb33 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 0000000000000000000000000000000000000000..0826de0a411ce9cc99125f7f788d11a5764bf874 --- /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 0000000000000000000000000000000000000000..8efb2081eaf7c844d8c71024c0ff21c455f9056c --- /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 eb2d80c4ff2fbc4f7870f167e277f8a61d413513..0000000000000000000000000000000000000000 --- 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 ca6f6a800787e120b3dfdf00f1702c58a2c53882..c23ffa0fc0094e3a3beccb31ec4ab0fd784bc6df 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 b89a9df127a862d32f6c81302fb1c459724d2012..8609dbf491fe2587b18bcb6a66eb9cb316fbdfd5 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 535439a1495f6972d78e9f973a3b7672869915cb..b63bda8d1453df724e9482ce7cb71f4ae7c9a139 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 f74ec70b3e96923bb716ee9478fed3b250c7eec2..1bdfde2ce77c1798744658895d18b61bac7f206c 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 857786022f807999c8d2284923c3e8e4e36d5b07..b9285aaa2d94636ebd428c2348c8d959b85ef84e 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 4843488e23d1d3e7369034d284244364c2b7d71e..73a31185eb74b6b2a5a20cf56a1e57aab299d143 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 989aa9f2e10e0d7f66fa221da3b07bf312451d18..7131f58ea53021ad678e219f7438b148a019ac03 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 02dab551744b2ece4ee03c76f1e358ef80645366..b4c550d133b63881f06ddd750718644770bbc759 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 e83db03ca0e43e14eafaa8484475e403d38634b9..e9c860d7a22f5409264aed688e780ca5a8b430b7 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 13bba399a9e6fe2f6fabb34345d4a9882e452a24..26cc53a33d9d89ebe6de59e7c361c0d5c228dedb 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 }