diff --git a/AlgebraicDataflowArchitectureModel/models/Citrus.model b/AlgebraicDataflowArchitectureModel/models/Citrus.model index 700e4dd..a4cd25b 100644 --- a/AlgebraicDataflowArchitectureModel/models/Citrus.model +++ b/AlgebraicDataflowArchitectureModel/models/Citrus.model @@ -23,10 +23,14 @@ } channel CreateToDo(aid:Str, bid:Int) { - out accounts.{aid}.books.{bid}.todos(toDoDB:Map, createtodo(year:Str, month:Str, day:Str, title:Str)) = insert(toDoDB, year, - insert(lookup(toDoDB, year), month, - insert(lookup(lookup(toDoDB, year), month), day, - append(lookup(lookup(lookup(toDoDB, year), month), day), {"title": title, "check": false})))) + out accounts.{aid}.books.{bid}.todos(toDoDB:Map, createtodo(year:Str, month:Str, day:Str, title:Str)) = insert(toDoDB, + year, + insert(lookup(toDoDB, year), + month, + insert(lookup(lookup(toDoDB, year), month), + day, + append(lookup(lookup(lookup(toDoDB, year), month), day), + {"title": title, "check": false})))) } channel ChangeToDoName(aid:Str, bid:Int, year:Str, month:Str, day:Str, tid:Int) { diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index beba922..14182ed 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -36,6 +36,7 @@ import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.JsonAccessor; +import models.dataConstraintModel.JsonTerm; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; import models.dataConstraintModel.Selector; @@ -180,9 +181,14 @@ // Add update statements. for (MethodDeclaration method: updateStatements.keySet()) { Expression updateExp = updateStatements.get(method).getKey(); - ResourceHierarchy childRes = updateStatements.get(method).getValue(); - TypeDeclaration childComponent = resourceComponents.get(childRes); - addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, childRes, childComponent, langSpec); + ResourceHierarchy descendantRes = updateStatements.get(method).getValue(); + Set children; + do { + if (JavaCodeGenerator.generatesComponent(descendantRes)) break; + children = descendantRes.getChildren(); + } while (children != null && children.size() == 1 && (descendantRes = children.iterator().next()) != null); + TypeDeclaration descendanttComponent = resourceComponents.get(descendantRes); + addUpdateStatementWithConstructorInvocationToMethod(method, updateExp, descendantRes, descendanttComponent, langSpec); } } @@ -240,31 +246,33 @@ Entry termEnt = termEntItr.next(); Term jsonTerm = termEnt.getValue(); if (jsonTerm.getType() != null && jsonTerm.getType().equals(replacedJsonType)) { - MethodDeclaration childConstructor = getConstructor(childComponent); - List params = new ArrayList<>(); - for (VariableDeclaration var: childConstructor.getParameters()) { - JsonAccessor jsonMember = new JsonAccessor(DataConstraintModel.dot); - jsonMember.addChild(jsonTerm); - jsonMember.addChild(new Constant(var.getName(), DataConstraintModel.typeString)); - Expression param = jsonMember.reduce(); - if (param != null) { - if (param instanceof Term) { - if (((Term) param).getType() == null) { - ((Term) param).setType(var.getType()); + if (jsonTerm instanceof JsonTerm || jsonTerm.getSymbol().equals(DataConstraintModel.addMember)) { + MethodDeclaration childConstructor = getConstructor(childComponent); + List params = new ArrayList<>(); + for (VariableDeclaration var: childConstructor.getParameters()) { + JsonAccessor jsonMember = new JsonAccessor(DataConstraintModel.dot); + jsonMember.addChild(jsonTerm); + jsonMember.addChild(new Constant(var.getName(), DataConstraintModel.typeString)); + Expression param = jsonMember.reduce(); + if (param != null) { + if (param instanceof Term) { + if (((Term) param).getType() == null) { + ((Term) param).setType(var.getType()); + } + } else if (param instanceof Variable) { + if (((Variable) param).getType() == null) { + ((Variable) param).setType(var.getType()); + } } - } else if (param instanceof Variable) { - if (((Variable) param).getType() == null) { - ((Variable) param).setType(var.getType()); - } + params.add(param.toImplementation(null)); + } else { + params.add(var.getName()); } - params.add(param.toImplementation(null)); - } else { - params.add(var.getName()); } + ((Term) exp).replaceSubTerm(termEnt.getKey(), new Constant(langSpec.getConstructorInvocation(replacingClassName, params))); + subTerms = ((Term) exp).getSubTerms(Term.class); + termEntItr = subTerms.entrySet().iterator(); } - ((Term) exp).replaceSubTerm(termEnt.getKey(), new Constant(langSpec.getConstructorInvocation(replacingClassName, params))); - subTerms = ((Term) exp).getSubTerms(Term.class); - termEntItr = subTerms.entrySet().iterator(); } } // Replace the type of the state field. diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java index df180a0..41c68e4 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java @@ -32,6 +32,7 @@ import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.JsonAccessor; +import models.dataConstraintModel.JsonTerm; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; import models.dataConstraintModel.Selector; @@ -110,15 +111,20 @@ } updateExp = ch.deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor, inputResourceToStateAccessor).getKey(); } - // Replace Json constructor with a constructor of the child resource. + // Replace Json constructor with a constructor of a descendant resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { - ResourceHierarchy childRes = outRes.getChildren().iterator().next(); - Type childStateType = childRes.getResourceStateType(); - String childComponentName = JavaCodeGenerator.getComponentName(childRes); - TypeDeclaration childComponent = componentMap.get(childComponentName); - if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) { - replaceJsonTermWithConstructorInvocation(updateExp, childStateType, childComponentName, childComponent); + ResourceHierarchy descendantRes = outRes.getChildren().iterator().next(); + Set children; + do { + if (JavaCodeGenerator.generatesComponent(descendantRes)) break; + children = descendantRes.getChildren(); + } while (children != null && children.size() == 1 && (descendantRes = children.iterator().next()) != null); + Type descendantStateType = descendantRes.getResourceStateType(); + String descendantComponentName = JavaCodeGenerator.getComponentName(descendantRes); + TypeDeclaration descendantComponent = componentMap.get(descendantComponentName); + if (DataConstraintModel.typeJson.isAncestorOf(descendantStateType)) { + replaceJsonTermWithConstructorInvocation(updateExp, descendantStateType, descendantComponentName, descendantComponent); } } // Replace the type of the state field. @@ -718,15 +724,20 @@ if (input != null) { // In each resource Expression updateExp = ch.deriveUpdateExpressionOf(out, JavaCodeGenerator.refAccessor).getKey(); - // Replace Json constructor with a constructor of the child resource. + // Replace Json constructor with a constructor of a descendant resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { - ResourceHierarchy childRes = outRes.getChildren().iterator().next(); - Type childStateType = childRes.getResourceStateType(); - String childComponentName = JavaCodeGenerator.getComponentName(childRes); - TypeDeclaration childComponent = componentMap.get(childComponentName); - if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) { - replaceJsonTermWithConstructorInvocation(updateExp, childStateType, childComponentName, childComponent); + ResourceHierarchy descendantRes = outRes.getChildren().iterator().next(); + Set children; + do { + if (JavaCodeGenerator.generatesComponent(descendantRes)) break; + children = descendantRes.getChildren(); + } while (children != null && children.size() == 1 && (descendantRes = children.iterator().next()) != null); + Type descendantStateType = descendantRes.getResourceStateType(); + String descendantComponentName = JavaCodeGenerator.getComponentName(descendantRes); + TypeDeclaration descendantComponent = componentMap.get(descendantComponentName); + if (DataConstraintModel.typeJson.isAncestorOf(descendantStateType)) { + replaceJsonTermWithConstructorInvocation(updateExp, descendantStateType, descendantComponentName, descendantComponent); } } // Replace the type of the state field. @@ -883,34 +894,36 @@ Entry termEnt = termEntItr.next(); Term jsonTerm = termEnt.getValue(); if (jsonTerm.getType() != null && jsonTerm.getType().equals(replacedJsonType)) { - String constructorInvocation = "new " + replacingClassName + "("; - MethodDeclaration childConstructor = getConstructor(childComponent); - String delimiter = ""; - for (VariableDeclaration var: childConstructor.getParameters()) { - JsonAccessor jsonMember = new JsonAccessor(DataConstraintModel.dot); - jsonMember.addChild(jsonTerm); - jsonMember.addChild(new Constant(var.getName(), DataConstraintModel.typeString)); - Expression param = jsonMember.reduce(); - if (param != null) { - if (param instanceof Term) { - if (((Term) param).getType() == null) { - ((Term) param).setType(var.getType()); + if (jsonTerm instanceof JsonTerm || jsonTerm.getSymbol().equals(DataConstraintModel.addMember)) { + String constructorInvocation = "new " + replacingClassName + "("; + MethodDeclaration childConstructor = getConstructor(childComponent); + String delimiter = ""; + for (VariableDeclaration var: childConstructor.getParameters()) { + JsonAccessor jsonMember = new JsonAccessor(DataConstraintModel.dot); + jsonMember.addChild(jsonTerm); + jsonMember.addChild(new Constant(var.getName(), DataConstraintModel.typeString)); + Expression param = jsonMember.reduce(); + if (param != null) { + if (param instanceof Term) { + if (((Term) param).getType() == null) { + ((Term) param).setType(var.getType()); + } + } else if (param instanceof Variable) { + if (((Variable) param).getType() == null) { + ((Variable) param).setType(var.getType()); + } } - } else if (param instanceof Variable) { - if (((Variable) param).getType() == null) { - ((Variable) param).setType(var.getType()); - } + constructorInvocation = constructorInvocation + delimiter + param.toImplementation(null); + } else { + constructorInvocation = constructorInvocation + delimiter + var.getName(); } - constructorInvocation = constructorInvocation + delimiter + param.toImplementation(null); - } else { - constructorInvocation = constructorInvocation + delimiter + var.getName(); + delimiter = ", "; } - delimiter = ", "; + constructorInvocation += ")"; + ((Term) exp).replaceSubTerm(termEnt.getKey(), new Constant(constructorInvocation)); + subTerms = ((Term) exp).getSubTerms(Term.class); + termEntItr = subTerms.entrySet().iterator(); } - constructorInvocation += ")"; - ((Term) exp).replaceSubTerm(termEnt.getKey(), new Constant(constructorInvocation)); - subTerms = ((Term) exp).getSubTerms(Term.class); - termEntItr = subTerms.entrySet().iterator(); } } } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java index d476588..ffcc360 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java @@ -34,6 +34,7 @@ import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.JsonAccessor; +import models.dataConstraintModel.JsonTerm; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; import models.dataConstraintModel.Selector; @@ -130,15 +131,20 @@ } updateExp = ch.deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor, inputResourceToStateAccessor).getKey(); } - // Replace Json constructor with a constructor of the child resource. + // Replace Json constructor with a constructor of a descendant resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { - ResourceHierarchy childRes = outRes.getChildren().iterator().next(); - Type childStateType = childRes.getResourceStateType(); - String childComponentName = JerseyCodeGenerator.getComponentName(childRes); - TypeDeclaration childComponent = componentMap.get(childComponentName); - if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) { - replaceJsonTermWithConstructorInvocation(updateExp, childStateType, childComponentName, childComponent); + ResourceHierarchy descendantRes = outRes.getChildren().iterator().next(); + Set children; + do { + if (JerseyCodeGenerator.generatesComponent(descendantRes)) break; + children = descendantRes.getChildren(); + } while (children != null && children.size() == 1 && (descendantRes = children.iterator().next()) != null); + Type descendantStateType = descendantRes.getResourceStateType(); + String descendantComponentName = JerseyCodeGenerator.getComponentName(descendantRes); + TypeDeclaration descendantComponent = componentMap.get(descendantComponentName); + if (DataConstraintModel.typeJson.isAncestorOf(descendantStateType)) { + replaceJsonTermWithConstructorInvocation(updateExp, descendantStateType, descendantComponentName, descendantComponent); } } // Replace the type of the state field. @@ -875,15 +881,20 @@ } } Expression updateExp = ch.deriveUpdateExpressionOf(out, JerseyCodeGenerator.refAccessor).getKey(); - // Replace Json constructor with a constructor of the child resource. + // Replace Json constructor with a constructor of a descendant resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { - ResourceHierarchy childRes = outRes.getChildren().iterator().next(); - Type childStateType = childRes.getResourceStateType(); - String childComponentName = JerseyCodeGenerator.getComponentName(childRes); - TypeDeclaration childComponent = componentMap.get(childComponentName); - if (DataConstraintModel.typeJson.isAncestorOf(childStateType)) { - replaceJsonTermWithConstructorInvocation(updateExp, childStateType, childComponentName, childComponent); + ResourceHierarchy descendantRes = outRes.getChildren().iterator().next(); + Set children; + do { + if (JerseyCodeGenerator.generatesComponent(descendantRes)) break; + children = descendantRes.getChildren(); + } while (children != null && children.size() == 1 && (descendantRes = children.iterator().next()) != null); + Type descendantStateType = descendantRes.getResourceStateType(); + String descendantComponentName = JerseyCodeGenerator.getComponentName(descendantRes); + TypeDeclaration descendantComponent = componentMap.get(descendantComponentName); + if (DataConstraintModel.typeJson.isAncestorOf(descendantStateType)) { + replaceJsonTermWithConstructorInvocation(updateExp, descendantStateType, descendantComponentName, descendantComponent); } } // Replace the type of the state field. @@ -1004,34 +1015,36 @@ Entry termEnt = termEntItr.next(); Term jsonTerm = termEnt.getValue(); if (jsonTerm.getType() != null && jsonTerm.getType().equals(replacedJsonType)) { - String constructorInvocation = "new " + replacingClassName + "("; - MethodDeclaration childConstructor = getConstructor(childComponent); - String delimiter = ""; - for (VariableDeclaration var: childConstructor.getParameters()) { - JsonAccessor jsonMember = new JsonAccessor(DataConstraintModel.dot); - jsonMember.addChild(jsonTerm); - jsonMember.addChild(new Constant(var.getName(), DataConstraintModel.typeString)); - Expression param = jsonMember.reduce(); - if (param != null) { - if (param instanceof Term) { - if (((Term) param).getType() == null) { - ((Term) param).setType(var.getType()); + if (jsonTerm instanceof JsonTerm || jsonTerm.getSymbol().equals(DataConstraintModel.addMember)) { + String constructorInvocation = "new " + replacingClassName + "("; + MethodDeclaration childConstructor = getConstructor(childComponent); + String delimiter = ""; + for (VariableDeclaration var: childConstructor.getParameters()) { + JsonAccessor jsonMember = new JsonAccessor(DataConstraintModel.dot); + jsonMember.addChild(jsonTerm); + jsonMember.addChild(new Constant(var.getName(), DataConstraintModel.typeString)); + Expression param = jsonMember.reduce(); + if (param != null) { + if (param instanceof Term) { + if (((Term) param).getType() == null) { + ((Term) param).setType(var.getType()); + } + } else if (param instanceof Variable) { + if (((Variable) param).getType() == null) { + ((Variable) param).setType(var.getType()); + } } - } else if (param instanceof Variable) { - if (((Variable) param).getType() == null) { - ((Variable) param).setType(var.getType()); - } + constructorInvocation = constructorInvocation + delimiter + param.toImplementation(null); + } else { + constructorInvocation = constructorInvocation + delimiter + var.getName(); } - constructorInvocation = constructorInvocation + delimiter + param.toImplementation(null); - } else { - constructorInvocation = constructorInvocation + delimiter + var.getName(); + delimiter = ", "; } - delimiter = ", "; + constructorInvocation += ")"; + ((Term) exp).replaceSubTerm(termEnt.getKey(), new Constant(constructorInvocation)); + subTerms = ((Term) exp).getSubTerms(Term.class); + termEntItr = subTerms.entrySet().iterator(); } - constructorInvocation += ")"; - ((Term) exp).replaceSubTerm(termEnt.getKey(), new Constant(constructorInvocation)); - subTerms = ((Term) exp).getSubTerms(Term.class); - termEntItr = subTerms.entrySet().iterator(); } } }