From ffbb17e9d36784a4f9ffbf2203a0385a2f230154 Mon Sep 17 00:00:00 2001 From: Chrissi <christopher@hbsc-werner.de> Date: Tue, 4 Jun 2019 10:06:05 +0200 Subject: [PATCH] add generation of instances for combination of rsum and rsync can be used for rsum --- .../model_sync/generator/Generator.scala | 12 ++ .../SModelCombiInstanceService.scala | 22 +++ .../SModelSUMCorePreparationService.scala | 2 - .../generator/SModelSUMRemoveRefService.scala | 22 +++ .../generator/acr_model/SClass.scala | 14 ++ .../generator/acr_model/STypedElement.scala | 5 + .../sync/InstanceCombiGenerator.scala | 134 ++++++++++++++++++ .../generator/sync/InstanceGenerator.scala | 13 +- .../generator/util/InstanceLine.scala | 7 +- 9 files changed, 217 insertions(+), 14 deletions(-) create mode 100644 src/main/scala/org/rosi_project/model_sync/generator/SModelCombiInstanceService.scala create mode 100644 src/main/scala/org/rosi_project/model_sync/generator/SModelSUMRemoveRefService.scala create mode 100644 src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.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 9d594c7..c81f258 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 @@ -51,6 +51,7 @@ class Generator(config: GeneratorConfig) { //create the new classes for rsum and rsync if (config.getCreate == Creation.rolesync) { sModels.foreach(sm => { + //instance generation for rsync if (sm._2.obj != null) { new SModelSyncInstanceService prepareModel(sm._1, sm._2) } @@ -63,6 +64,8 @@ class Generator(config: GeneratorConfig) { 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) }) @@ -73,6 +76,15 @@ class Generator(config: GeneratorConfig) { new SModelSUMCorePreparationService prepareModel (sm._1) //add sync stuff new SModelOnlySyncService prepareModel (sm._1) + //instance generation for combi means rsum + if (sm._2.obj != null) { + new SModelCombiInstanceService prepareModel(sm._1, sm._2) + } + else + { + //remove references + new SModelSUMRemoveRefService prepareModel (sm._1) + } //create view and query stuff new SModelSUMPreparationService prepareModel (sm._1) }) diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiInstanceService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiInstanceService.scala new file mode 100644 index 0000000..348b2e3 --- /dev/null +++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiInstanceService.scala @@ -0,0 +1,22 @@ +package org.rosi_project.model_sync.generator + +import org.rosi_project.model_sync.generator.acr_model.SModel +import org.rosi_project.model_sync.generator.util.ClassAndInstance +import org.rosi_project.model_sync.generator.sync.InstanceCombiGenerator + +/** Simple service to create instances. + * For the combination of sum and sync. + * + * @author Christopher Werner + */ +class SModelCombiInstanceService { + + /** Add a new class to the [[SModel]] to instantiate it. + * + * @param sModel the model to augment + */ + def prepareModel(sModel: SModel, clsAins: ClassAndInstance): Unit = { + val insgenerator = new InstanceCombiGenerator(clsAins) + sModel.accept(insgenerator) + } +} \ 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 index 4debc8d..eb2d80c 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMCorePreparationService.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMCorePreparationService.scala @@ -18,11 +18,9 @@ class SModelSUMCorePreparationService { def prepareModel(sModel: SModel): Unit = { val getterSetterVisitor = new BasicTypeGetterSetterGeneratingVisitor val relationCompartmentVisitor = new RelationCompartmentGeneratingVisitor - val removeReferencesVisitor = new ReferenceRemoveVisitor //order is important !!!! sModel.accept(getterSetterVisitor) sModel.accept(relationCompartmentVisitor) - sModel.accept(removeReferencesVisitor) } } \ No newline at end of file diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMRemoveRefService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMRemoveRefService.scala new file mode 100644 index 0000000..b389f9f --- /dev/null +++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMRemoveRefService.scala @@ -0,0 +1,22 @@ +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.ReferenceRemoveVisitor + +/** Remove references from model classes. + * + * @author Christopher Werner + */ +class SModelSUMRemoveRefService { + + /** Remove reference from model classes. + * + * @param sModel the model to augment + */ + def prepareModel(sModel: SModel): Unit = { + val removeReferencesVisitor = new ReferenceRemoveVisitor + + //order is important !!!! + sModel.accept(removeReferencesVisitor) + } +} \ No newline at end of file diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala index 08cc586..a69d98e 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala @@ -77,6 +77,20 @@ class SClass(_name: String, } } } + + override def proofHierarchicalEquality(sType: STypedElement): Boolean = { + if (sType == this) { + return true + } else { + this.getAllParents().foreach(p => { + if (p.proofHierarchicalEquality(sType)) { + return true + } + }) + return false + } + + } /** * Augments `this` class with another method. diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala index d3de6f2..b57f9e3 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala @@ -34,6 +34,11 @@ abstract class STypedElement (_name: String, * will be ignored however. */ def getInheritanceHierarchy: Seq[STypedElement] = Seq.empty + + /** + * Proof the hierarchical equality between two STypedElement + */ + def proofHierarchicalEquality(sType: STypedElement): Boolean = sType == this /** Provides all classes that need to be imported for `this` type. */ 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 new file mode 100644 index 0000000..4cefc3e --- /dev/null +++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.scala @@ -0,0 +1,134 @@ +package org.rosi_project.model_sync.generator.sync + +import scala.collection.JavaConverters._ +import org.rosi_project.model_sync.generator.acr_model._ +import org.rosi_project.model_sync.generator.util.ClassAndInstance +import org.eclipse.emf.ecore.EObject +import org.rosi_project.model_sync.generator.util.InstanceLine +import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes +import org.eclipse.emf.ecore.EStructuralFeature +import org.eclipse.emf.common.util.EList +import org.rosi_project.model_sync.util.EMFUtilForGenerator +import java.util.List + +class InstanceCombiGenerator(val clsins: ClassAndInstance) extends SModelVisitor { + + override def visit(sModel: SModel): Unit = { + //println("++++++++++++++++++++++++++++++++++++++++++++++") + val example = new SClass("ExampleCombiCase", "example") + val contents = clsins.obj.eAllContents().asScala + var counter = 0 + var lines: Seq[InstanceLine] = Seq.empty + var generationLines: Seq[InstanceLine] = Seq.empty + var sType = STypeRegistry.getFromClass(clsins.obj.eClass()) + if (sType != null) { + lines = lines :+ new InstanceLine(counter, clsins.obj, sType) + counter += 1 + } + contents.foreach(o => { + sType = STypeRegistry.getFromClass(o.eClass()) + if (sType != null) { + lines = lines :+ new InstanceLine(counter, o, sType) + counter += 1 + } + }) + //add values for instances + lines.foreach(l => { + l.usedType.getAllConstructorParameters.foreach(cp => { + if (!STypeRegistry.isDefaultType(cp.getType.getName)) { + val structs: Seq[EStructuralFeature] = l.obj.eClass().getEAllStructuralFeatures.asScala + structs.foreach(att => { + if (att.getName == cp.getName) { + val obj = l.obj.eGet(att) + if (obj.isInstanceOf[EObject]) { + lines.foreach(lnow => { + if (lnow.obj == obj.asInstanceOf[EObject]) { + //println("Found: " + lnow.counter) .filter(_.isInstanceOf[SRelationalCompartmentClass]) + sModel.getRelationalCompartments.foreach(rc => { + val realRc = rc.asInstanceOf[SRelationalCompartmentClass] + //println(" AN: " + att.getName + " l1: " + l.usedType.getName + " l2: " + lnow.usedType.getName + " RC: " + realRc.connectedRef.getName + " SN: " + realRc.sClass.getName + " TN: " + realRc.tClass.getName) + if (realRc.connectedRef.getName == att.getName && l.usedType.proofHierarchicalEquality(realRc.sClass) && lnow.usedType.proofHierarchicalEquality(realRc.tClass)) { + val s = s"new ${realRc.getName}(${l.getName()}, ${lnow.getName()})" + generationLines = generationLines :+ new InstanceLine(0, null, realRc, s) + } + }) + } + }) + } else { + val listi: List[EObject] = EMFUtilForGenerator.getList(obj) + val liste = listi.asScala + liste.foreach(eo => { + lines.foreach(lnow => { + if (lnow.obj == eo) { + sModel.getRelationalCompartments.foreach(rc => { + val realRc = rc.asInstanceOf[SRelationalCompartmentClass] + //println(" AN: " + att.getName + " l1: " + l.usedType.getName + " l2: " + lnow.usedType.getName + " RC: " + realRc.connectedRef.getName + " SN: " + realRc.sClass.getName + " TN: " + realRc.tClass.getName) + if (realRc.connectedRef.getName == att.getName && l.usedType.proofHierarchicalEquality(realRc.sClass) && lnow.usedType.proofHierarchicalEquality(realRc.tClass)) { + val s = s"new ${realRc.getName}(${l.getName()}, ${lnow.getName()})" + generationLines = generationLines :+ new InstanceLine(0, null, realRc, s) + } + }) + } + }) + }) + } + } + }) + } + }) + }) + + //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))) + }) + + //construction of connections + generationLines.foreach(l => { + example.augmentConstructor(new SMethodStatement(l.getLine(), Set(l.usedType))) + }) + + + example.addParent(PredefTypes.App) + sModel.addJoinObject(example) + //println("++++++++++++++++++++++++++++++++++++++++++++++") + // pass + + } + + def setValues(eo: EObject, lines: Seq[InstanceLine]): String = { + lines.foreach(lnow => { + if (lnow.obj == eo) { + return lnow.getName() + } + }) + "" + } + + override def visit(sClass: SClass): Unit = { + // pass + } + + override def visit(sAttr: SAttribute): Unit = { + // pass + } + + override def visit(sRef: SReference): Unit = { + // pass + } + + override def visit(sMethod: SMethod): Unit = { + // pass + } + + override def visit(sType: SType): Unit = { + // pass + } + +} \ No newline at end of file diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceGenerator.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceGenerator.scala index 066cc6e..224714e 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceGenerator.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceGenerator.scala @@ -19,7 +19,7 @@ import java.util.List class InstanceGenerator(val clsins: ClassAndInstance) extends SModelVisitor { override def visit(sModel: SModel): Unit = { - println("++++++++++++++++++++++++++++++++++++++++++++++") + //println("++++++++++++++++++++++++++++++++++++++++++++++") val example = new SClass("ExampleCase", "example") val contents = clsins.obj.eAllContents().asScala var counter = 0 @@ -48,9 +48,8 @@ class InstanceGenerator(val clsins: ClassAndInstance) extends SModelVisitor { structs.foreach(att => { if (att.getName == cp.getName) { val obj = l.obj.eGet(att) - println("### " + att.getName + " T: " + obj.isTraversableAgain + " Si: " + obj.size + " C: " + obj.getClass + " " + obj.getClass.getSimpleName) + //println("### " + att.getName) if (obj.isInstanceOf[EObject]) { - //println("Obj") lines.foreach(lnow => { if (lnow.obj == obj.asInstanceOf[EObject]) { //println("Found: " + lnow.counter) @@ -68,16 +67,10 @@ class InstanceGenerator(val clsins: ClassAndInstance) extends SModelVisitor { }) } }) - - /*var structs: Seq[EStructuralFeature] = l.obj.eClass().getEAllStructuralFeatures.asScala - structs.foreach(att => { - println(att.getName + " " + l.obj.eGet(att)) - })*/ - //println(l.obj.eGet(l.obj.eClass().getEAllAttributes.get(0))) }) example.addParent(PredefTypes.App) sModel.addJoinObject(example) - println("++++++++++++++++++++++++++++++++++++++++++++++") + //println("++++++++++++++++++++++++++++++++++++++++++++++") // pass } diff --git a/src/main/scala/org/rosi_project/model_sync/generator/util/InstanceLine.scala b/src/main/scala/org/rosi_project/model_sync/generator/util/InstanceLine.scala index d7a3624..56bd013 100644 --- a/src/main/scala/org/rosi_project/model_sync/generator/util/InstanceLine.scala +++ b/src/main/scala/org/rosi_project/model_sync/generator/util/InstanceLine.scala @@ -9,10 +9,13 @@ import org.rosi_project.model_sync.generator.acr_model.SMethodParameter import org.rosi_project.model_sync.generator.acr_model.STypeRegistry import org.eclipse.emf.ecore.EStructuralFeature -class InstanceLine(val counter: Int, val obj: EObject, val usedType: STypedElement) { +class InstanceLine(val counter: Int, val obj: EObject, val usedType: STypedElement, val lineString: String = "") { def getLine(): String = { - s"val i${counter} = new ${usedType.getName} (${usedType.getAllConstructorParameters.map(classEmptyConstructorParameterCreation(_)).mkString(", ")})" + if (obj != null) { + return s"val i${counter} = new ${usedType.getName} (${usedType.getAllConstructorParameters.map(classEmptyConstructorParameterCreation(_)).mkString(", ")})" + } + return lineString } def getName(): String = "i" + counter -- GitLab