diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index f2c704b..b23a6a3 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -1046,7 +1046,7 @@ // to get a descendant resource directly. (e.g, .todos.{year}.{month}.{day}.{id} ==> .getTodos().getTodo(year, month, day, id)) if (doesChainInvocations) { Term newGetter = new Term(new Symbol(getterPrefix + typeName, -1, Symbol.Type.METHOD)); - if (getter != null) newGetter.addChild(getter); + newGetter.addChild(getter); getter = newGetter; doesChainInvocations = false; } @@ -1165,7 +1165,7 @@ // to get a descendant resource directly. (e.g, .todos.{year}.{month}.{day}.{id} ==> .getTodos().getTodo(year, month, day, id)) if (doesChainInvocations) { Term newGetter = new Term(new Symbol(getterPrefix + typeName, -1, Symbol.Type.METHOD)); - if (getter != null) newGetter.addChild(getter); + newGetter.addChild(getter); getter = newGetter; doesChainInvocations = false; } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index f3d9070..44f8bbf 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -1561,6 +1561,7 @@ do { descendantRes = children.iterator().next(); if (generatesComponent(descendantRes)) { + // If there exists at least one descendant resource whose component is not to be generated. updateStatements.put(update, new AbstractMap.SimpleEntry<>(updateExp, new AbstractMap.SimpleEntry<>(outRes, descendantRes))); updateExp = null; break; @@ -1568,105 +1569,108 @@ children = descendantRes.getChildren(); } while (children != null && children.size() == 1); } - // Replace the type of the state field. - Type fieldType = getImplStateType(outRes, langSpec); - if (updateExp instanceof Term) { - ((Term) updateExp).setType(fieldType); - for (Map.Entry varEnt: ((Term) updateExp).getVariables().entrySet()) { - if (varEnt.getValue().getName().equals(fieldOfResourceState)) { - varEnt.getValue().setType(fieldType); + // Add statements to the update method. + if (updateExp != null) { + // Replace the type of the state field. + Type fieldType = getImplStateType(outRes, langSpec); + if (updateExp instanceof Term) { + ((Term) updateExp).setType(fieldType); + for (Map.Entry varEnt: ((Term) updateExp).getVariables().entrySet()) { + if (varEnt.getValue().getName().equals(fieldOfResourceState)) { + varEnt.getValue().setType(fieldType); + } + } + } else if (updateExp instanceof Variable) { + ((Variable) updateExp).setType(fieldType); + } + // Add statements to the update method. + String[] sideEffects = new String[] {""}; + String newState = updateExp.toImplementation(sideEffects); + int numOfOutResourcesWithTheSameHierarchy = 0; + for (ResourcePath outResPath: ch.getOutputResources()) { + if (outResPath.getResourceHierarchy().equals(outRes)) { + numOfOutResourcesWithTheSameHierarchy++; } } - } else if (updateExp instanceof Variable) { - ((Variable) updateExp).setType(fieldType); - } - // Add statements to the update method. - String[] sideEffects = new String[] {""}; - String newState = updateExp.toImplementation(sideEffects); - int numOfOutResourcesWithTheSameHierarchy = 0; - for (ResourcePath outResPath: ch.getOutputResources()) { - if (outResPath.getResourceHierarchy().equals(outRes)) { - numOfOutResourcesWithTheSameHierarchy++; - } - } - String updateStatement = ""; - if (generatesComponent(outRes)) { - if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; - if (updateStatement.endsWith("\n")) { - updateStatement = updateStatement.substring(0, updateStatement.length() - 1); + String updateStatement = ""; + if (generatesComponent(outRes)) { + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + if (updateStatement.endsWith("\n")) { + updateStatement = updateStatement.substring(0, updateStatement.length() - 1); + } + } else { + updateStatement = sideEffects[0] + langSpec.getFieldAccessor(fieldOfResourceState) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); // this.value = ... } } else { - updateStatement = sideEffects[0] + langSpec.getFieldAccessor(fieldOfResourceState) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); // this.value = ... - } - } else { - if (sideEffects[0] != null) { - updateStatement = sideEffects[0]; - String resourceName = langSpec.toVariableName(getComponentName(outRes, langSpec)); - updateStatement = updateStatement.replace(langSpec.getFieldAccessor(fieldOfResourceState), langSpec.getFieldAccessor(resourceName)); - if (updateStatement.endsWith("\n")) { - updateStatement = updateStatement.substring(0, updateStatement.length() - 1); + if (sideEffects[0] != null) { + updateStatement = sideEffects[0]; + String resourceName = langSpec.toVariableName(getComponentName(outRes, langSpec)); + updateStatement = updateStatement.replace(langSpec.getFieldAccessor(fieldOfResourceState), langSpec.getFieldAccessor(resourceName)); + if (updateStatement.endsWith("\n")) { + updateStatement = updateStatement.substring(0, updateStatement.length() - 1); + } + } + if (DataConstraintModel.typeList.isAncestorOf(resourceNode.getParent().getResourceStateType())) { + Term selector = new Term(DataConstraintModel.set); + selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); + selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); + selector.addChild(new Constant(newState)); + String[] sideEffects2 = new String[] {""}; + String newList = selector.toImplementation(sideEffects2); + updateStatement += sideEffects2[0]; + } else if (DataConstraintModel.typeMap.isAncestorOf(resourceNode.getParent().getResourceStateType())) { + Term selector = new Term(DataConstraintModel.insert); + selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); + selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); + selector.addChild(new Constant(newState)); + String[] sideEffects2 = new String[] {""}; + String newMap = selector.toImplementation(sideEffects2); + updateStatement += sideEffects2[0]; + } else if (!(updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect())) { + String resourceName = langSpec.toVariableName(getComponentName(outRes, langSpec)); + updateStatement += langSpec.getFieldAccessor(resourceName) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); } } - if (DataConstraintModel.typeList.isAncestorOf(resourceNode.getParent().getResourceStateType())) { - Term selector = new Term(DataConstraintModel.set); - selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); - selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); - selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[] {""}; - String newList = selector.toImplementation(sideEffects2); - updateStatement += sideEffects2[0]; - } else if (DataConstraintModel.typeMap.isAncestorOf(resourceNode.getParent().getResourceStateType())) { - Term selector = new Term(DataConstraintModel.insert); - selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); - selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); - selector.addChild(new Constant(newState)); - String[] sideEffects2 = new String[] {""}; - String newMap = selector.toImplementation(sideEffects2); - updateStatement += sideEffects2[0]; - } else if (!(updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect())) { - String resourceName = langSpec.toVariableName(getComponentName(outRes, langSpec)); - updateStatement += langSpec.getFieldAccessor(resourceName) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); - } - } - // add an update statement of the state of dst side resource. - if (numOfOutResourcesWithTheSameHierarchy == 1) { - update.addFirstStatement(updateStatement); - } else { - Term conditions = null; - int i = 1; - Map>> resourcePaths = ch.fillOutsideResourcePaths(out, getPushAccessor(platformSpec)); - for (Expression pathParam: out.getResource().getPathParams()) { - if (pathParam instanceof Variable) { - String selfParamName = ((Variable) pathParam).getName(); - Expression arg = null; - for (Selector selector: ch.getAllSelectors()) { - if (selector.getExpression() instanceof Variable) { - Variable selVar = (Variable) selector.getExpression(); - if (selVar.getName().equals(selfParamName)) { - arg = selVar; - break; + // add an update statement of the state of dst side resource. + if (numOfOutResourcesWithTheSameHierarchy == 1) { + update.addFirstStatement(updateStatement); + } else { + Term conditions = null; + int i = 1; + Map>> resourcePaths = ch.fillOutsideResourcePaths(out, getPushAccessor(platformSpec)); + for (Expression pathParam: out.getResource().getPathParams()) { + if (pathParam instanceof Variable) { + String selfParamName = ((Variable) pathParam).getName(); + Expression arg = null; + for (Selector selector: ch.getAllSelectors()) { + if (selector.getExpression() instanceof Variable) { + Variable selVar = (Variable) selector.getExpression(); + if (selVar.getName().equals(selfParamName)) { + arg = selVar; + break; + } } } + if (arg == null) { + ResourcePath filledPath = resourcePaths.get(out).getKey(); + arg = filledPath.getPathParams().get(i - 1); + } + Term condition = new Term(DataConstraintModel.eq, new Expression[] { + new Parameter("self" + (i > 1 ? i : ""), DataConstraintModel.typeString), + arg}); + if (conditions == null) { + conditions = condition; + } else { + conditions = new Term(DataConstraintModel.and, new Expression[] { + conditions, + condition}); + } } - if (arg == null) { - ResourcePath filledPath = resourcePaths.get(out).getKey(); - arg = filledPath.getPathParams().get(i - 1); - } - Term condition = new Term(DataConstraintModel.eq, new Expression[] { - new Parameter("self" + (i > 1 ? i : ""), DataConstraintModel.typeString), - arg}); - if (conditions == null) { - conditions = condition; - } else { - conditions = new Term(DataConstraintModel.and, new Expression[] { - conditions, - condition}); - } + i++; } - i++; + update.addFirstStatement(langSpec.getIfStatement(conditions, updateStatement)); } - update.addFirstStatement(langSpec.getIfStatement(conditions, updateStatement)); } } } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork @@ -2486,7 +2490,6 @@ } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[] {""}); // Values of channel parameters. for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { @@ -2516,7 +2519,12 @@ } } } - mainInputAccessor.addStatement(langSpec.getMethodInvocation(resourceAccess, input.getName(), args) + langSpec.getStatementDelimiter()); + if (resExp != null) { + String resourceAccess = resExp.toImplementation(new String[] {""}); + mainInputAccessor.addStatement(langSpec.getMethodInvocation(resourceAccess, input.getName(), args) + langSpec.getStatementDelimiter()); + } else { + mainInputAccessor.addStatement(langSpec.getMethodInvocation(input.getName(), args) + langSpec.getStatementDelimiter()); + } } if (input != null) { @@ -2641,7 +2649,6 @@ } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[] {""}); // Values of channel parameters. for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { @@ -2655,7 +2662,12 @@ args.add(mesVar.getName()); } } - rootInputAccessor.addStatement(langSpec.getMethodInvocation(resourceAccess, input.getName(), args) + langSpec.getStatementDelimiter()); + if (resExp != null) { + String resourceAccess = resExp.toImplementation(new String[] {""}); + rootInputAccessor.addStatement(langSpec.getMethodInvocation(resourceAccess, input.getName(), args) + langSpec.getStatementDelimiter()); + } else { + rootInputAccessor.addStatement(langSpec.getMethodInvocation(input.getName(), args) + langSpec.getStatementDelimiter()); + } if (input != null && input.getThrows() != null && ((RestApiSpecific) platformSpec).hasJsonException(input)) { ((RestApiSpecific) platformSpec).addJsonException(rootInputAccessor); } @@ -3205,11 +3217,15 @@ } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[] {""}); for (VariableDeclaration var: updateAccessor.getParameters()) { args.add(var.getName()); } - updateAccessor.addStatement(langSpec.getMethodInvocation(resourceAccess, updateMethodName, args) + langSpec.getStatementDelimiter()); + if (resExp != null) { + String resourceAccess = resExp.toImplementation(new String[] {""}); + updateAccessor.addStatement(langSpec.getMethodInvocation(resourceAccess, updateMethodName, args) + langSpec.getStatementDelimiter()); + } else { + updateAccessor.addStatement(langSpec.getMethodInvocation(updateMethodName, args) + langSpec.getStatementDelimiter()); + } rootComponent.addMethod(updateAccessor); } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java index 7d89968..ff28368 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java @@ -1230,7 +1230,6 @@ } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[] {null}); // Values of channel parameters. for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { @@ -1268,7 +1267,12 @@ argsStr += delimiter + arg; delimiter = ", "; } - inputAccessor.addStatement(resourceAccess + "." + input.getName() + "(" + argsStr + ");"); + if (resExp != null) { + String resourceAccess = resExp.toImplementation(new String[] {null}); + inputAccessor.addStatement(resourceAccess + "." + input.getName() + "(" + argsStr + ");"); + } else { + inputAccessor.addStatement(input.getName() + "(" + argsStr + ");"); + } } } } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java index abd1e02..c452d91 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java @@ -327,7 +327,6 @@ } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[] {""}); int v = 0; for (VariableDeclaration var: update2.getParameters()) { if (v < out.getResource().getPathParams().size()) { @@ -342,7 +341,12 @@ delimiter = ", "; v++; } - update.addStatement(resourceAccess + "." + update2.getName() + "(" + args + ");"); + if (resExp != null) { + String resourceAccess = resExp.toImplementation(new String[] {""}); + update.addStatement(resourceAccess + "." + update2.getName() + "(" + args + ");"); + } else { + update.addStatement(update2.getName() + "(" + args + ");"); + } } // to convert a json param to a tuple, pair or map object. for (VariableDeclaration param: update.getParameters()) { @@ -1342,7 +1346,6 @@ } resExp = ((Term) resExp).getChild(0); } - String resourceAccess = resExp.toImplementation(new String[] {""}); // Values of channel parameters. for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { @@ -1358,7 +1361,12 @@ delimiter = ", "; } } - inputAccessor.addStatement(resourceAccess + "." + input.getName() + "(" + args + ");"); + if (resExp != null) { + String resourceAccess = resExp.toImplementation(new String[] {""}); + inputAccessor.addStatement(resourceAccess + "." + input.getName() + "(" + args + ");"); + } else { + inputAccessor.addStatement(input.getName() + "(" + args + ");"); + } if (input != null && input.getThrows() != null && input.getThrows().getExceptions().contains("JsonProcessingException")) { inputAccessor.addThrow("JsonProcessingException"); } diff --git a/AlgebraicDataflowArchitectureModel/src/tests/JAXRSCodeGeneratorTest.java b/AlgebraicDataflowArchitectureModel/src/tests/JAXRSCodeGeneratorTest.java index 9df8290..8fb7c44 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/JAXRSCodeGeneratorTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/JAXRSCodeGeneratorTest.java @@ -1276,8 +1276,8 @@ } TypeInference.infer(model); DataTransferMethodAnalyzer.decideToStoreResourceStates(graph); - ArrayList codetree = JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model)); -// ArrayList codetree = new CodeGeneratorFromDataFlowGraph().generateCode(model, graph, new JerseySpecific(), new JavaSpecific()); +// ArrayList codetree = JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model)); + ArrayList codetree = new CodeGeneratorFromDataFlowGraph().generateCode(model, graph, new JerseySpecific(), new JavaSpecific()); return codetree; } diff --git a/AlgebraicDataflowArchitectureModel/src/tests/JavaCodeGeneratorTest.java b/AlgebraicDataflowArchitectureModel/src/tests/JavaCodeGeneratorTest.java index b9a5dc0..8128ce4 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/JavaCodeGeneratorTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/JavaCodeGeneratorTest.java @@ -1438,8 +1438,8 @@ } TypeInference.infer(model); DataTransferMethodAnalyzer.decideToStoreResourceStates(graph); - ArrayList codetree = JavaMethodBodyGenerator.doGenerate(graph, model, JavaCodeGenerator.doGenerate(graph, model)); -// ArrayList codetree = new CodeGeneratorFromDataFlowGraph().generateCode(model, graph, new StandaloneSpecific(), new JavaSpecific()); +// ArrayList codetree = JavaMethodBodyGenerator.doGenerate(graph, model, JavaCodeGenerator.doGenerate(graph, model)); + ArrayList codetree = new CodeGeneratorFromDataFlowGraph().generateCode(model, graph, new StandaloneSpecific(), new JavaSpecific()); return codetree; }