diff --git a/models/CustomerManagement-PULL.Json b/models/CustomerManagement-PULL.Json new file mode 100644 index 0000000..3fc8821 --- /dev/null +++ b/models/CustomerManagement-PULL.Json @@ -0,0 +1,15 @@ +{ + "name" : "CustomerManagement", + "contexts" : [ + { + "relations": [], + "transfer": { + "src": "companies.{company}.String", + "dst": "customers.{customer}.String", + "data": {"name": "address"}, + "style": "PULL", + "multiplicity": "1:*" + } + } + ] +} \ No newline at end of file diff --git a/models/CustomerManagement-PUSH.Json b/models/CustomerManagement-PUSH.Json new file mode 100644 index 0000000..bf420fb --- /dev/null +++ b/models/CustomerManagement-PUSH.Json @@ -0,0 +1,21 @@ +{ + "name" : "CustomerManagement", + "contexts" : [ + { + "relations": [ + { + "src": "companies.{company}", + "dst": "customers", + "multiplicity": "*:1" + } + ], + "transfer": { + "src": "companies.{company}.String", + "dst": "customers.{customer}.String", + "data": {"name": "address"}, + "style": "PUSH", + "multiplicity": "1:*" + } + } + ] +} \ No newline at end of file diff --git a/models/CustomerManagement.Json b/models/CustomerManagement.Json deleted file mode 100644 index 59e6c0e..0000000 --- a/models/CustomerManagement.Json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name" : "CustomerManagement", - "contexts" : [ - { - "relations": [], - "transfer": { - "src": "Companies.{company}.String", - "dst": "customers.{customer}.String", - "data": {"name": "address"}, - "style": "PULL", - "multiplicity": "1:*" - } - } - ] -} \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 451a648..4681cfd 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -29,12 +29,15 @@ dstEdges.add(dstEdge2); List relations = new ArrayList<>(); 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; + design = ModelLoader.load("models/CustomerManagement-PUSH.Json"); + System.out.println(design.getDeltaComplex()); + System.out.println(ASTGenerator.generate(design)); + try { - design = new DataSynchronizationDesign(context); +// DataSynchronizationContext context = new DataSynchronizationContext(relations, transferRelation, "address", PushPullValue.PULL); +// design = new DataSynchronizationDesign(context); // ObjectNode cm = new ObjectNode("CompanyMediator"); // MediatorInsertion mi = new MediatorInsertion(customer, company, cm, context); @@ -43,7 +46,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/models/dataSynchronizationModel/DataSynchronizationContext.java b/src/main/java/models/dataSynchronizationModel/DataSynchronizationContext.java index 486fb2e..5daa0d3 100644 --- a/src/main/java/models/dataSynchronizationModel/DataSynchronizationContext.java +++ b/src/main/java/models/dataSynchronizationModel/DataSynchronizationContext.java @@ -78,6 +78,22 @@ return syncronizationRelation.getMultiplicity(); } + public boolean isTransferToOne() { + return (syncronizationRelation.getMultiplicity() == MultiplicityValue.OneToOne || syncronizationRelation.getMultiplicity() == MultiplicityValue.ManyToOne); + } + + public boolean isTransferToMany() { + return (syncronizationRelation.getMultiplicity() == MultiplicityValue.OneToMany || syncronizationRelation.getMultiplicity() == MultiplicityValue.ManyToMany); + } + + public boolean isTransferOneTo() { + return (syncronizationRelation.getMultiplicity() == MultiplicityValue.OneToOne || syncronizationRelation.getMultiplicity() == MultiplicityValue.OneToMany); + } + + public boolean isTransferManyTo() { + return (syncronizationRelation.getMultiplicity() == MultiplicityValue.ManyToOne || syncronizationRelation.getMultiplicity() == MultiplicityValue.ManyToMany); + } + public String getDataName() { return dataName; } diff --git a/src/main/java/models/dataSynchronizationModel/DataSynchronizationDesign.java b/src/main/java/models/dataSynchronizationModel/DataSynchronizationDesign.java index e21fedf..f8466e0 100644 --- a/src/main/java/models/dataSynchronizationModel/DataSynchronizationDesign.java +++ b/src/main/java/models/dataSynchronizationModel/DataSynchronizationDesign.java @@ -25,6 +25,14 @@ private List mediatorInsertions = new ArrayList<>(); private List presenterInsertions = new ArrayList<>(); + public static String toComponentName(String name) { + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + + public static String toVariableName(String name) { + return name.substring(0, 1).toLowerCase() + name.substring(1); + } + public DataSynchronizationDesign(DataSynchronizationContext synchronizationContexts) throws IllegalRelationException { this.synchronizationContexts = new ArrayList<>(); this.synchronizationContexts.add(synchronizationContexts); @@ -80,47 +88,338 @@ return deltaComplex; } - private Stack constructDefaultDeltas(DataSynchronizationContext transferContext) throws IllegalRelationException { + /* + * construct default deltas that satisfy the law of demeter. + * + * @param synchronizationContext a synchronization context in data synchronization model + * @return generated deltas + */ + private Stack constructDefaultDeltas(DataSynchronizationContext synchronizationContext) throws IllegalRelationException { Stack deltaStack = new Stack<>(); - PushPullValue transferStyle = transferContext.getTransferStyle(); + PushPullValue transferStyle = synchronizationContext.getTransferStyle(); ObjectNode srcObj = null; ObjectNode dstObj = null; if (transferStyle == PushPullValue.PUSH) { - srcObj = transferContext.getSrcTopObject(); - dstObj = transferContext.getDstTopObject(); + srcObj = synchronizationContext.getSrcTopObject(); + dstObj = synchronizationContext.getDstTopObject(); } else { - srcObj = transferContext.getDstTopObject(); - dstObj = transferContext.getSrcTopObject(); + srcObj = synchronizationContext.getDstTopObject(); + dstObj = synchronizationContext.getSrcTopObject(); } - String refName = dstObj.getName().substring(0, 1).toLowerCase() + dstObj.getName().substring(1); + String refName = toVariableName(dstObj.getName()); ReferenceEdge prevReference = new ReferenceEdge(srcObj, dstObj, refName); boolean hasDiagonalRelation = false; - if (!transferContext.isFlat()) { - boolean toOne = true; // potential multiplicity - ObjectHierarchy srcHierarchy = null; - ObjectHierarchy dstHierarchy = null; - List allRelations = new ArrayList<>(transferContext.getIntermediateRelations()); + if (!synchronizationContext.isFlat()) { + boolean toOne = true; // identifiable multiplicity + List allRelations = new ArrayList<>(synchronizationContext.getIntermediateRelations()); for (Relation relation: allRelations) { - if (transferContext.getSrcObjectHierarchy().isPrefixOf(relation.getSrcObjectHierarchy()) - || transferContext.getDstObjectHierarchy().isPrefixOf(relation.getDstObjectHierarchy())) { + if (synchronizationContext.getSrcObjectHierarchy().isPrefixOf(relation.getSrcObjectHierarchy()) + || synchronizationContext.getDstObjectHierarchy().isPrefixOf(relation.getDstObjectHierarchy())) { hasDiagonalRelation = true; break; } } if (!hasDiagonalRelation) { - allRelations.add(transferContext.getSyncronizationRelation().getPrevRelation()); + allRelations.add(synchronizationContext.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()); + if (!synchronizationContext.getSrcObjectHierarchy().isPrefixOf(lastRelation.getSrcObjectHierarchy())) { + bottomRelation = new Relation(synchronizationContext.getSrcObjectHierarchy().getPrevObjectHierarchy(), + synchronizationContext.getSrcObjectHierarchy(), + synchronizationContext.getTransferMultiplicity()); allRelations.add(bottomRelation); - } else if (!transferContext.getDstObjectHierarchy().isPrefixOf(lastRelation.getDstObjectHierarchy())) { - bottomRelation = new Relation(transferContext.getSrcObjectHierarchy(), - transferContext.getDstObjectHierarchy().getPrevObjectHierarchy(), - transferContext.getTransferMultiplicity()); + } else if (!synchronizationContext.getDstObjectHierarchy().isPrefixOf(lastRelation.getDstObjectHierarchy())) { + bottomRelation = new Relation(synchronizationContext.getSrcObjectHierarchy(), + synchronizationContext.getDstObjectHierarchy().getPrevObjectHierarchy(), + synchronizationContext.getTransferMultiplicity()); + allRelations.add(bottomRelation); + } + } + ObjectHierarchy srcHierarchy = null; + ObjectHierarchy dstHierarchy = null; + for (Relation relation: allRelations) { + ObjectHierarchy newSrcHierarchy = null; + ObjectHierarchy newDstHierarchy = null; + if (transferStyle == PushPullValue.PUSH) { + newSrcHierarchy = relation.getSrcObjectHierarchy(); + newDstHierarchy = relation.getDstObjectHierarchy(); + } else { + newSrcHierarchy = relation.getDstObjectHierarchy(); + newDstHierarchy = relation.getSrcObjectHierarchy(); + } + if (srcHierarchy == null) { + srcHierarchy = new ObjectHierarchy(newSrcHierarchy.getTop()); + } + if (dstHierarchy == null) { + dstHierarchy = new ObjectHierarchy(newDstHierarchy.getTop()); + } + while (dstHierarchy.getDepth() < newDstHierarchy.getDepth() || srcHierarchy.getDepth() < newSrcHierarchy.getDepth()) { + List oneDestinations = new ArrayList<>(); + List manyDestinations = new ArrayList<>(); + boolean tmpToOne = toOne; + for (int i = 0; i < newDstHierarchy.getDepth(); i++) { + ReferenceEdge dstEdge = newDstHierarchy.getEdge(i); + if (dstHierarchy != null && i < dstHierarchy.getDepth()) { + if (!dstHierarchy.getEdge(i).equals(dstEdge)) { + throw new IllegalRelationException(); + } + } else { + dstHierarchy.addEdge(dstEdge); + if (dstEdge.toMany()) { + tmpToOne = false; + toOne = false; + } + if (!tmpToOne && + (transferStyle == PushPullValue.PUSH && relation.toOne()) + || (transferStyle != PushPullValue.PUSH && (relation.oneTo()))) { + // If the specified multiplicity of destination objects does not match to their identifiable multiplicity, + // then the reference to select one destination object from identifiable multiple objects is needed. + manyDestinations.add(dstEdge); + toOne = true; + } else { + // If the specified multiplicity of destination objects and their identifiable are both many or both one, + // then the reference to select one destination object from identifiable multiple objects is not needed. + oneDestinations.add(dstEdge); + } + } + } + + // 1) Create component obtaining deltas. + Delta delta = null; + ReferenceEdge prevDstEdge = null; + for (int i = oneDestinations.size() - 1; i >= 0; i--) { + ReferenceEdge dstEdge = oneDestinations.get(i); + if (prevDstEdge != null) { + srcObj = (ObjectNode) dstEdge.getSource(); + dstObj = (ObjectNode) prevDstEdge.getDestination(); + String dataName = toVariableName(prevDstEdge.getName()); + if (!newSrcHierarchy.contains((ObjectNode) dstEdge.getDestination())) { + PrimitiveDelta primDelta = null; + if (!prevDstEdge.toMany()) { + primDelta = new PrimitivePullDelta(dstEdge, prevDstEdge, dataName); // a primitive component obtaining delta + } else { + primDelta = new PrimitivePullDelta(dstEdge, prevDstEdge, dataName, true, false); // a primitive component obtaining delta + } + if (delta == null) { + delta = new Delta(primDelta); + } else { + delta = delta.combine(primDelta); + } + if (!prevDstEdge.toMany()) { + prevDstEdge = new ReferenceEdge(srcObj, dstObj, dataName); + } else { + prevDstEdge = new ReferenceEdge(srcObj, dstObj, dataName, prevDstEdge.getKeyTypeName()); + } + } else { + prevReference = new ReferenceEdge((ObjectNode) dstEdge.getDestination(), (ObjectNode) dstEdge.getDestination(), dataName); + break; + } + } else { + prevDstEdge = dstEdge; + } + } + if (delta != null) deltaStack.push(delta); // add a component obtaining SIMPLEX delta + if (prevDstEdge != null) { + if (!prevReference.isIdentical()) { + srcObj = (ObjectNode) prevReference.getSource(); + dstObj = (ObjectNode) prevDstEdge.getDestination(); + String dataName = toVariableName(prevDstEdge.getName()); + delta = new Delta(new PrimitivePullDelta(prevReference, prevDstEdge, dataName, prevDstEdge.toMany())); + if (delta != null) + deltaStack.push(delta); // add a component obtaining SIMPLEX delta + if (!prevDstEdge.toMany()) { + prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + } else { + prevReference = new ReferenceEdge(srcObj, dstObj, dataName, prevDstEdge.getKeyTypeName()); + } + } else { + prevReference = prevDstEdge; + } + } + + // 2) Create container passing deltas. + delta = null; + boolean oneTo = true; + for (int i = 0; i < newSrcHierarchy.getDepth(); i++) { + ReferenceEdge srcEdge = newSrcHierarchy.getEdge(i); + if (srcHierarchy != null && i < srcHierarchy.getDepth()) { + if (!srcHierarchy.getEdge(i).equals(srcEdge)) { + throw new IllegalRelationException(); + } + } else { + srcHierarchy.addEdge(srcEdge); + if (srcEdge.toMany()) { + oneTo = false; + } + srcObj = (ObjectNode) srcEdge.getDestination(); + dstObj = (ObjectNode) prevReference.getDestination(); + String dataName = toVariableName(prevReference.getName()); + if (!prevReference.isIdentical() && !dstHierarchy.contains(srcObj)) { + PrimitiveDelta primDelta = null; + if (toOne) { + primDelta = new PrimitivePullPushDelta(prevReference, srcEdge, dataName); // a container passing primitive delta + } else { + primDelta = new PrimitivePullPushDelta(prevReference, srcEdge, dataName, true); // a container passing primitive delta + } + if (delta == null) { + delta = new Delta(primDelta); + } else { + if (oneTo) { + delta = delta.combine(primDelta); + } else { + if (delta != null) { + deltaStack.push(delta); // add a container passing SIMPLEX delta + } + delta = new Delta(primDelta); + } + } + if (toOne) { + prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + } else { + prevReference = new ReferenceEdge(srcObj, dstObj, dataName, prevReference.getKeyTypeName()); + } + } + } + } + if (delta != null) deltaStack.push(delta); // add a container passing SIMPLEX delta + + // 3) Create a component selecting delta. + for (ReferenceEdge dstEdge : manyDestinations) { + srcObj = (ObjectNode) prevReference.getSource(); + dstObj = (ObjectNode) dstEdge.getDestination(); + String dataName = toVariableName(dstEdge.getName()); + PrimitivePullDelta componentSelectingDelta = null; + componentSelectingDelta = new PrimitivePullDelta(prevReference, dstEdge, dataName); + delta = new Delta(componentSelectingDelta); + deltaStack.push(delta); // add a component selecting delta + prevReference = new ReferenceEdge(srcObj, dstObj, dataName); + } + } + } + } + if (!hasDiagonalRelation) { + // 4) Create the bottom (data transfer) delta. + Delta dataTransferDelta = null; + if (transferStyle == PushPullValue.PUSH) { + // PUSH transfer + if (synchronizationContext.isTransferToOne()) { + // Simple PUSH + + // Add the data transfer delta. + srcObj = (ObjectNode) prevReference.getSource(); + dstObj = (ObjectNode) synchronizationContext.getSrcObjectHierarchy().getBottom(); + String dataName = synchronizationContext.getDataName(); + ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); + PrimitivePullPushDelta primDelta = new PrimitivePullPushDelta(dataEdge, prevReference, dataName); // PUSH data transfer + if (synchronizationContext.getSyncronizationRelation().toMany()) { + primDelta.setMultipleTransfer(true); + } + dataTransferDelta = new Delta(primDelta); + } else { + // Broadcasting + prevReference = new ReferenceEdge(prevReference); + prevReference.setKeyTypeName(synchronizationContext.getDstObjectHierarchy().getEdges().getLast().getKeyTypeName()); +// prevReference.setMultiplicity(MultiplicityValue.OneToMany); + + // Add the data transfer delta. + srcObj = (ObjectNode) prevReference.getSource(); + dstObj = (ObjectNode) synchronizationContext.getSrcObjectHierarchy().getBottom(); + String dataName = synchronizationContext.getDataName(); + ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); + PrimitivePullPushDelta primDelta = new PrimitivePullPushDelta(dataEdge, prevReference, dataName); // PUSH data transfer + if (synchronizationContext.getDstObjectHierarchy().getEdges().getLast().toMany()) { + primDelta.setMultipleDefinition(true); + } + if (synchronizationContext.getSyncronizationRelation().toMany()) { + primDelta.setMultipleTransfer(true); + } + dataTransferDelta = new Delta(primDelta); + } + } else { + if (synchronizationContext.isTransferOneTo()) { + // Simple PULL + + // Add the data transfer delta. + srcObj = (ObjectNode) prevReference.getDestination(); + dstObj = (ObjectNode) synchronizationContext.getSrcObjectHierarchy().getBottom(); + String dataName = synchronizationContext.getDataName(); + ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); + PrimitivePullDelta primDelta = new PrimitivePullDelta(prevReference, dataEdge, dataName); // PULL data transfer + if (synchronizationContext.getSyncronizationRelation().manyTo()) { + primDelta.setMultipleTransfer(true); + } + dataTransferDelta = new Delta(primDelta); + } else { + // Data collecting + prevReference = new ReferenceEdge(prevReference); + prevReference.setKeyTypeName(synchronizationContext.getSrcObjectHierarchy().getEdges().getLast().getKeyTypeName()); +// prevReference.setMultiplicity(MultiplicityValue.OneToMany); + + // Add the data transfer delta. + srcObj = (ObjectNode) prevReference.getDestination(); + dstObj = (ObjectNode) synchronizationContext.getSrcObjectHierarchy().getBottom(); + String dataName = synchronizationContext.getDataName(); + ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); + PrimitivePullDelta primDelta = new PrimitivePullDelta(prevReference, dataEdge, dataName, true); // PULL data transfer + if (synchronizationContext.getSyncronizationRelation().manyTo()) { + primDelta.setMultipleTransfer(true); + } + dataTransferDelta = new Delta(primDelta); + } + } + deltaStack.push(dataTransferDelta); + } + return deltaStack; + } + + /* + * construct default deltas that do not satisfy the law of demeter. + * + * @param synchronizationContext a synchronization context in data synchronization model + * @return generated deltas + */ + private Stack constructDefaultDeltas2(DataSynchronizationContext synchronizationContext) throws IllegalRelationException { + Stack deltaStack = new Stack<>(); + PushPullValue transferStyle = synchronizationContext.getTransferStyle(); + ObjectNode srcObj = null; + ObjectNode dstObj = null; + if (transferStyle == PushPullValue.PUSH) { + srcObj = synchronizationContext.getSrcTopObject(); + dstObj = synchronizationContext.getDstTopObject(); + } else { + srcObj = synchronizationContext.getDstTopObject(); + dstObj = synchronizationContext.getSrcTopObject(); + } + String refName = toVariableName(dstObj.getName()); + ReferenceEdge prevReference = new ReferenceEdge(srcObj, dstObj, refName); + boolean hasDiagonalRelation = false; + if (!synchronizationContext.isFlat()) { + boolean toOne = true; // identifiable multiplicity + ObjectHierarchy srcHierarchy = null; + ObjectHierarchy dstHierarchy = null; + List allRelations = new ArrayList<>(synchronizationContext.getIntermediateRelations()); + for (Relation relation: allRelations) { + if (synchronizationContext.getSrcObjectHierarchy().isPrefixOf(relation.getSrcObjectHierarchy()) + || synchronizationContext.getDstObjectHierarchy().isPrefixOf(relation.getDstObjectHierarchy())) { + hasDiagonalRelation = true; + break; + } + } + if (!hasDiagonalRelation) { + allRelations.add(synchronizationContext.getSyncronizationRelation().getPrevRelation()); + } else { + Relation lastRelation = allRelations.getLast(); + Relation bottomRelation = null; + if (!synchronizationContext.getSrcObjectHierarchy().isPrefixOf(lastRelation.getSrcObjectHierarchy())) { + bottomRelation = new Relation(synchronizationContext.getSrcObjectHierarchy().getPrevObjectHierarchy(), + synchronizationContext.getSrcObjectHierarchy(), + synchronizationContext.getTransferMultiplicity()); + allRelations.add(bottomRelation); + } else if (!synchronizationContext.getDstObjectHierarchy().isPrefixOf(lastRelation.getDstObjectHierarchy())) { + bottomRelation = new Relation(synchronizationContext.getSrcObjectHierarchy(), + synchronizationContext.getDstObjectHierarchy().getPrevObjectHierarchy(), + synchronizationContext.getTransferMultiplicity()); allRelations.add(bottomRelation); } } @@ -135,35 +434,35 @@ newDstHierarchy = relation.getSrcObjectHierarchy(); } if ((dstHierarchy == null || dstHierarchy.getDepth() < newDstHierarchy.getDepth()) || (srcHierarchy == null || srcHierarchy.getDepth() < newSrcHierarchy.getDepth())) { - List oneDestination = new ArrayList<>(); + List oneDestinations = new ArrayList<>(); List manyDestinations = new ArrayList<>(); boolean nextToOne = toOne; for (int i = 0; i < newDstHierarchy.getDepth(); i++) { + ReferenceEdge dstEdge = newDstHierarchy.getEdge(i); if (dstHierarchy != null && i < dstHierarchy.getDepth()) { - if (!dstHierarchy.getEdge(i).equals(newDstHierarchy.getEdge(i))) { + if (!dstHierarchy.getEdge(i).equals(dstEdge)) { throw new IllegalRelationException(); } } else { - if (newDstHierarchy.getEdge(i).toMany()) { + if (dstEdge.toMany()) { nextToOne = false; } if (nextToOne) { - oneDestination.add(newDstHierarchy.getEdge(i)); + oneDestinations.add(dstEdge); } else { - manyDestinations.add(newDstHierarchy.getEdge(i)); + manyDestinations.add(dstEdge); } } } - // 1) Create container passing deltas. + // 1) Create container passing simplex deltas. List primitiveDeltaList = new ArrayList<>(); - for (ReferenceEdge dstEdge: oneDestination) { + for (ReferenceEdge dstEdge: oneDestinations) { srcObj = (ObjectNode) prevReference.getSource(); dstObj = (ObjectNode) dstEdge.getDestination(); - String dataName = dstObj.getName(); - dataName = dataName.substring(0, 1).toLowerCase() + dataName.substring(1); + String dataName = toVariableName(dstObj.getName()); if (!prevReference.isIdentical()) { - primitiveDeltaList.add(new PrimitivePullDelta(prevReference, dstEdge, dataName)); + primitiveDeltaList.add(new PrimitivePullDelta(prevReference, dstEdge, dataName)); // a component obtaining primitive delta } prevReference = new ReferenceEdge(srcObj, dstObj, dataName); } @@ -176,13 +475,12 @@ } else { srcObj = (ObjectNode) srcEdge.getDestination(); dstObj = (ObjectNode) prevReference.getDestination(); - String dataName = dstObj.getName(); - dataName = dataName.substring(0, 1).toLowerCase() + dataName.substring(1); + String dataName = toVariableName(dstObj.getName()); if (!prevReference.isIdentical() && !prevReference.getDestination().equals(srcEdge.getDestination())) { if (toOne) { - primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName)); + primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName)); // a container passing primitive delta } else { - primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName, true)); + primitiveDeltaList.add(new PrimitivePullPushDelta(prevReference, srcEdge, dataName, true)); // a container passing primitive delta } Delta delta = null; for (PrimitiveDelta primDelta : primitiveDeltaList) { @@ -192,7 +490,7 @@ delta = new Delta(primDelta, delta); } } - deltaStack.push(delta); // add a container passing delta + deltaStack.push(delta); // add a container passing SIMPLEX delta primitiveDeltaList.clear(); } prevReference = new ReferenceEdge(srcObj, dstObj, dataName); @@ -202,24 +500,22 @@ if (!toOne) { 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, - // then the reference to select one destination object from potential multiple objects is needed. + if ((transferStyle == PushPullValue.PUSH && relation.toOne()) || (transferStyle != PushPullValue.PUSH && relation.oneTo())) { + // If the specified multiplicity of destination objects does not match to their identifiable multiplicity, + // then the reference to select one destination object from identifiable multiple objects is needed. toOne = true; } else { - // If the specified multiplicity of destination objects and their potential multiplicity are both many, - // then the reference to select one destination object from potential multiple objects is needed. + // If the specified multiplicity of destination objects and their identifiable multiplicity are both many, + // then the reference to select one destination object from identifiable multiple objects is needed. multipleDefinition = true; } - // 2) Create a component selecting delta. + // 2) Create a component selecting simplex delta. PrimitivePullDelta componentSelectingDelta = null; for (ReferenceEdge dstEdge : manyDestinations) { if (componentSelectingDelta == null) { srcObj = (ObjectNode) prevReference.getSource(); dstObj = (ObjectNode) dstEdge.getDestination(); - String dataName = dstObj.getName(); - dataName = dataName.substring(0, 1).toLowerCase() + dataName.substring(1); + String dataName = toVariableName(dstObj.getName()); componentSelectingDelta = new PrimitivePullDelta(prevReference, dstEdge, dataName, multipleDefinition); primitiveDeltaList.add(componentSelectingDelta); Delta delta = null; @@ -230,7 +526,7 @@ delta = new Delta(primDelta, delta); } } - deltaStack.push(delta); // add a component identifying delta + deltaStack.push(delta); // add a component selecting SIMPLEX delta primitiveDeltaList.clear(); if (!multipleDefinition) { prevReference = new ReferenceEdge(srcObj, dstObj, dataName); @@ -240,9 +536,8 @@ } else { srcObj = (ObjectNode) prevReference.getSource(); dstObj = (ObjectNode) dstEdge.getDestination(); - String dataName = dstObj.getName(); - dataName = dataName.substring(0, 1).toLowerCase() + dataName.substring(1); - componentSelectingDelta = new PrimitivePullDelta(prevReference, dstEdge, dataName, multipleDefinition); + String dataName = toVariableName(dstObj.getName()); + componentSelectingDelta = new PrimitivePullDelta(prevReference, dstEdge, dataName, multipleDefinition); // a component obtaining primitive delta primitiveDeltaList.add(componentSelectingDelta); if (!multipleDefinition) { prevReference = new ReferenceEdge(srcObj, dstObj, dataName); @@ -252,7 +547,7 @@ } } } - // 3) Create a component obtaining delta. + // 3) Create a component obtaining simplex delta. if (primitiveDeltaList.size() > 0) { Delta delta = null; for (PrimitiveDelta primDelta: primitiveDeltaList) { @@ -262,7 +557,7 @@ delta = new Delta(primDelta, delta); } } - deltaStack.push(delta); // add a component obtaining delta + deltaStack.push(delta); // add a component obtaining SIMPLEX delta } } else { throw new IllegalRelationException(); @@ -276,73 +571,66 @@ Delta dataTransferDelta = null; if (transferStyle == PushPullValue.PUSH) { // PUSH transfer - if (transferContext.getTransferMultiplicity() == MultiplicityValue.ManyToOne - || transferContext.getTransferMultiplicity() == MultiplicityValue.OneToOne) { + if (synchronizationContext.isTransferToOne()) { // Simple PUSH // Add the data transfer delta. srcObj = (ObjectNode) prevReference.getSource(); - dstObj = (ObjectNode) transferContext.getSrcObjectHierarchy().getBottom(); - String dataName = transferContext.getDataName(); + dstObj = (ObjectNode) synchronizationContext.getSrcObjectHierarchy().getBottom(); + String dataName = synchronizationContext.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) { + if (synchronizationContext.getSyncronizationRelation().toMany()) { primDelta.setMultipleTransfer(true); } dataTransferDelta = new Delta(primDelta); } else { // Broadcasting prevReference = new ReferenceEdge(prevReference); - prevReference.setKeyTypeName(transferContext.getDstObjectHierarchy().getEdges().getLast().getKeyTypeName()); + prevReference.setKeyTypeName(synchronizationContext.getDstObjectHierarchy().getEdges().getLast().getKeyTypeName()); // prevReference.setMultiplicity(MultiplicityValue.OneToMany); // Add the data transfer delta. srcObj = (ObjectNode) prevReference.getSource(); - dstObj = (ObjectNode) transferContext.getSrcObjectHierarchy().getBottom(); - String dataName = transferContext.getDataName(); + dstObj = (ObjectNode) synchronizationContext.getSrcObjectHierarchy().getBottom(); + String dataName = synchronizationContext.getDataName(); ReferenceEdge dataEdge = new ReferenceEdge(srcObj, dstObj, dataName); 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) { + if (synchronizationContext.getDstObjectHierarchy().getEdges().getLast().toMany()) { primDelta.setMultipleDefinition(true); } - if (transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.OneToMany - || transferContext.getSyncronizationRelation().getMultiplicity() == MultiplicityValue.ManyToMany) { + if (synchronizationContext.getSyncronizationRelation().toMany()) { primDelta.setMultipleTransfer(true); } dataTransferDelta = new Delta(primDelta); } } else { - if (transferContext.getTransferMultiplicity() == MultiplicityValue.OneToMany - || transferContext.getTransferMultiplicity() == MultiplicityValue.OneToOne) { + if (synchronizationContext.isTransferOneTo()) { // Simple PULL // Add the data transfer delta. srcObj = (ObjectNode) prevReference.getDestination(); - dstObj = (ObjectNode) transferContext.getSrcObjectHierarchy().getBottom(); - String dataName = transferContext.getDataName(); + dstObj = (ObjectNode) synchronizationContext.getSrcObjectHierarchy().getBottom(); + String dataName = synchronizationContext.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) { + if (synchronizationContext.getSyncronizationRelation().manyTo()) { primDelta.setMultipleTransfer(true); } dataTransferDelta = new Delta(primDelta); } else { // Data collecting prevReference = new ReferenceEdge(prevReference); - prevReference.setKeyTypeName(transferContext.getSrcObjectHierarchy().getEdges().getLast().getKeyTypeName()); + prevReference.setKeyTypeName(synchronizationContext.getSrcObjectHierarchy().getEdges().getLast().getKeyTypeName()); // prevReference.setMultiplicity(MultiplicityValue.OneToMany); // Add the data transfer delta. srcObj = (ObjectNode) prevReference.getDestination(); - dstObj = (ObjectNode) transferContext.getSrcObjectHierarchy().getBottom(); - String dataName = transferContext.getDataName(); + dstObj = (ObjectNode) synchronizationContext.getSrcObjectHierarchy().getBottom(); + String dataName = synchronizationContext.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) { + if (synchronizationContext.getSyncronizationRelation().manyTo()) { primDelta.setMultipleTransfer(true); } dataTransferDelta = new Delta(primDelta); diff --git a/src/main/java/models/dataSynchronizationModel/ObjectHierarchy.java b/src/main/java/models/dataSynchronizationModel/ObjectHierarchy.java index 20a9fc5..afc2aee 100644 --- a/src/main/java/models/dataSynchronizationModel/ObjectHierarchy.java +++ b/src/main/java/models/dataSynchronizationModel/ObjectHierarchy.java @@ -38,6 +38,11 @@ return edges; } + public void addEdge(ReferenceEdge edge) { + edges.add(edge); + isFlat = false; + } + public boolean isFlat() { return isFlat; } @@ -50,6 +55,18 @@ return edges.get(index); } + public boolean contains(ObjectNode node) { + if (top.equals(node)) { + return true; + } + for (ReferenceEdge edge : edges) { + if (edge.getDestination().equals(node)) { + return true; + } + } + return false; + } + public boolean isPrefixOf(ObjectHierarchy another) { if (!top.equals(another.top)) { return false; @@ -75,4 +92,12 @@ } return new ObjectHierarchy(edges); } + + public String toString() { + String str = top.toString(); + for (ReferenceEdge edge : edges) { + str += "." + ((ObjectNode) edge.getDestination()).toString(); + } + return str; + } } diff --git a/src/main/java/models/dataSynchronizationModel/Relation.java b/src/main/java/models/dataSynchronizationModel/Relation.java index 5ecfc46..f6edbf2 100644 --- a/src/main/java/models/dataSynchronizationModel/Relation.java +++ b/src/main/java/models/dataSynchronizationModel/Relation.java @@ -80,6 +80,22 @@ return multiplicity; } + public boolean toOne() { + return (multiplicity == MultiplicityValue.OneToOne || multiplicity == MultiplicityValue.ManyToOne); + } + + public boolean toMany() { + return (multiplicity == MultiplicityValue.OneToMany || multiplicity == MultiplicityValue.ManyToMany); + } + + public boolean oneTo() { + return (multiplicity == MultiplicityValue.OneToOne || multiplicity == MultiplicityValue.OneToMany); + } + + public boolean manyTo() { + return (multiplicity == MultiplicityValue.ManyToOne || multiplicity == MultiplicityValue.ManyToMany); + } + public Relation getPrevRelation() { return new Relation(this.srcObjectHierarchy.getPrevObjectHierarchy(), this.dstObjectHierarchy.getPrevObjectHierarchy(), this.multiplicity); } diff --git a/src/test/java/parser/TestParser.java b/src/test/java/parser/TestParser.java index 0f62959..433fbb1 100644 --- a/src/test/java/parser/TestParser.java +++ b/src/test/java/parser/TestParser.java @@ -17,7 +17,7 @@ @Test void testCustomerManagement(){ - //File file = new File("models/CustomerManagement.Json"); + //File file = new File("models/CustomerManagement-PULL.Json"); File file = new File("models/designPattern/Adapter.Json"); try {