diff --git a/models/designPattern/Chain-of-responsibility.Json b/models/designPattern/Chain-of-responsibility.Json index 28a66b5..78c4119 100644 --- a/models/designPattern/Chain-of-responsibility.Json +++ b/models/designPattern/Chain-of-responsibility.Json @@ -4,10 +4,9 @@ { "relations": [], "transfer": { - "src": "Main", - "dst": "Main.OrcKing.{ConcreteOrcRequestHandler}", + "src": "Main.Request", + "dst": "Main.{ConcreteOrcRequestHandler}.Request", "data": { - "type": "Request", "name": "request" }, "style": "PUSH", diff --git a/models/designPattern/Command2.Json b/models/designPattern/Command2.Json index 972e4ac..a4b5779 100644 --- a/models/designPattern/Command2.Json +++ b/models/designPattern/Command2.Json @@ -4,10 +4,9 @@ { "relations": [], "transfer": { - "src": "Main", - "dst": "Main.Wizard", + "src": "Main.Goblin", + "dst": "Main.Wizard.Goblin", "data": { - "type": "Goblin", "name": "goblin" }, "style": "PUSH", @@ -17,10 +16,9 @@ { "relations": [], "transfer": { - "src": "Main.Wizard", - "dst": "Main.Goblin", + "src": "Main.Data", + "dst": "Main.Wizard.Goblin.Data", "data": { - "type": "data", "name": "data" }, "style": "PUSH", diff --git a/models/designPattern/Flyweight.Json b/models/designPattern/Flyweight.Json index f049a7b..708108b 100644 --- a/models/designPattern/Flyweight.Json +++ b/models/designPattern/Flyweight.Json @@ -6,7 +6,7 @@ { "src": "Main.AlchemistShop.PotionFactory.{Potion}", "dst": "Main.AlchemistShop", - "multiplicity": "1:1" + "multiplicity": "*:*" } ], "transfer": { @@ -22,13 +22,13 @@ { "relations": [], "transfer": { - "src": "Main.AlchemistShop.TopShelf.{Potion}.Data", - "dst": "Main.Data", + "src": "Main.AlchemistShop.TopShelf.{Potion}", + "dst": "Main.AlchemistShop.{Potion}", "data": { - "name": "data" + "name": "potion" }, "style": "PULL", - "multiplicity": "*:1" + "multiplicity": "*:*" } } ] diff --git a/models/designPattern/Observer.Json b/models/designPattern/Observer.Json index 769a19e..d439ae5 100644 --- a/models/designPattern/Observer.Json +++ b/models/designPattern/Observer.Json @@ -2,18 +2,11 @@ "name": "Observer", "contexts": [ { - "relations": [ - { - "src": "Main", - "dst": "Main.Weather.{ConcreteObserver}", - "multiplicity": "1:1" - } - ], + "relations": [], "transfer": { - "src": "Main.Weather", - "dst": "Main.Weather.{ConcreteObserver}", + "src": "Main.Data", + "dst": "Main.{ConcreteObserver}.Data", "data": { - "type": "Data", "name": "data" }, "style": "PUSH", @@ -23,14 +16,13 @@ { "relations": [], "transfer": { - "src": "Main", - "dst": "Main.Weather", + "src": "Main.ConcreteObserver", + "dst": "Main.Weather.{ConcreteObserver}", "data": { - "type": "ConcreteObserver", "name": "concreteObserver" }, "style": "PUSH", - "multiplicity": "1:*" + "multiplicity": "1:1" } } ] diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 7570aeb..451a648 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -28,8 +28,8 @@ dstEdges.add(dstEdge); dstEdges.add(dstEdge2); List relations = new ArrayList<>(); -// Relation transferRelation = new Relation(company, customer, MultiplicityValue.OneToOne); Relation transferRelation = new Relation(srcEdges, dstEdges, MultiplicityValue.OneToMany); +// DataSynchronizationContext context = new DataSynchronizationContext(relations, transferRelation, "address", PushPullValue.PULL); DataSynchronizationContext context = new DataSynchronizationContext(relations, transferRelation, "address", PushPullValue.PUSH); DataSynchronizationDesign design; @@ -43,7 +43,7 @@ // DependencyInversion di = new DependencyInversion(company, new InterfaceNode(company, "ICompany"), customer); // design.addDependencyInversion(di); - design = new Flyweight().create(); +// design = new Flyweight().create(); System.out.println(design.getDeltaComplex()); System.out.println(ASTGenerator.generate(design)); diff --git a/src/main/java/designPatternExtensions/designPattern/Chain_of_Responsibility.java b/src/main/java/designPatternExtensions/designPattern/Chain_of_Responsibility.java index 96e423c..0ae79f0 100644 --- a/src/main/java/designPatternExtensions/designPattern/Chain_of_Responsibility.java +++ b/src/main/java/designPatternExtensions/designPattern/Chain_of_Responsibility.java @@ -18,15 +18,15 @@ DataSynchronizationDesign design = ModelLoader.load("models/designPattern/Chain-of-responsibility.Json"); DataSynchronizationContext dtc = design.getSynchronizationContexts().getFirst(); ObjectNode main = dtc.getSrcTopObject(); - ObjectNode concreteOrcRequestHandler = (ObjectNode) dtc.getDstObjectHierarchy().getEdge(1).getDestination(); + ObjectNode concreteOrcRequestHandler = (ObjectNode) dtc.getDstObjectHierarchy().getEdge(0).getDestination(); //ObjectNode concreteOrcRequestHandler = (ObjectNode) dtc.getDstResource().getEdge(0).getDestination(); InterfaceNode requestHandler = new InterfaceNode(concreteOrcRequestHandler, "RequestHandler"); DependencyInversion di = new DependencyInversion(concreteOrcRequestHandler, requestHandler); design.addDependencyInversion(di); -// MediatorInsertion mi = new MediatorInsertion(main, concreteOrcRequestHandler, new ObjectNode("OrcKing"), PushPullValue.PUSH); -// design.addMediatorInsertion(mi); + MediatorInsertion mi = new MediatorInsertion(main, concreteOrcRequestHandler, new ObjectNode("OrcKing"), PushPullValue.PUSH); + design.addMediatorInsertion(mi); return design; } diff --git a/src/main/java/designPatternExtensions/designPattern/Command.java b/src/main/java/designPatternExtensions/designPattern/Command.java index 8882594..069a338 100644 --- a/src/main/java/designPatternExtensions/designPattern/Command.java +++ b/src/main/java/designPatternExtensions/designPattern/Command.java @@ -31,10 +31,11 @@ public DataSynchronizationDesign create() throws IllegalRelationException { DataSynchronizationDesign design = ModelLoader.load("models/designPattern/Command2.Json"); DataSynchronizationContext dtc = design.getSynchronizationContexts().getFirst(); - //ObjectNode main = dtc.getSrcFirstResource(); - ObjectNode goblin = dtc.getSrcObjectHierarchy().getBottom(); + ObjectNode main = dtc.getDstTopObject(); + ObjectNode wizard = (ObjectNode) dtc.getDstObjectHierarchy().getEdges().get(0).getDestination(); + ObjectNode goblin = dtc.getDstBottomObject(); -// MediatorInsertion mi = new MediatorInsertion(main, goblin, new ObjectNode("Wizard"), dtc.getTransferStyle(), false); +// MediatorInsertion mi = new MediatorInsertion(main, goblin, new ObjectNode("wizard"), dtc.getTransferStyle()); // design.addMediatorInsertion(mi); DependencyInversion di = new DependencyInversion(goblin, new InterfaceNode(goblin, "Target")); diff --git a/src/main/java/designPatternExtensions/designPattern/Observer.java b/src/main/java/designPatternExtensions/designPattern/Observer.java index 89d0c6d..c0fde19 100644 --- a/src/main/java/designPatternExtensions/designPattern/Observer.java +++ b/src/main/java/designPatternExtensions/designPattern/Observer.java @@ -1,6 +1,7 @@ package designPatternExtensions.designPattern; import designPatternExtensions.DependencyInversion; import designPatternExtensions.InterfaceNode; +import designPatternExtensions.MediatorInsertion; import designPatternExtensions.ModelLoader; import models.deltaAlgebra.MultiplicityValue; import models.deltaAlgebra.ObjectNode; @@ -17,7 +18,11 @@ public DataSynchronizationDesign create() throws IllegalRelationException { DataSynchronizationDesign design = ModelLoader.load("models/designPattern/"+this.getClass().getSimpleName()+".Json"); DataSynchronizationContext dtc = design.getSynchronizationContexts().getFirst(); - ObjectNode concreteObserver = (ObjectNode) dtc.getDstObjectHierarchy().getEdge(1).getDestination(); + ObjectNode main = dtc.getDstTopObject(); + ObjectNode concreteObserver = (ObjectNode) dtc.getDstObjectHierarchy().getEdge(0).getDestination(); + +// MediatorInsertion mi = new MediatorInsertion(main, concreteObserver, new ObjectNode("Weather"), dtc.getTransferStyle()); +// design.addMediatorInsertion(mi); DependencyInversion di1 = new DependencyInversion(concreteObserver, new InterfaceNode(concreteObserver, "WeatherObserver")); design.addDependencyInversion(di1); diff --git a/src/main/java/generators/ASTGenerator.java b/src/main/java/generators/ASTGenerator.java index 9b026ff..109e402 100644 --- a/src/main/java/generators/ASTGenerator.java +++ b/src/main/java/generators/ASTGenerator.java @@ -139,26 +139,27 @@ // Construct coordinator method MethodDeclaration coordionator = null; - if (!primitivePullDelta.isMultipleDefinition() || pullEdge1.toMany()) { - coordionator = createMethod(class1, updateMethodPrefix + toComponentName(pullEdge2.getName())); - } else { + if (primitivePullDelta.isMultipleDefinition() && !pullEdge1.toMany() && !primitivePullDelta.isMultipleTransfer()) { coordionator = createMethod(class1, addMethodPrefix + toComponentName(pullEdge2.getName())); + } else { + coordionator = createMethod(class1, updateMethodPrefix + toComponentName(pullEdge2.getName())); } FieldAccess field3 = new FieldAccess(new ThisExpression(), field13.getName()); // this.name3 FieldAccess field2 = new FieldAccess(field12.getName()); List args = new ArrayList<>(); - if (pullEdge2.toMany()) { + if ((!primitivePullDelta.isMultipleDefinition() && pullEdge2.toMany()) + || (primitivePullDelta.isMultipleDefinition() && !pullEdge1.toMany() && !primitivePullDelta.isMultipleTransfer())) { VariableDeclaration idVar = new VariableDeclaration(keyType, pullEdge2.getName() + idPostfix); coordionator.addParameter(idVar); args.add(new Variable(idVar.getName())); // name2.getName3(name3Id) } MethodInvocation callGetter = new MethodInvocation(field2, getter.getName(), args); // name2.getName3() if (!primitivePullDelta.isMultipleDefinition()) { - Assignment assignment = new Assignment(field3, callGetter); // this.name3 = name2.getName3(); + Assignment assignment = new Assignment(field3, callGetter); // this.name3 = name2.getName3(); ExpressionStatement assignmentStatement = new ExpressionStatement(assignment); coordionator.addUniqueStatement(assignmentStatement); } else { - if (!pullEdge1.toMany()) { + if (!pullEdge1.toMany() && !primitivePullDelta.isMultipleTransfer()) { VariableDeclaration idVar = new VariableDeclaration(keyType, pullEdge2.getName() + idPostfix); args = new ArrayList<>(); args.add(new Variable(idVar.getName())); @@ -166,17 +167,34 @@ coordionator.addUniqueStatement(new ExpressionStatement(new MethodInvocation(field3, mapPut, args))); // this.name3Map.put(name3Id, name2.getName3()); } else { EnhancedForStatement collectionLoop = new EnhancedForStatement(); // for (key2 loopVar: name2Map.keySet()) - String loopVarName = pullEdge1.getName() + idPostfix; - keyType = ((MapType) field12.getType()).getKeyType(); + String loopVarName = null; + if (pullEdge1.toMany()) { + loopVarName = pullEdge1.getName() + idPostfix; + keyType = ((MapType) field12.getType()).getKeyType(); + } else { + loopVarName = pullEdge2.getName() + idPostfix; + keyType = ((MapType) field13.getType()).getKeyType(); + } VariableDeclaration loopVar = new VariableDeclaration(keyType, loopVarName); - MethodInvocation keysGetter = new MethodInvocation(field2, mapKeySet); + MethodInvocation keysGetter = null; + if (pullEdge1.toMany()) { + keysGetter = new MethodInvocation(field2, mapKeySet); + } else { + keysGetter = new MethodInvocation(field3, mapKeySet); + } args = new ArrayList<>(); args.add(new Variable(loopVarName)); - MethodInvocation valueGetter = new MethodInvocation(field2, mapGet, args); + if (pullEdge1.toMany()) { + MethodInvocation valueGetter = new MethodInvocation(field2, mapGet, args); + args = new ArrayList<>(); + args.add(new Variable(loopVarName)); + args.add(new MethodInvocation(valueGetter, getter.getName())); + } else { + args = new ArrayList<>(); + args.add(new Variable(loopVarName)); + args.add(new MethodInvocation(field2, getter.getName(), List.of(new Variable(loopVarName)))); + } Block loopBody = new Block(); - args = new ArrayList<>(); - args.add(new Variable(loopVarName)); - args.add(new MethodInvocation(valueGetter, getter.getName())); loopBody.addStatement(new ExpressionStatement(new MethodInvocation(field3, mapPut, args))); // this.name3Map.put(loopVar, name2Map.get(loopVar).getName3()); collectionLoop.setParameter(loopVar); collectionLoop.setExpression(keysGetter); @@ -202,9 +220,16 @@ models.algebra.Type type1 = codebase.getComponentType(name1); models.algebra.Type type2 = codebase.getComponentType(name2); models.algebra.Type type3 = codebase.getComponentType(name3); - FieldDeclaration field12 = createField(class1, pullEdge.getName(), type2); // class1 -> class2 (PULL) + FieldDeclaration field12 = null; + if (!pullEdge.toMany()) { + field12 = createField(class1, pullEdge.getName(), type2); // class1 -> class2 (PULL) + } else { + MapType typeKeyToType2 = codebase.getMapType(pullEdge.getKeyTypeName(), name2); + field12 = createField(class1, pullEdge.getName() + mapPostfix, typeKeyToType2); // class3 -> {class2} (PULL) + } FieldDeclaration field13 = null; models.algebra.Type keyType = null; + models.algebra.Type keyType2 = null; if (!pushEdge.toMany()) { field13 = createField(class1, pushEdge.getName(), type3); // class1 -> class3 (PUSH) } else { @@ -212,52 +237,94 @@ keyType = typeKeyToType3.getKeyType(); field13 = createField(class1, pushEdge.getName() + mapPostfix, typeKeyToType3); // class1 -> {class3} (PUSH) } - FieldDeclaration field32 = createField(class3, pullEdge.getName(), type2); // class3 -> class2 (define) + FieldDeclaration field32 = null; + if (!primitivePullPushDelta.isMultipleDefinition()) { + field32 = createField(class3, pullEdge.getName(), type2); // class3 -> class2 (define) + } else { + MapType typeKeyToType2 = codebase.getMapType(pullEdge.getKeyTypeName(), name2); + keyType2 = typeKeyToType2.getKeyType(); + field32 = createField(class3, pullEdge.getName() + mapPostfix, typeKeyToType2); // class3 -> {class2} (define) + } // Construct setter method MethodDeclaration setter = null; - if (!pushEdge.toMany() || primitivePullPushDelta.isMultipleDefinition()) { - setter = createMethod(class3, setterPrefix + toComponentName(name2)); - } else { + VariableDeclaration param2Id = null; + if (pushEdge.toMany() && !primitivePullPushDelta.isMultipleDefinition() && !primitivePullPushDelta.isMultipleTransfer()) { setter = createConstructor(class3); + } else { + setter = createMethod(class3, setterPrefix + toComponentName(name2)); + if (primitivePullPushDelta.isMultipleDefinition()) { + param2Id = new VariableDeclaration(keyType2, toVariableName(name2) + idPostfix); + setter.addParameter(param2Id); + } } - VariableDeclaration param2 = new VariableDeclaration(type2, toVariableName(name2)); + VariableDeclaration param2 = new VariableDeclaration(type2, toVariableName(pullEdge.getName())); setter.addParameter(param2); - FieldAccess field2 = new FieldAccess(new ThisExpression(), field32.getName()); // this.name2 - Assignment assignment = new Assignment(field2, new Variable(toVariableName(name2))); // this.name2 = name2; - ExpressionStatement assignmentStatement = new ExpressionStatement(assignment); - setter.addUniqueStatement(assignmentStatement); + FieldAccess field2 = new FieldAccess(new ThisExpression(), field32.getName()); + if (primitivePullPushDelta.isMultipleDefinition()) { + List args = new ArrayList<>(); + args.add(new Variable(param2Id.getName())); + args.add(new Variable(toVariableName(name2))); + setter.addUniqueStatement(new ExpressionStatement(new MethodInvocation(field2, mapPut, args))); // name2Map.put(name2Id, name2); + } else { + Assignment assignment = new Assignment(field2, new Variable(toVariableName(pullEdge.getName()))); // this.name2 = name2; + ExpressionStatement assignmentStatement = new ExpressionStatement(assignment); + setter.addUniqueStatement(assignmentStatement); + } // Construct coordinator method MethodDeclaration coordionator = null; - if (!pushEdge.toMany() || primitivePullPushDelta.isMultipleDefinition()) { - coordionator = createMethod(class1, updateMethodPrefix + toComponentName(name3)); - } else { + if (pushEdge.toMany() && !primitivePullPushDelta.isMultipleDefinition() && !primitivePullPushDelta.isMultipleTransfer()) { coordionator = createMethod(class1, addMethodPrefix + toComponentName(name3)); + } else { + coordionator = createMethod(class1, updateMethodPrefix + toComponentName(name3)); } - List args = new ArrayList<>(); - args.add(new FieldAccess(field12.getName())); FieldAccess field3 = new FieldAccess(field13.getName()); - if (!pushEdge.toMany() || primitivePullPushDelta.isMultipleDefinition()) { - if (!primitivePullPushDelta.isMultipleDefinition()) { - MethodInvocation callSetter = new MethodInvocation(field3, setter.getName(), args); // name3.setName2(name2) + if (!pushEdge.toMany() || primitivePullPushDelta.isMultipleDefinition() || primitivePullPushDelta.isMultipleTransfer()) { + if (!primitivePullPushDelta.isMultipleDefinition() && !primitivePullPushDelta.isMultipleTransfer()) { + List args = new ArrayList<>(); + args.add(new FieldAccess(field12.getName())); + MethodInvocation callSetter = new MethodInvocation(field3, setter.getName(), args); // name3.setName2(name2) coordionator.addUniqueStatement(new ExpressionStatement(callSetter)); } else { - EnhancedForStatement broadcastLoop = new EnhancedForStatement(); // for (type3 loopVar: name3Map.values()) - String loopVarName = pushEdge.getName(); - VariableDeclaration loopVar = new VariableDeclaration(type3, loopVarName); - MethodInvocation valuesGetter = new MethodInvocation(field3, mapValues); - MethodInvocation callSetter = new MethodInvocation(new Variable(loopVarName), setter.getName(), args); // loopVar.setName2(name2) + EnhancedForStatement broadcastLoop = new EnhancedForStatement(); // for (key2 loopVar: name2Map.keySet()) + MethodInvocation callSetter = null; + MethodInvocation keysGetter = null; + String loopVarName = null; + List args = new ArrayList<>(); + if (pullEdge.toMany()) { + loopVarName = pullEdge.getName() + idPostfix; + keyType = ((MapType) field12.getType()).getKeyType(); + args.add(new Variable(loopVarName)); + MethodInvocation valueGetter = new MethodInvocation(field2, mapGet, args); + args = new ArrayList<>(); + args.add(new Variable(loopVarName)); + args.add(valueGetter); + callSetter = new MethodInvocation(field3, setter.getName(), args); // name3.setName2(loopVar, name2Map.get(loopVar)) + keysGetter = new MethodInvocation(field2, mapKeySet); + } else { + loopVarName = pushEdge.getName() + idPostfix; + keyType = ((MapType) field13.getType()).getKeyType(); + args.add(new Variable(loopVarName)); + MethodInvocation valueGetter = new MethodInvocation(field3, mapGet, args); + args = new ArrayList<>(); + args.add(field2); + callSetter = new MethodInvocation(valueGetter, setter.getName(), args); // name3Map.get(loopVar).setName2(name2) + keysGetter = new MethodInvocation(field3, mapKeySet); + } Block loopBody = new Block(); loopBody.addStatement(new ExpressionStatement(callSetter)); + VariableDeclaration loopVar = new VariableDeclaration(keyType, loopVarName); broadcastLoop.setParameter(loopVar); - broadcastLoop.setExpression(valuesGetter); + broadcastLoop.setExpression(keysGetter); broadcastLoop.setBody(loopBody); coordionator.addUniqueStatement(broadcastLoop); } } else { VariableDeclaration idVar = new VariableDeclaration(keyType, pushEdge.getName() + idPostfix); coordionator.addParameter(idVar); + List args = new ArrayList<>(); + args.add(new FieldAccess(field12.getName())); ClassInstanceCreation callConstructor = new ClassInstanceCreation((SimpleType) type3.getImplementationType(), args); // new Name3(name2) args = new ArrayList<>(); args.add(new Variable(idVar.getName())); diff --git a/src/main/java/models/dataSynchronizationModel/DataSynchronizationContext.java b/src/main/java/models/dataSynchronizationModel/DataSynchronizationContext.java index 8b941b3..486fb2e 100644 --- a/src/main/java/models/dataSynchronizationModel/DataSynchronizationContext.java +++ b/src/main/java/models/dataSynchronizationModel/DataSynchronizationContext.java @@ -66,6 +66,13 @@ return syncronizationRelation.getDstTopObject(); } + public ObjectNode getSrcBottomObject() { + return syncronizationRelation.getSrcBottomObject(); + } + + public ObjectNode getDstBottomObject() { + return syncronizationRelation.getDstBottomObject(); + } public MultiplicityValue getTransferMultiplicity() { return syncronizationRelation.getMultiplicity(); diff --git a/src/main/java/models/dataSynchronizationModel/DataSynchronizationDesign.java b/src/main/java/models/dataSynchronizationModel/DataSynchronizationDesign.java index 8d8b269..e21fedf 100644 --- a/src/main/java/models/dataSynchronizationModel/DataSynchronizationDesign.java +++ b/src/main/java/models/dataSynchronizationModel/DataSynchronizationDesign.java @@ -109,6 +109,20 @@ } if (!hasDiagonalRelation) { allRelations.add(transferContext.getSyncronizationRelation().getPrevRelation()); + } else { + Relation lastRelation = allRelations.getLast(); + Relation bottomRelation = null; + if (!transferContext.getSrcObjectHierarchy().isPrefixOf(lastRelation.getSrcObjectHierarchy())) { + bottomRelation = new Relation(transferContext.getSrcObjectHierarchy().getPrevObjectHierarchy(), + transferContext.getSrcObjectHierarchy(), + transferContext.getTransferMultiplicity()); + allRelations.add(bottomRelation); + } else if (!transferContext.getDstObjectHierarchy().isPrefixOf(lastRelation.getDstObjectHierarchy())) { + bottomRelation = new Relation(transferContext.getSrcObjectHierarchy(), + transferContext.getDstObjectHierarchy().getPrevObjectHierarchy(), + transferContext.getTransferMultiplicity()); + allRelations.add(bottomRelation); + } } for (Relation relation: allRelations) { ObjectHierarchy newSrcHierarchy = null; @@ -123,6 +137,7 @@ if ((dstHierarchy == null || dstHierarchy.getDepth() < newDstHierarchy.getDepth()) || (srcHierarchy == null || srcHierarchy.getDepth() < newSrcHierarchy.getDepth())) { List oneDestination = new ArrayList<>(); List manyDestinations = new ArrayList<>(); + boolean nextToOne = toOne; for (int i = 0; i < newDstHierarchy.getDepth(); i++) { if (dstHierarchy != null && i < dstHierarchy.getDepth()) { if (!dstHierarchy.getEdge(i).equals(newDstHierarchy.getEdge(i))) { @@ -130,9 +145,9 @@ } } else { if (newDstHierarchy.getEdge(i).toMany()) { - toOne = false; + nextToOne = false; } - if (toOne) { + if (nextToOne) { oneDestination.add(newDstHierarchy.getEdge(i)); } else { manyDestinations.add(newDstHierarchy.getEdge(i)); @@ -164,7 +179,11 @@ String dataName = dstObj.getName(); dataName = dataName.substring(0, 1).toLowerCase() + dataName.substring(1); if (!prevReference.isIdentical() && !prevReference.getDestination().equals(srcEdge.getDestination())) { - primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName)); + if (toOne) { + primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName)); + } else { + primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName, true)); + } Delta delta = null; for (PrimitiveDelta primDelta : primitiveDeltaList) { if (delta == null) { @@ -179,9 +198,10 @@ prevReference = new ReferenceEdge(srcObj, dstObj, dataName); } } + toOne = nextToOne; if (!toOne) { - boolean multipleDefinition = false; + boolean multipleDefinition = false; // destination multiplicity of the defined reference if ((transferStyle == PushPullValue.PUSH && (relation.getMultiplicity() == MultiplicityValue.ManyToOne || relation.getMultiplicity() == MultiplicityValue.OneToOne)) || (transferStyle != PushPullValue.PUSH && (relation.getMultiplicity() == MultiplicityValue.OneToMany || relation.getMultiplicity() == MultiplicityValue.OneToOne))) { // If the specified multiplicity of destination objects does not match to their potential multiplicity, @@ -192,8 +212,8 @@ // then the reference to select one destination object from potential multiple objects is needed. multipleDefinition = true; } - // 2) Create a component identifying delta. - PrimitiveDelta componentSelectingDelta = null; + // 2) Create a component selecting delta. + PrimitivePullDelta componentSelectingDelta = null; for (ReferenceEdge dstEdge : manyDestinations) { if (componentSelectingDelta == null) { srcObj = (ObjectNode) prevReference.getSource(); @@ -212,14 +232,23 @@ } deltaStack.push(delta); // add a component identifying delta primitiveDeltaList.clear(); - prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + if (!multipleDefinition) { + prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + } else { + prevReference = new ReferenceEdge(srcObj, dstObj, dataName, dstEdge.getKeyTypeName()); + } } else { srcObj = (ObjectNode) prevReference.getSource(); dstObj = (ObjectNode) dstEdge.getDestination(); String dataName = dstObj.getName(); dataName = dataName.substring(0, 1).toLowerCase() + dataName.substring(1); - primitiveDeltaList.add(new PrimitivePullDelta(prevReference, dstEdge, dataName, multipleDefinition)); - prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + componentSelectingDelta = new PrimitivePullDelta(prevReference, dstEdge, dataName, multipleDefinition); + primitiveDeltaList.add(componentSelectingDelta); + if (!multipleDefinition) { + prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + } else { + prevReference = new ReferenceEdge(srcObj, dstObj, dataName, dstEdge.getKeyTypeName()); + } } } } @@ -257,19 +286,31 @@ String dataName = transferContext.getDataName(); ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); PrimitivePullPushDelta primDelta = new PrimitivePullPushDelta(dataEdge, prevReference, dataName); // PUSH data transfer + if (transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.OneToMany + || transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.ManyToMany) { + primDelta.setMultipleTransfer(true); + } dataTransferDelta = new Delta(primDelta); } else { // Broadcasting prevReference = new ReferenceEdge(prevReference); prevReference.setKeyTypeName(transferContext.getDstObjectHierarchy().getEdges().getLast().getKeyTypeName()); - prevReference.setMultiplicity(MultiplicityValue.OneToMany); +// prevReference.setMultiplicity(MultiplicityValue.OneToMany); // Add the data transfer delta. srcObj = (ObjectNode) prevReference.getSource(); dstObj = (ObjectNode) transferContext.getSrcObjectHierarchy().getBottom(); String dataName = transferContext.getDataName(); ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); - PrimitivePullPushDelta primDelta = new PrimitivePullPushDelta(dataEdge, prevReference, dataName, true); // PUSH data transfer + PrimitivePullPushDelta primDelta = new PrimitivePullPushDelta(dataEdge, prevReference, dataName); // PUSH data transfer + if (transferContext.getDstObjectHierarchy().getEdges().getLast().getMultiplicity() == MultiplicityValue.OneToMany + || transferContext.getDstObjectHierarchy().getEdges().getLast().getMultiplicity() == MultiplicityValue.ManyToMany) { + primDelta.setMultipleDefinition(true); + } + if (transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.OneToMany + || transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.ManyToMany) { + primDelta.setMultipleTransfer(true); + } dataTransferDelta = new Delta(primDelta); } } else { @@ -283,12 +324,16 @@ String dataName = transferContext.getDataName(); ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); PrimitivePullDelta primDelta = new PrimitivePullDelta(prevReference, dataEdge, dataName); // PULL data transfer + if (transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.ManyToOne + || transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.ManyToMany) { + primDelta.setMultipleTransfer(true); + } dataTransferDelta = new Delta(primDelta); } else { // Data collecting prevReference = new ReferenceEdge(prevReference); prevReference.setKeyTypeName(transferContext.getSrcObjectHierarchy().getEdges().getLast().getKeyTypeName()); - prevReference.setMultiplicity(MultiplicityValue.OneToMany); +// prevReference.setMultiplicity(MultiplicityValue.OneToMany); // Add the data transfer delta. srcObj = (ObjectNode) prevReference.getDestination(); @@ -296,6 +341,10 @@ String dataName = transferContext.getDataName(); ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); PrimitivePullDelta primDelta = new PrimitivePullDelta(prevReference, dataEdge, dataName, true); // PULL data transfer + if (transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.ManyToOne + || transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.ManyToMany) { + primDelta.setMultipleTransfer(true); + } dataTransferDelta = new Delta(primDelta); } } diff --git a/src/main/java/models/dataSynchronizationModel/Relation.java b/src/main/java/models/dataSynchronizationModel/Relation.java index b7abb85..5ecfc46 100644 --- a/src/main/java/models/dataSynchronizationModel/Relation.java +++ b/src/main/java/models/dataSynchronizationModel/Relation.java @@ -64,10 +64,18 @@ return srcObjectHierarchy.getTop(); } + public ObjectNode getSrcBottomObject() { + return srcObjectHierarchy.getBottom(); + } + public ObjectNode getDstTopObject() { return dstObjectHierarchy.getTop(); } + public ObjectNode getDstBottomObject() { + return dstObjectHierarchy.getBottom(); + } + public MultiplicityValue getMultiplicity() { return multiplicity; } diff --git a/src/main/java/models/deltaAlgebra/PrimitivePullDelta.java b/src/main/java/models/deltaAlgebra/PrimitivePullDelta.java index bfbbd58..04b7e2f 100644 --- a/src/main/java/models/deltaAlgebra/PrimitivePullDelta.java +++ b/src/main/java/models/deltaAlgebra/PrimitivePullDelta.java @@ -8,6 +8,7 @@ private ReferenceEdge pullEdge1 = null; private ReferenceEdge pullEdge2 = null; private boolean multipleDefinition = false; + private boolean multipleTransfer = false; public PrimitivePullDelta(ReferenceEdge pullEdge1, ReferenceEdge pullEdge2, String dataName) { super(dataName); @@ -22,6 +23,14 @@ this.multipleDefinition = multipleDefinition; } + public PrimitivePullDelta(ReferenceEdge pullEdge1, ReferenceEdge pullEdge2, String dataName, boolean multipleDefinition, boolean multipleTransfer) { + super(dataName); + this.pullEdge1 = pullEdge1; + this.pullEdge2 = pullEdge2; + this.multipleDefinition = multipleDefinition; + this.multipleTransfer = multipleTransfer; + } + @Override public ObjectNode getCoordinator() { return (ObjectNode) pullEdge1.getSource(); @@ -63,9 +72,17 @@ return multipleDefinition; } + public boolean isMultipleTransfer() { + return multipleTransfer; + } + + public void setMultipleTransfer(boolean multipleTransfer) { + this.multipleTransfer = multipleTransfer; + } + @Override public PrimitivePullDelta copy() { - return new PrimitivePullDelta(pullEdge1, pullEdge2, dataName, multipleDefinition); + return new PrimitivePullDelta(pullEdge1, pullEdge2, dataName, multipleDefinition, multipleTransfer); } @Override diff --git a/src/main/java/models/deltaAlgebra/PrimitivePullPushDelta.java b/src/main/java/models/deltaAlgebra/PrimitivePullPushDelta.java index 8fba5de..4158392 100644 --- a/src/main/java/models/deltaAlgebra/PrimitivePullPushDelta.java +++ b/src/main/java/models/deltaAlgebra/PrimitivePullPushDelta.java @@ -8,6 +8,7 @@ private ReferenceEdge pullEdge = null; private ReferenceEdge pushEdge = null; private boolean multipleDefinition = false; + private boolean multipleTransfer = false; public PrimitivePullPushDelta(ReferenceEdge pullEdge, ReferenceEdge pushEdge, String dataName) { super(dataName); @@ -22,6 +23,14 @@ this.multipleDefinition = multipleDefinition; } + public PrimitivePullPushDelta(ReferenceEdge pullEdge, ReferenceEdge pushEdge, String dataName, boolean multipleDefinition, boolean multipleTransfer) { + super(dataName); + this.pullEdge = pullEdge; + this.pushEdge = pushEdge; + this.multipleDefinition = multipleDefinition; + this.multipleTransfer = multipleTransfer; + } + @Override public ObjectNode getCoordinator() { return (ObjectNode) pushEdge.getSource(); @@ -63,9 +72,21 @@ return multipleDefinition; } + public void setMultipleDefinition(boolean multipleDefinition) { + this.multipleDefinition = multipleDefinition; + } + + public boolean isMultipleTransfer() { + return multipleTransfer; + } + + public void setMultipleTransfer(boolean multipleTransfer) { + this.multipleTransfer = multipleTransfer; + } + @Override public PrimitivePullPushDelta copy() { - return new PrimitivePullPushDelta(pullEdge, pushEdge, dataName, multipleDefinition); + return new PrimitivePullPushDelta(pullEdge, pushEdge, dataName, multipleDefinition, multipleTransfer); } @Override