diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 41e4dc2..610356b 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -9,14 +9,16 @@ public static void main(String[] args) { List srcEdges = new ArrayList<>(); List dstEdges = new ArrayList<>(); - ObjectNode companies = new ObjectNode("companies"); - ObjectNode company = new ObjectNode("company"); - ObjectNode customers = new ObjectNode("customers"); - ObjectNode customer = new ObjectNode("customer"); - ObjectNode address = new ObjectNode("string"); - ReferenceEdge srcEdge = new ReferenceEdge(companies, company, "company", MultiplicityValue.OneToMany); + ObjectNode companies = new ObjectNode("Companies"); + ObjectNode company = new ObjectNode("Company"); + ObjectNode customers = new ObjectNode("Customers"); + ObjectNode customer = new ObjectNode("Customer"); + ObjectNode address = new ObjectNode("String"); +// ReferenceEdge srcEdge = new ReferenceEdge(companies, company, "company"); + ReferenceEdge srcEdge = new ReferenceEdge(companies, company, "company", "String"); srcEdges.add(srcEdge); - ReferenceEdge dstEdge = new ReferenceEdge(customers, customer, "customer", MultiplicityValue.OneToMany); +// ReferenceEdge dstEdge = new ReferenceEdge(customers, customer, "customer"); + ReferenceEdge dstEdge = new ReferenceEdge(customers, customer, "customer", "String"); dstEdges.add(dstEdge); List relations = new ArrayList<>(); Relation transferRelation = new Relation(srcEdges, dstEdges, MultiplicityValue.OneToMany); diff --git a/src/main/java/generators/ASTGenerator.java b/src/main/java/generators/ASTGenerator.java index 5acd940..8ed2456 100644 --- a/src/main/java/generators/ASTGenerator.java +++ b/src/main/java/generators/ASTGenerator.java @@ -4,12 +4,18 @@ import java.util.List; import ast.*; +import models.algebra.Type; +import models.dataConstraintModel.MapType; import models.objectOrientedTransfer.*; public class ASTGenerator { public static final String getterPrefix = "get"; public static final String setterPrefix = "set"; public static final String updateMethodPrefix = "update"; + public static final String idPostfix = "Id"; + public static final String mapPostfix = "Map"; + public static final String mapGet = "get"; + public static final String mapPut = "put"; public static String toComponentName(String name) { return name.substring(0, 1).toUpperCase() + name.substring(1); @@ -40,123 +46,182 @@ public static Codebase weavePrimitiveDelta(Codebase codebase, PrimitiveDelta primitiveDelta) { if (primitiveDelta instanceof PrimitivePullDelta) { - PrimitivePullDelta primitivePullDelta = (PrimitivePullDelta) primitiveDelta; - ReferenceEdge pullEdge1 = primitivePullDelta.getPullEdge1(); - ReferenceEdge pullEdge2 = primitivePullDelta.getPullEdge2(); - ObjectNode obj1 = (ObjectNode) pullEdge1.getSource(); - ObjectNode obj2 = (ObjectNode) pullEdge1.getDestination(); - ObjectNode obj3 = (ObjectNode) pullEdge2.getDestination(); - String name1 = toComponentName(obj1.getName()); - String name2 = toComponentName(obj2.getName()); - String name3 = toComponentName(obj3.getName()); - TypeDeclaration class1 = createClass(codebase, name1); - TypeDeclaration class2 = createClass(codebase, name2); - TypeDeclaration class3 = createClass(codebase, name3); - 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, pullEdge1.getName(), type2); // class1 -> class2 (PULL) - FieldDeclaration field23 = createField(class2, pullEdge2.getName(), type3); // class2 -> class3 (PULL) - FieldDeclaration field13 = createField(class1, pullEdge2.getName(), type3); // class1 -> class3 (create) - - // Construct getter method - MethodDeclaration getter = createMethod(class2, getterPrefix + toComponentName(pullEdge2.getName())); - ReturnStatement return23 = new ReturnStatement(); - return23.setExpression(new FieldAccess(new ThisExpression(), field23.getName())); // return this.name3; - getter.addStatement(return23); - getter.setReturnType(type3); - - // Construct coordinator method - MethodDeclaration coordionator = createMethod(class1, getterPrefix + toComponentName(pullEdge2.getName())); - FieldAccess field3 = new FieldAccess(new ThisExpression(), field13.getName()); // this.name3 - FieldAccess field2 = new FieldAccess(field12.getName()); - MethodInvocation callGetter = new MethodInvocation(field2, getter.getName()); // name2.getName3() - Assignment assignment = new Assignment(field3, callGetter); // this.name3 = name2.getName3(); - ExpressionStatement assignmentStatement = new ExpressionStatement(assignment); - coordionator.addStatement(assignmentStatement); + codebase = weavePrimitivePullDelta(codebase, (PrimitivePullDelta) primitiveDelta); } else if (primitiveDelta instanceof PrimitivePullPushDelta) { - PrimitivePullPushDelta primitivePullPushDelta = (PrimitivePullPushDelta) primitiveDelta; - ReferenceEdge pullEdge = primitivePullPushDelta.getPullEdge(); - ReferenceEdge pushEdge = primitivePullPushDelta.getPushEdge(); - ObjectNode obj1 = (ObjectNode) pullEdge.getSource(); - ObjectNode obj2 = (ObjectNode) pullEdge.getDestination(); - ObjectNode obj3 = (ObjectNode) pushEdge.getDestination(); - String name1 = toComponentName(obj1.getName()); - String name2 = toComponentName(obj2.getName()); - String name3 = toComponentName(obj3.getName()); - TypeDeclaration class1 = createClass(codebase, name1); - TypeDeclaration class2 = createClass(codebase, name2); - TypeDeclaration class3 = createClass(codebase, name3); - 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 field13 = createField(class1, pushEdge.getName(), type3); // class1 -> class3 (PUSH) - FieldDeclaration field32 = createField(class3, pullEdge.getName(), type2); // class3 -> class2 (create) - - // Construct setter method - MethodDeclaration setter = createMethod(class3, setterPrefix + toComponentName(name2)); - VariableDeclaration param2 = new VariableDeclaration(type2, name2); - 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.addStatement(assignmentStatement); - - // Construct coordinator method - MethodDeclaration coordionator = createMethod(class1, updateMethodPrefix + toComponentName(name2)); - FieldAccess field3 = new FieldAccess(field13.getName()); - List args = new ArrayList<>(); - args.add(new FieldAccess(field12.getName())); - MethodInvocation callSetter = new MethodInvocation(field3, setter.getName(), args); // name3.setName2(name2) - coordionator.addStatement(new ExpressionStatement(callSetter)); + codebase = weavePrimitivePullPushDelta(codebase, (PrimitivePullPushDelta) primitiveDelta); } else if (primitiveDelta instanceof PrimitivePushDelta) { - PrimitivePushDelta primitivePushDelta = (PrimitivePushDelta) primitiveDelta; - ReferenceEdge pushEdge1 = primitivePushDelta.getPushEdge1(); - ReferenceEdge pushEdge2 = primitivePushDelta.getPushEdge2(); - ObjectNode obj1 = (ObjectNode) pushEdge1.getSource(); - ObjectNode obj2 = (ObjectNode) pushEdge1.getDestination(); - ObjectNode obj3 = (ObjectNode) pushEdge2.getDestination(); - String name1 = toComponentName(obj1.getName()); - String name2 = toComponentName(obj2.getName()); - String name3 = toComponentName(obj3.getName()); - TypeDeclaration class1 = createClass(codebase, name1); - TypeDeclaration class2 = createClass(codebase, name2); - TypeDeclaration class3 = createClass(codebase, name3); - 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, pushEdge1.getName(), type2); // class1 -> class2 (PUSH) - FieldDeclaration field23 = createField(class2, pushEdge2.getName(), type3); // class2 -> class3 (PUSH) - FieldDeclaration field31 = createField(class3, toVariableName(name1), type1); // class3 -> class1 (create) - - // Construct setter in class3 - MethodDeclaration setter3 = createMethod(class3, setterPrefix + toComponentName(name1)); - VariableDeclaration param1 = new VariableDeclaration(type1, name1); - setter3.addParameter(param1); - FieldAccess field1 = new FieldAccess(new ThisExpression(), field31.getName()); // this.name1 - Assignment assignment = new Assignment(field1, new Variable(toVariableName(name1))); // this.name1 = name1; - ExpressionStatement assignmentStatement = new ExpressionStatement(assignment); - setter3.addStatement(assignmentStatement); + codebase = weavePrimitivePushDelta(codebase, (PrimitivePushDelta) primitiveDelta); + } + return codebase; + } - // Construct setter in class2 - MethodDeclaration setter2 = createMethod(class2, setterPrefix + toComponentName(name1)); - param1 = new VariableDeclaration(type1, toVariableName(name1)); - setter2.addParameter(param1); + private static Codebase weavePrimitivePullDelta(Codebase codebase, PrimitivePullDelta primitivePullDelta) { + ReferenceEdge pullEdge1 = primitivePullDelta.getPullEdge1(); + ReferenceEdge pullEdge2 = primitivePullDelta.getPullEdge2(); + ObjectNode obj1 = (ObjectNode) pullEdge1.getSource(); + ObjectNode obj2 = (ObjectNode) pullEdge1.getDestination(); + ObjectNode obj3 = (ObjectNode) pullEdge2.getDestination(); + String name1 = toComponentName(obj1.getName()); + String name2 = toComponentName(obj2.getName()); + String name3 = toComponentName(obj3.getName()); + TypeDeclaration class1 = createClass(codebase, name1); + TypeDeclaration class2 = createClass(codebase, name2); + TypeDeclaration class3 = createClass(codebase, name3); + 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, pullEdge1.getName(), type2); // class1 -> class2 (PULL) + FieldDeclaration field23 = null; + models.algebra.Type keyType = null; + if (!pullEdge2.toMany()) { + field23 = createField(class2, pullEdge2.getName(), type3); // class2 -> class3 (PULL) + } else { + MapType typeKeyToType3 = codebase.getMapType(pullEdge2.getKeyTypeName(), name3); + keyType = typeKeyToType3.getKeyType(); + field23 = createField(class2, pullEdge2.getName() + mapPostfix, typeKeyToType3); // class2 -> {class3} (PULL) + } + FieldDeclaration field13 = createField(class1, pullEdge2.getName(), type3); // class1 -> class3 (create) + + // Construct getter method + MethodDeclaration getter = createMethod(class2, getterPrefix + toComponentName(pullEdge2.getName())); + ReturnStatement return23 = new ReturnStatement(); + if (!pullEdge2.toMany()) { + return23.setExpression(new FieldAccess(new ThisExpression(), field23.getName())); // return this.name3; + } else { + VariableDeclaration idVar = new VariableDeclaration(keyType, pullEdge2.getName() + idPostfix); + getter.addParameter(idVar); FieldAccess field3 = new FieldAccess(field23.getName()); List args = new ArrayList<>(); - args.add(new Variable(param1.getName())); - MethodInvocation callSetter = new MethodInvocation(field3, setter3.getName(), args); // name3.setName1(name1) - setter2.addStatement(new ExpressionStatement(callSetter)); - - // Construct coordinator method - MethodDeclaration coordionator = createMethod(class1, updateMethodPrefix + toComponentName(name1)); - FieldAccess field2 = new FieldAccess(field12.getName()); - args = new ArrayList<>(); - args.add(new ThisExpression()); - callSetter = new MethodInvocation(field2, setter2.getName(), args); // name2.setName1(this) - coordionator.addStatement(new ExpressionStatement(callSetter)); + args.add(new Variable(idVar.getName())); + MethodInvocation callGetter = new MethodInvocation(field3, mapGet, args); // name3Map.get(name3Id) + return23.setExpression(callGetter); // return name3Map.get(name3Id); } + getter.addStatement(return23); + getter.setReturnType(type3); + + // Construct coordinator method + MethodDeclaration 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()) { + 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() + Assignment assignment = new Assignment(field3, callGetter); // this.name3 = name2.getName3(); + ExpressionStatement assignmentStatement = new ExpressionStatement(assignment); + coordionator.addStatement(assignmentStatement); + return codebase; + } + + private static Codebase weavePrimitivePullPushDelta(Codebase codebase, PrimitivePullPushDelta primitivePullPushDelta) { + ReferenceEdge pullEdge = primitivePullPushDelta.getPullEdge(); + ReferenceEdge pushEdge = primitivePullPushDelta.getPushEdge(); + ObjectNode obj1 = (ObjectNode) pullEdge.getSource(); + ObjectNode obj2 = (ObjectNode) pullEdge.getDestination(); + ObjectNode obj3 = (ObjectNode) pushEdge.getDestination(); + String name1 = toComponentName(obj1.getName()); + String name2 = toComponentName(obj2.getName()); + String name3 = toComponentName(obj3.getName()); + TypeDeclaration class1 = createClass(codebase, name1); + TypeDeclaration class2 = createClass(codebase, name2); + TypeDeclaration class3 = createClass(codebase, name3); + 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 field13 = null; + models.algebra.Type keyType = null; + if (!pushEdge.toMany()) { + field13 = createField(class1, pushEdge.getName(), type3); // class1 -> class3 (PUSH) + } else { + MapType typeKeyToType3 = codebase.getMapType(pushEdge.getKeyTypeName(), name3); + keyType = typeKeyToType3.getKeyType(); + field13 = createField(class1, pushEdge.getName() + mapPostfix, typeKeyToType3); // class1 -> {class3} (PUSH) + } + FieldDeclaration field32 = createField(class3, pullEdge.getName(), type2); // class3 -> class2 (create) + + // Construct setter method + MethodDeclaration setter = null; + if (!pushEdge.toMany()) { + setter = createMethod(class3, setterPrefix + toComponentName(name2)); + } else { + setter = createConstructor(class3); + } + VariableDeclaration param2 = new VariableDeclaration(type2, toVariableName(name2)); + 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.addStatement(assignmentStatement); + + // Construct coordinator method + MethodDeclaration coordionator = createMethod(class1, updateMethodPrefix + toComponentName(name2)); + List args = new ArrayList<>(); + args.add(new FieldAccess(field12.getName())); + FieldAccess field3 = new FieldAccess(field13.getName()); + if (!pushEdge.toMany()) { + MethodInvocation callSetter = new MethodInvocation(field3, setter.getName(), args); // name3.setName2(name2) + coordionator.addStatement(new ExpressionStatement(callSetter)); + } else { + VariableDeclaration idVar = new VariableDeclaration(keyType, pushEdge.getName() + idPostfix); + coordionator.addParameter(idVar); + ClassInstanceCreation callConstructor = new ClassInstanceCreation((SimpleType) type3.getImplementationType(), args); // new Name3(name2) + args = new ArrayList<>(); + args.add(new Variable(idVar.getName())); + args.add(callConstructor); + coordionator.addStatement(new ExpressionStatement(new MethodInvocation(field3, mapPut, args))); // name3Map.put(name3Id, new new Name3(name2)); + } + return codebase; + } + + private static Codebase weavePrimitivePushDelta(Codebase codebase, PrimitivePushDelta primitivePushDelta) { + ReferenceEdge pushEdge1 = primitivePushDelta.getPushEdge1(); + ReferenceEdge pushEdge2 = primitivePushDelta.getPushEdge2(); + ObjectNode obj1 = (ObjectNode) pushEdge1.getSource(); + ObjectNode obj2 = (ObjectNode) pushEdge1.getDestination(); + ObjectNode obj3 = (ObjectNode) pushEdge2.getDestination(); + String name1 = toComponentName(obj1.getName()); + String name2 = toComponentName(obj2.getName()); + String name3 = toComponentName(obj3.getName()); + TypeDeclaration class1 = createClass(codebase, name1); + TypeDeclaration class2 = createClass(codebase, name2); + TypeDeclaration class3 = createClass(codebase, name3); + 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, pushEdge1.getName(), type2); // class1 -> class2 (PUSH) + FieldDeclaration field23 = createField(class2, pushEdge2.getName(), type3); // class2 -> class3 (PUSH) + FieldDeclaration field31 = createField(class3, toVariableName(name1), type1); // class3 -> class1 (create) + + // Construct setter in class3 + MethodDeclaration setter3 = createMethod(class3, setterPrefix + toComponentName(name1)); + VariableDeclaration param1 = new VariableDeclaration(type1, name1); + setter3.addParameter(param1); + FieldAccess field1 = new FieldAccess(new ThisExpression(), field31.getName()); // this.name1 + Assignment assignment = new Assignment(field1, new Variable(toVariableName(name1))); // this.name1 = name1; + ExpressionStatement assignmentStatement = new ExpressionStatement(assignment); + setter3.addStatement(assignmentStatement); + + // Construct setter in class2 + MethodDeclaration setter2 = createMethod(class2, setterPrefix + toComponentName(name1)); + param1 = new VariableDeclaration(type1, toVariableName(name1)); + setter2.addParameter(param1); + FieldAccess field3 = new FieldAccess(field23.getName()); + List args = new ArrayList<>(); + args.add(new Variable(param1.getName())); + MethodInvocation callSetter = new MethodInvocation(field3, setter3.getName(), args); // name3.setName1(name1) + setter2.addStatement(new ExpressionStatement(callSetter)); + + // Construct coordinator method + MethodDeclaration coordionator = createMethod(class1, updateMethodPrefix + toComponentName(name1)); + FieldAccess field2 = new FieldAccess(field12.getName()); + args = new ArrayList<>(); + args.add(new ThisExpression()); + callSetter = new MethodInvocation(field2, setter2.getName(), args); // name2.setName1(this) + coordionator.addStatement(new ExpressionStatement(callSetter)); return codebase; } @@ -177,6 +242,15 @@ return method; } + private static MethodDeclaration createConstructor(TypeDeclaration type) { + for (MethodDeclaration method: type.getMethods()) { + if (method.getName().equals(type.getTypeName())) return method; + } + MethodDeclaration method = new MethodDeclaration(type.getTypeName(), true); // constructor + type.addMethod(method); + return method; + } + private static FieldDeclaration createField(TypeDeclaration type, String fieldName, models.algebra.Type fieldType) { for (FieldDeclaration field: type.getFields()) { if (field.getName().equals(fieldName)) return field; diff --git a/src/main/java/generators/Codebase.java b/src/main/java/generators/Codebase.java index 031e474..2b5ae0f 100644 --- a/src/main/java/generators/Codebase.java +++ b/src/main/java/generators/Codebase.java @@ -7,14 +7,14 @@ import ast.CompilationUnit; import ast.SimpleType; import models.algebra.Type; +import models.dataConstraintModel.MapType; public class Codebase { - private Map classes; - private Map componentTypes; + private Map classes = new HashMap<>(); + private Map componentTypes = new HashMap<>(); + private Map standardTypes = new HashMap<>(); public Codebase() { - classes = new HashMap<>(); - componentTypes = new HashMap<>(); } public Collection getCompilationUnits() { @@ -25,13 +25,31 @@ return classes.get(name); } - public Type getComponentType(String name) { - return componentTypes.get(name); + public models.algebra.Type getComponentType(String typeName) { + return componentTypes.get(typeName); } + public models.algebra.Type getOrCreateStandardType(String typeName) { + models.algebra.Type type = standardTypes.get(typeName); + if (type == null) { + type = new models.algebra.Type(typeName, new SimpleType(typeName)); + standardTypes.put(typeName, type); + } + return type; + } + + public MapType getMapType(String keyTypeName, String valueTypeName) { + models.algebra.Type valueType = componentTypes.get(valueTypeName); + if (valueType == null) { + valueType = getOrCreateStandardType(valueTypeName); + } + models.algebra.Type keyType = getOrCreateStandardType(keyTypeName); + return new MapType("map", new SimpleType("HashMap<>"), new SimpleType("Map<" + keyTypeName + ", " + valueTypeName + ">"), keyType, valueType); + } + public void addCompilationUnit(String name, CompilationUnit compilationUnit) { classes.put(name, compilationUnit); - Type newType = new Type(name, new SimpleType(name)); + models.algebra.Type newType = new models.algebra.Type(name, new SimpleType(name)); componentTypes.put(name, newType); } diff --git a/src/main/java/models/dataConstraintModel/MapType.java b/src/main/java/models/dataConstraintModel/MapType.java new file mode 100644 index 0000000..b9f3233 --- /dev/null +++ b/src/main/java/models/dataConstraintModel/MapType.java @@ -0,0 +1,49 @@ +package models.dataConstraintModel; + +import models.algebra.Type; + +public class MapType extends Type { + protected Type keyType = null; + protected Type valueType = null; + + public MapType(String typeName, ITypeImpl implementationType) { + super(typeName, implementationType); + } + + public MapType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType) { + super(typeName, implementationType, interfaceType); + } + + public MapType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type parentMapType) { + super(typeName, implementationType, interfaceType, parentMapType); + } + + public MapType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type keyType, Type valueType) { + super(typeName, implementationType, interfaceType); + this.keyType = keyType; + this.valueType = valueType; + } + + public MapType(String typeName, ITypeImpl implementationType, ITypeImpl interfaceType, Type parentMapType, Type keyType, Type valueType) { + super(typeName, implementationType, interfaceType, parentMapType); + this.keyType = keyType; + this.valueType = valueType; + } + + public Type getKeyType() { + return keyType; + } + + public void setKeyType(Type keyType) { + this.keyType = keyType; + } + + public Type getValueType() { + return valueType; + } + + public void setValueType(Type valueType) { + this.valueType = valueType; + } + +} diff --git a/src/main/java/models/objectOrientedTransfer/DataTransferDesign.java b/src/main/java/models/objectOrientedTransfer/DataTransferDesign.java index 6297026..a650dac 100644 --- a/src/main/java/models/objectOrientedTransfer/DataTransferDesign.java +++ b/src/main/java/models/objectOrientedTransfer/DataTransferDesign.java @@ -114,7 +114,7 @@ throw new IllegalRelationException(); } } else { - if (newDstResource.get(i).getMultiplicity() == MultiplicityValue.OneToMany) { + if (newDstResource.get(i).toMany()) { toOne = false; } if (toOne) { @@ -124,48 +124,49 @@ } } } + + // 1) Create container passing deltas. + List primitiveDeltaList = new ArrayList<>(); + for (ReferenceEdge dstEdge: oneDestination) { + 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)); + prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + } + for (int i = 0; i < newSrcResource.size(); i++) { + ReferenceEdge srcEdge = newSrcResource.get(i); + if (i < srcResource.size()) { + if (!srcResource.get(i).equals(srcEdge)) { + throw new IllegalRelationException(); + } + } else { + srcObj = (ObjectNode) srcEdge.getDestination(); + dstObj = (ObjectNode) prevReference.getDestination(); + String dataName = dstObj.getName(); + dataName = dataName.substring(0, 1).toLowerCase() + dataName.substring(1); + primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName)); + Delta delta = null; + for (PrimitiveDelta primDelta: primitiveDeltaList) { + if (delta == null) { + delta = new Delta(primDelta); + } else { + delta = new Delta(primDelta, delta); + } + } + deltaStack.push(delta); // add a container passing delta + primitiveDeltaList.clear(); + prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + } + } + if (!toOne && ((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, // then the reference to select one destination object from potential multiple objects is needed. - // 1) Create container passing deltas. - List primitiveDeltaList = new ArrayList<>(); - for (ReferenceEdge dstEdge: oneDestination) { - 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)); - prevReference = new ReferenceEdge(srcObj, dstObj, dataName); - } - for (int i = 0; i < newSrcResource.size(); i++) { - ReferenceEdge srcEdge = newSrcResource.get(i); - if (i < srcResource.size()) { - if (!srcResource.get(i).equals(srcEdge)) { - throw new IllegalRelationException(); - } - } else { - srcObj = (ObjectNode) srcEdge.getDestination(); - dstObj = (ObjectNode) prevReference.getDestination(); - String dataName = dstObj.getName(); - dataName = dataName.substring(0, 1).toLowerCase() + dataName.substring(1); - primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName)); - Delta delta = null; - for (PrimitiveDelta primDelta: primitiveDeltaList) { - if (delta == null) { - delta = new Delta(primDelta); - } else { - delta = new Delta(primDelta, delta); - } - } - deltaStack.push(delta); // add a container passing delta - primitiveDeltaList.clear(); - prevReference = new ReferenceEdge(srcObj, dstObj, dataName); - } - } - // 2) Create a component identifying delta. PrimitiveDelta componentSelectingDelta = null; for (ReferenceEdge dstEdge: manyDestinations) { diff --git a/src/main/java/models/objectOrientedTransfer/DeltaComplex.java b/src/main/java/models/objectOrientedTransfer/DeltaComplex.java index 7f7751d..f301548 100644 --- a/src/main/java/models/objectOrientedTransfer/DeltaComplex.java +++ b/src/main/java/models/objectOrientedTransfer/DeltaComplex.java @@ -49,6 +49,17 @@ return deltaSequence; } + public DeltaComplex flatten() { + DeltaComplex flattenComplex = subComplex; + if (flattenComplex != null) { + flattenComplex = flattenComplex.flatten(); + } + for (PrimitiveDelta primDelta: frontierDelta.split().reversed()) { + flattenComplex = new DeltaComplex(new Delta(primDelta), flattenComplex); + } + return flattenComplex; + } + public Delta collapse() { Delta allDelta = null; for (Delta delta: this.split()) { diff --git a/src/main/java/models/objectOrientedTransfer/ReferenceEdge.java b/src/main/java/models/objectOrientedTransfer/ReferenceEdge.java index 6337ce9..07e73f8 100644 --- a/src/main/java/models/objectOrientedTransfer/ReferenceEdge.java +++ b/src/main/java/models/objectOrientedTransfer/ReferenceEdge.java @@ -5,6 +5,7 @@ public class ReferenceEdge extends Edge { protected String name; protected MultiplicityValue multiplicity; + protected String keyTypeName = null; public ReferenceEdge(ObjectNode src, ObjectNode dst, String name) { super(src, dst); @@ -17,6 +18,13 @@ this.name = name; this.multiplicity = multiplicity; } + + public ReferenceEdge(ObjectNode src, ObjectNode dst, String name, String keyTypeName) { + super(src, dst); + this.name = name; + this.multiplicity = MultiplicityValue.OneToMany; + this.keyTypeName = keyTypeName; + } public String getName() { return name; @@ -33,5 +41,12 @@ public void setMultiplicity(MultiplicityValue multiplicity) { this.multiplicity = multiplicity; } + + public boolean toMany() { + return multiplicity == MultiplicityValue.OneToMany || multiplicity == MultiplicityValue.ManyToMany; + } + public String getKeyTypeName() { + return keyTypeName; + } }