diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index eacaf25..37bf0f2 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -61,6 +61,7 @@ public static final Type presenterType = new Type("SwingPresenter", "SwingPresenter"); private static String mainTypeName = null; private static HashMap> componentNames = new HashMap<>(); + protected Map>> updateMethods; protected ILanguageSpecific langSpec = null; protected IPlatformSpecific platformSpec = null; @@ -162,6 +163,7 @@ public ArrayList generateCode(DataTransferModel model, DataFlowGraph flowGraph, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { this.langSpec = langSpec; this.platformSpec = platformSpec; + this.updateMethods = new HashMap<>(); ArrayList codes = new ArrayList<>(); Map> dependedRootComponentGraph = null; @@ -512,6 +514,28 @@ } } + protected String getUpdateMethodName(ResourceHierarchy srcRes, ResourceHierarchy dstRes, DataTransferChannel ch) { + Map> dstResUpdatesMethods = updateMethods.getOrDefault(dstRes, new HashMap<>()); + updateMethods.put(dstRes, dstResUpdatesMethods); + Map dstResFromSrcResUpdatesMethods = dstResUpdatesMethods.getOrDefault(srcRes, new HashMap<>()); + dstResUpdatesMethods.put(srcRes, dstResFromSrcResUpdatesMethods); + String updateMethodName = dstResFromSrcResUpdatesMethods.get(ch); + if (updateMethodName == null) { + String srcResComponentName = getComponentName(srcRes, langSpec); + String dstResComponentName = getComponentName(dstRes, langSpec); + if (generatesComponent(dstRes)) { + updateMethodName = updateMethodPrefix + from + srcResComponentName; + } else if (dstRes.getParent() != null) { + updateMethodName = updateMethodPrefix + dstResComponentName + from + srcResComponentName; + } + if (dstResFromSrcResUpdatesMethods.size() > 0) { + updateMethodName += dstResFromSrcResUpdatesMethods.size() + 1; // To avoid declaring the method multiply. + } + dstResFromSrcResUpdatesMethods.put(ch, updateMethodName); + } + return updateMethodName; + } + protected MethodDeclaration getConstructor(TypeDeclaration component) { for (MethodDeclaration m: component.getMethods()) { if (m.isConstructor()) return m; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 69bcf51..4237555 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -62,12 +62,10 @@ public class CodeGeneratorFromDataFlowGraph extends CodeGenerator { protected Map resourceHierarchyToComponent; protected Map> constructorParams; - protected Map>> updateMethods; public void generateCodeFromFlowGraph(DataTransferModel model, DataFlowGraph flowGraph, Collection components, ArrayList codes, Map> dependedRootComponentGraph) { resourceHierarchyToComponent = new HashMap<>(); constructorParams = new HashMap<>(); - updateMethods = new HashMap<>(); Map resourceConstructors = new HashMap<>(); List> constructorStatements = new ArrayList<>(); Map>> updateStatements = new HashMap<>(); @@ -2913,6 +2911,24 @@ } params.addAll(refParams); + // Create a guard condition. + Term guardCondition = null; + for (Map.Entry paramEnt: in.getResource().getPathParamsAndConstraints()) { + if (paramEnt.getValue() != null) { + Term newCondition = new Term(DataConstraintModel.eq); + newCondition.addChild(paramEnt.getKey(), true); + newCondition.addChild(paramEnt.getValue(), true); + if (guardCondition == null) { + guardCondition = newCondition; + } else { + Term composedCondition = new Term(DataConstraintModel.and); + composedCondition.addChild(guardCondition, true); + composedCondition.addChild(newCondition, true); + guardCondition = composedCondition; + } + } + } + // Call the update method. ResourceHierarchy dstRes = dstNode.getResourceHierarchy(); String updateMethodName = getUpdateMethodName(srcNode.getResourceHierarchy(), dstRes, ch); // Get the method name. @@ -2967,8 +2983,15 @@ if (!hasUpdateMethodinvoked) { // The first call to an update method in this method callerMethod.addStatement(restApiSpec.getHttpMethodParamsConstructionStatement(srcRes.getResourceName(), params, true)); - callerMethod.addStatement(langSpec.getVariableDeclaration(DataConstraintModel.typeString.getInterfaceTypeName(), "result") - + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, srcResName, httpMethod)); + String httpMethodCall = langSpec.getVariableDeclaration(DataConstraintModel.typeString.getInterfaceTypeName(), "result") + + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, srcResName, httpMethod); + if (guardCondition == null) { + // Non-conditional http method call. + callerMethod.addStatement(httpMethodCall); + } else { + // Conditional http method call by a guarded state transition. + callerMethod.addStatement(langSpec.getIfStatement(guardCondition, httpMethodCall)); + } if (srcComponent != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(srcComponent)) { // Declare a client field to connect to the destination resource of push transfer. ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(srcComponent); @@ -2983,7 +3006,14 @@ } else { // After the second time of call to update methods in this method callerMethod.addStatement(restApiSpec.getHttpMethodParamsConstructionStatement(srcRes.getResourceName(), params, false)); - callerMethod.addStatement("result" + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, srcResName, httpMethod)); + String httpMethodCall = "result" + langSpec.getAssignment() + restApiSpec.getHttpMethodCallStatement(restApiSpec.getBaseURL(), dstPath, srcResName, httpMethod); + if (guardCondition == null) { + // Non-conditional http method call. + callerMethod.addStatement(httpMethodCall); + } else { + // Conditional http method call by a guarded state transition. + callerMethod.addStatement(langSpec.getIfStatement(guardCondition, httpMethodCall)); + } if (srcComponent != null && !((RestApiSpecific) platformSpec).hasHttpClientFieldDeclaration(srcComponent)) { // Declare a client field to connect to the destination resource of push transfer. ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(srcComponent); @@ -3004,8 +3034,16 @@ for (Map.Entry> paramEnt: params) { args.add(paramEnt.getValue().getValue()); } - callerMethod.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); + String methodInvocation = null; + methodInvocation = langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) + + langSpec.getStatementDelimiter(); // this.dst.updateDstFromSrc(value, refParams); + if (guardCondition == null) { + // Non-conditional invocation. + callerMethod.addStatement(methodInvocation); + } else { + // Conditional invocation by a guarded state transition. + callerMethod.addStatement(langSpec.getIfStatement(guardCondition, methodInvocation)); + } } } else { // Intra-service @@ -3017,12 +3055,20 @@ for (Map.Entry> paramEnt: params) { args.add(paramEnt.getValue().getValue()); } + String methodInvocation = null; if (srcRes != dstRes) { - callerMethod.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.dst.updateDstFromSrc(value, refParams); + methodInvocation = langSpec.getMethodInvocation(langSpec.getFieldAccessor(dstCompName), updateMethodName, args) + + langSpec.getStatementDelimiter(); // this.dst.updateDstFromSrc(value, refParams); } else { - callerMethod.addStatement(langSpec.getMethodInvocation(updateMethodName, args) - + langSpec.getStatementDelimiter()); // this.updateDstFromSrc(value, refParams); + methodInvocation = langSpec.getMethodInvocation(updateMethodName, args) + + langSpec.getStatementDelimiter(); // this.updateDstFromSrc(value, refParams); + } + if (guardCondition == null) { + // Non-conditional invocation. + callerMethod.addStatement(methodInvocation); + } else { + // Conditional invocation by a guarded state transition. + callerMethod.addStatement(langSpec.getIfStatement(guardCondition, methodInvocation)); } } if (addForStatement) { @@ -3117,28 +3163,6 @@ } return update; } - - protected String getUpdateMethodName(ResourceHierarchy srcRes, ResourceHierarchy dstRes, DataTransferChannel ch) { - Map> dstResUpdatesMethods = updateMethods.getOrDefault(dstRes, new HashMap<>()); - updateMethods.put(dstRes, dstResUpdatesMethods); - Map dstResFromSrcResUpdatesMethods = dstResUpdatesMethods.getOrDefault(srcRes, new HashMap<>()); - dstResUpdatesMethods.put(srcRes, dstResFromSrcResUpdatesMethods); - String updateMethodName = dstResFromSrcResUpdatesMethods.get(ch); - if (updateMethodName == null) { - String srcResComponentName = getComponentName(srcRes, langSpec); - String dstResComponentName = getComponentName(dstRes, langSpec); - if (generatesComponent(dstRes)) { - updateMethodName = updateMethodPrefix + from + srcResComponentName; - } else if (dstRes.getParent() != null) { - updateMethodName = updateMethodPrefix + dstResComponentName + from + srcResComponentName; - } - if (dstResFromSrcResUpdatesMethods.size() > 0) { - updateMethodName += dstResFromSrcResUpdatesMethods.size() + 1; // To avoid declaring the method multiply. - } - dstResFromSrcResUpdatesMethods.put(ch, updateMethodName); - } - return updateMethodName; - } protected void declareGetterAccessorInTheRootResource(ResourceNode resourceNode, TypeDeclaration rootComponent) { if (resourceNode.getResourceHierarchy().getParent() != null) {