diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 39de6cd..ea45a55 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -937,9 +937,26 @@ v++; } } - for (Variable var: message.getVariables().values()) { - resInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); - mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + for (Map.Entry varEnt: message.getVariables().entrySet()) { + Variable var = varEnt.getValue(); + String refVarName = null; + for (ChannelMember refCm: ((DataTransferChannel) ch).getReferenceChannelMembers()) { + Expression varExp = refCm.getStateTransition().getMessageExpression().getSubTerm(varEnt.getKey()); + if (varExp != null && varExp instanceof Variable) { + if (refCm.getStateTransition().getCurStateExpression().contains(varExp)) { + refVarName = refCm.getResource().getResourceName(); + break; + } + } + } + if (refVarName != null) { + // var has come from a reference resource. + resInputParams.add(langSpec.newVariableDeclaration(var.getType(), refVarName)); + } else { + // var has not come from a reference resource. + resInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + } } input = langSpec.newMethodDeclaration(((Term) message).getSymbol().getImplName(), false, null, resInputParams); if (component != null) { @@ -1028,6 +1045,18 @@ // Add an invocation to the accessor method. if (inputAccessor != null) { + for (ChannelMember rc: ((DataTransferChannel) ch).getReferenceChannelMembers()) { + // For each reference channel member, get the current state of the reference side resource by pull data transfer. + ResourcePath ref = rc.getResource(); + if (!out.getResource().equals(ref)) { + String refVarName = ref.getResourceName(); + Expression refGetter = JavaCodeGenerator.pullAccessor.getDirectStateAccessorFor(ref, null); + String[] sideEffects = new String[] {""}; + String refExp = refGetter.toImplementation(sideEffects); + String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); + inputAccessor.addFirstStatement(sideEffects[0] + refTypeName + " " + refVarName + " = " + refExp + ";"); + } + } Expression resExp = getPullAccessor().getDirectStateAccessorFor(out.getResource(), null); List args = new ArrayList<>(); if (resExp instanceof Term) { @@ -1039,8 +1068,20 @@ } String resourceAccess = resExp.toImplementation(new String[] {null}); if (message instanceof Term) { - for (Variable var: message.getVariables().values()) { - args.add(var.getName()); + for (Map.Entry varEnt: message.getVariables().entrySet()) { + String refVarName = null; + for (ChannelMember rc: ((DataTransferChannel) ch).getReferenceChannelMembers()) { + Expression varExp = rc.getStateTransition().getMessageExpression().getSubTerm(varEnt.getKey()); + if (varExp != null && rc.getStateTransition().getCurStateExpression().contains(varExp)) { + refVarName = rc.getResource().getResourceName(); + break; + } + } + if (refVarName != null) { + args.add(refVarName); + } else { + args.add(varEnt.getValue().getName()); + } } } inputAccessor.addStatement(langSpec.getMethodInvocation(resourceAccess, input.getName(), args) + langSpec.getStatementDelimiter()); @@ -1049,7 +1090,7 @@ if (input != null) { // Add a statement to update the state field to the input method. try { - Expression updateExp = ((DataTransferChannel) ch).deriveUpdateExpressionOf(out, getPullAccessor()); + Expression updateExp = ((DataTransferChannel) ch).deriveUpdateExpressionOf(out, getRefAccessor()); // Replace Json constructor with a constructor of the child resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java index b15569b..76971ed 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java @@ -23,6 +23,7 @@ import models.algebra.Expression; import models.algebra.Field; import models.algebra.Parameter; +import models.algebra.Position; import models.algebra.Symbol; import models.algebra.Term; import models.algebra.Type; @@ -610,9 +611,26 @@ v++; } } - for (Variable var: message.getVariables().values()) { - resInputParams.add(new VariableDeclaration(var.getType(), var.getName())); - mainInputParams.add(new VariableDeclaration(var.getType(), var.getName())); + for (Map.Entry varEnt: message.getVariables().entrySet()) { + Variable var = varEnt.getValue(); + String refVarName = null; + for (ChannelMember refCm: ((DataTransferChannel) ch).getReferenceChannelMembers()) { + Expression varExp = refCm.getStateTransition().getMessageExpression().getSubTerm(varEnt.getKey()); + if (varExp != null && varExp instanceof Variable) { + if (refCm.getStateTransition().getCurStateExpression().contains(varExp)) { + refVarName = refCm.getResource().getResourceName(); + break; + } + } + } + if (refVarName != null) { + // var has come from a reference resource. + resInputParams.add(new VariableDeclaration(var.getType(), refVarName)); + } else { + // var has not come from a reference resource. + resInputParams.add(new VariableDeclaration(var.getType(), var.getName())); + mainInputParams.add(new VariableDeclaration(var.getType(), var.getName())); + } } MethodDeclaration input = new MethodDeclaration( ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(), diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java index 083520a..443d7bf 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java @@ -509,7 +509,7 @@ } if (input != null) { // In each resource - Expression updateExp = entry.getKey().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); + Expression updateExp = entry.getKey().deriveUpdateExpressionOf(out, JavaCodeGenerator.refAccessor); // Replace Json constructor with a constructor of the child resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { @@ -569,6 +569,26 @@ if (mainComponent != null) { MethodDeclaration inputAccessor = getMethod(mainComponent, input.getName()); if (inputAccessor != null) { + Set referredSet = referredResources.get(input); + for (ChannelMember rc: entry.getKey().getReferenceChannelMembers()) { + // For each reference channel member, get the current state of the reference side resource by pull data transfer. + ResourcePath ref = rc.getResource(); + if (referredSet == null) { + referredSet = new HashSet<>(); + referredResources.put(input, referredSet); + } + if (!out.getResource().equals(ref)) { + String refVarName = ref.getResourceName(); + if (!referredSet.contains(ref)) { + referredSet.add(ref); + Expression refGetter = JavaCodeGenerator.pullAccessor.getDirectStateAccessorFor(ref, null); + sideEffects = new String[] {""}; + String refExp = refGetter.toImplementation(sideEffects); + String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); + inputAccessor.addFirstStatement(sideEffects[0] + refTypeName + " " + refVarName + " = " + refExp + ";"); + } + } + } Expression resExp = JavaCodeGenerator.pullAccessor.getDirectStateAccessorFor(out.getResource(), null); String args = ""; String delimiter = ""; @@ -583,8 +603,20 @@ String resourceAccess = resExp.toImplementation(new String[] {null}); if (out.getStateTransition().getMessageExpression() instanceof Term) { Term message = (Term) out.getStateTransition().getMessageExpression(); - for (Variable var: message.getVariables().values()) { - args += delimiter + var.getName(); + for (Map.Entry varEnt: message.getVariables().entrySet()) { + String refVarName = null; + for (ChannelMember rc: entry.getKey().getReferenceChannelMembers()) { + Expression varExp = rc.getStateTransition().getMessageExpression().getSubTerm(varEnt.getKey()); + if (varExp != null && rc.getStateTransition().getCurStateExpression().contains(varExp)) { + refVarName = rc.getResource().getResourceName(); + break; + } + } + if (refVarName != null) { + args += delimiter + refVarName; + } else { + args += delimiter + varEnt.getValue().getName(); + } delimiter = ", "; } } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java index 7e81d3b..b791f97 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java @@ -23,6 +23,7 @@ import models.algebra.Expression; import models.algebra.Field; import models.algebra.Parameter; +import models.algebra.Position; import models.algebra.Symbol; import models.algebra.Term; import models.algebra.Type; @@ -535,13 +536,31 @@ } else { resourcePath = "\"" + resourcePath + "\""; } - for (Variable var: message.getVariables().values()) { - String paramName = var.getName(); - VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); - resInputParams.add(param); - param = new VariableDeclaration(var.getType(), paramName); - param.addAnnotation(new Annotation("FormParam", "\"" + paramName + "\"")); - rootInputParams.add(param); + for (Map.Entry varEnt: message.getVariables().entrySet()) { + Variable var = varEnt.getValue(); + String refVarName = null; + for (ChannelMember refCm: ((DataTransferChannel) ch).getReferenceChannelMembers()) { + Expression varExp = refCm.getStateTransition().getMessageExpression().getSubTerm(varEnt.getKey()); + if (varExp != null && varExp instanceof Variable) { + if (refCm.getStateTransition().getCurStateExpression().contains(varExp)) { + refVarName = refCm.getResource().getResourceName(); + break; + } + } + } + if (refVarName != null) { + // var has come from a reference resource. + VariableDeclaration param = new VariableDeclaration(var.getType(), refVarName); + resInputParams.add(param); + } else { + // var has not come from reference resource. + String paramName = var.getName(); + VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); + resInputParams.add(param); + param = new VariableDeclaration(var.getType(), paramName); + param.addAnnotation(new Annotation("FormParam", "\"" + paramName + "\"")); + rootInputParams.add(param); + } } if (rn.getResourceHierarchy().getParent() != null && rn.getResourceHierarchy().getParent().getParent() != null) { diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java index a04e044..e04d2c6 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java @@ -288,16 +288,24 @@ if (!chainedCalls.contains(srcUpdate)) { // The first call to an update method in this method // Value of the source side (input side) resource. - params.add(0, new AbstractMap.SimpleEntry<>(src.getResourceStateType(), new AbstractMap.SimpleEntry<>(srcResourceName, "this.value"))); + params.add(0, new AbstractMap.SimpleEntry<>(src.getResourceStateType(), + new AbstractMap.SimpleEntry<>(JerseyCodeGenerator.toVariableName(srcResourceName), "this.value"))); srcUpdate.addStatement(getHttpMethodParamsStatement(srcComponent.getTypeName(), params, true)); - srcUpdate.addStatement("String result = " + getHttpMethodCallStatement(baseURL, dstResourceName, srcResName, httpMethod)); + srcUpdate.addStatement("String result = " + getHttpMethodCallStatement(baseURL, + JerseyCodeGenerator.toVariableName(dstResourceName), + JerseyCodeGenerator.toVariableName(srcResName), + httpMethod)); chainedCalls.add(srcUpdate); } else { // After the second time of call to update methods in this method // Value of the source side (input side) resource. - params.add(0, new AbstractMap.SimpleEntry<>(src.getResourceStateType(), new AbstractMap.SimpleEntry<>(srcResourceName, "this.value"))); + params.add(0, new AbstractMap.SimpleEntry<>(src.getResourceStateType(), + new AbstractMap.SimpleEntry<>(JerseyCodeGenerator.toVariableName(srcResourceName), "this.value"))); srcUpdate.addStatement(getHttpMethodParamsStatement(srcComponent.getTypeName(), params, false)); - srcUpdate.addStatement("result = " + getHttpMethodCallStatement(baseURL, dstResourceName, srcResName, httpMethod)); + srcUpdate.addStatement("result = " + getHttpMethodCallStatement(baseURL, + JerseyCodeGenerator.toVariableName(dstResourceName), + JerseyCodeGenerator.toVariableName(srcResName), + httpMethod)); } srcUpdate.addThrow("JsonProcessingException"); } @@ -330,16 +338,24 @@ if (!chainedCalls.contains(srcInput)) { // First call to an update method in this method // Value of the source side (input side) resource. - params.add(0, new AbstractMap.SimpleEntry<>(src.getResourceStateType(), new AbstractMap.SimpleEntry<>(srcResourceName, "this.value"))); + params.add(0, new AbstractMap.SimpleEntry<>(src.getResourceStateType(), + new AbstractMap.SimpleEntry<>(JerseyCodeGenerator.toVariableName(srcResourceName), "this.value"))); srcInput.addStatement(getHttpMethodParamsStatement(srcComponent.getTypeName(), params, true)); - srcInput.addStatement("String result = " + getHttpMethodCallStatement(baseURL, dstResourceName, srcResName, httpMethod)); + srcInput.addStatement("String result = " + getHttpMethodCallStatement(baseURL, + JerseyCodeGenerator.toVariableName(dstResourceName), + JerseyCodeGenerator.toVariableName(srcResName), + httpMethod)); chainedCalls.add(srcInput); } else { // After the second time of call to update methods in this method // Value of the source side (input side) resource. - params.add(0, new AbstractMap.SimpleEntry<>(src.getResourceStateType(), new AbstractMap.SimpleEntry<>(srcResourceName, "this.value"))); + params.add(0, new AbstractMap.SimpleEntry<>(src.getResourceStateType(), + new AbstractMap.SimpleEntry<>(JerseyCodeGenerator.toVariableName(srcResourceName), "this.value"))); srcInput.addStatement(getHttpMethodParamsStatement(srcComponent.getTypeName(), params, false)); - srcInput.addStatement("result = " + getHttpMethodCallStatement(baseURL, dstResourceName, srcResName, httpMethod)); + srcInput.addStatement("result = " + getHttpMethodCallStatement(baseURL, + JerseyCodeGenerator.toVariableName(dstResourceName), + JerseyCodeGenerator.toVariableName(srcResName), + httpMethod)); } srcInput.addThrow("JsonProcessingException"); } @@ -507,7 +523,24 @@ } if (input != null) { // In each resource - Expression updateExp = entry.getKey().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor); + Set referredSet = referredResources.get(input); + for (ChannelMember rc: entry.getKey().getReferenceChannelMembers()) { + // For each reference channel member, get the current state of the reference side resource by pull data transfer. + ResourcePath ref = rc.getResource(); + if (referredSet == null) { + referredSet = new HashSet<>(); + referredResources.put(input, referredSet); + } + if (!out.getResource().equals(ref)) { + String refResourceName = ref.getResourceName(); + Type refResourceType = ref.getResourceStateType(); + if (!referredSet.contains(ref)) { + referredSet.add(ref); + generatePullDataTransfer(input, refResourceName, refResourceName, refResourceType); + } + } + } + Expression updateExp = entry.getKey().deriveUpdateExpressionOf(out, JerseyCodeGenerator.refAccessor); // Replace Json constructor with a constructor of the child resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { @@ -530,7 +563,7 @@ updateStatement = sideEffects[0] + "this.value = " + newState + ";"; } if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { - input.addFirstStatement(updateStatement); + input.addStatement(updateStatement); } } else { String updateStatement = null; @@ -558,7 +591,7 @@ updateStatement = sideEffects[0] + "this." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(resource)) + " = " + newState + ";"; } if (updateStatement != null && (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement))) { - input.addFirstStatement(updateStatement); + input.addStatement(updateStatement); } } }