diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerationContext.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerationContext.java index a14604e..0b8784f 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerationContext.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerationContext.java @@ -1,16 +1,33 @@ package generators; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Stack; +import code.ast.Block; +import code.ast.MethodDeclaration; import code.ast.TypeDeclaration; +import code.ast.VariableDeclaration; +import models.algebra.Expression; +import models.algebra.Field; +import models.algebra.Parameter; +import models.algebra.Symbol; +import models.algebra.Term; import models.algebra.Type; +import models.algebra.Variable; +import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.ListType; import models.dataConstraintModel.MapType; import models.dataConstraintModel.ResourceHierarchy; +import models.dataConstraintModel.ResourcePath; +import models.dataConstraintModel.Selector; import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor; public class CodeGenerationContext { protected HashMap> componentNames = new HashMap<>(); @@ -109,6 +126,38 @@ return resourceHierarchyToComponent.get(res); } + public MethodDeclaration getConstructor(TypeDeclaration component) { + for (MethodDeclaration m: component.getMethods()) { + if (m.isConstructor()) return m; + } + return null; + } + + public MethodDeclaration getMethod(TypeDeclaration component, String methodName, List params) { + for (MethodDeclaration m: component.getMethods()) { + if (m.getName().equals(methodName)) { + if (m.getParameters() == null && (params == null || params.size() == 0)) return m; + if (m.getParameters() != null && params != null && m.getParameters().size() == params.size()) { + boolean matchParams = true; + for (int i = 0; i < m.getParameters().size(); i++) { + if (!m.getParameters().get(i).getType().equals(params.get(i).getType())) { + matchParams = false; + break; + } + } + if (matchParams) return m; + } + } + } + return null; + } + + public MethodDeclaration getMethod(TypeDeclaration component, String methodName) { + for (MethodDeclaration m: component.getMethods()) { + if (m.getName().equals(methodName)) return m; + } + return null; + } public String getOrPutUpdateMethodName(ResourceHierarchy srcRes, DataTransferChannel ch, ResourceHierarchy dstRes) { Map> dstResUpdatesMethods = updateMethods.getOrDefault(dstRes, new HashMap<>()); @@ -131,4 +180,750 @@ } return updateMethodName; } + + public MethodDeclaration getOrDeclareUpdateMethod(ResourceHierarchy srcRes, ResourceHierarchy dstRes, DataTransferChannel ch, ArrayList parameters) { + MethodDeclaration update = null; + String updateMethodName = getOrPutUpdateMethodName(srcRes, ch, dstRes); + if (CodeGenerator.generatesComponent(dstRes)) { + // A component is created for this resource. + TypeDeclaration dstComponent = getComponent(dstRes); + for (MethodDeclaration method: dstComponent.getMethods()) { + if (method.getName().equals(updateMethodName)) { + update = method; + break; + } + } + if (update == null) { + update = langSpec.newMethodDeclaration(updateMethodName, false, null, parameters); + dstComponent.addMethod(update); + } + } else if (dstRes.getParent() != null) { + // No component is created for this resource. + TypeDeclaration dstParentComponent = getComponent(dstRes.getParent()); + for (MethodDeclaration method: dstParentComponent.getMethods()) { + if (method.getName().equals(updateMethodName)) { + update = method; + break; + } + } + if (update == null) { + update = langSpec.newMethodDeclaration(updateMethodName, false, null, parameters); + dstParentComponent.addMethod(update); + } + } + return update; + } + + public void declareGetterAccessorInTheRootResource(ResourceNode resourceNode, TypeDeclaration rootComponent) { + if (resourceNode.getResourceHierarchy().getParent() != null) { + // For a non-root resource + MethodDeclaration getterAccessor = null; + List mainGetterParams = new ArrayList<>(); + String resourcePath = getGetterResourcePathAndPathParams(resourceNode.getPrimaryResourcePath(), mainGetterParams, platformSpec, langSpec); + if (resourcePath.indexOf('/') > 0) { + // Remove the root resource from the path + resourcePath = resourcePath.substring(resourcePath.indexOf('/')); + } else { + resourcePath = ""; + } + if (mainGetterParams.size() > 0) { + getterAccessor = langSpec.newMethodDeclaration(CodeGeneratorFromDataFlowGraph.getterPrefix + getComponentName(resourceNode.getResourceHierarchy(), langSpec) + CodeGeneratorFromDataFlowGraph.methoNameOfResourceState, + false, + getImplStateType(resourceNode.getResourceHierarchy(), langSpec), + mainGetterParams); + } else { + getterAccessor = langSpec.newMethodDeclaration(CodeGeneratorFromDataFlowGraph.getterPrefix + getComponentName(resourceNode.getResourceHierarchy(), langSpec) + CodeGeneratorFromDataFlowGraph.methoNameOfResourceState, + getImplStateType(resourceNode.getResourceHierarchy(), langSpec)); + } + getterAccessor.setBody(new Block()); + ResourcePath resPath = new ResourcePath(resourceNode.getPrimaryResourcePath()); + for (int i = 0; i < mainGetterParams.size(); i++) { + Parameter pathParam = new Parameter(mainGetterParams.get(i).getName()); + resPath.replacePathParam(i, pathParam, null); + } + Expression getState = getPullAccessor(platformSpec).getDirectStateAccessorFor(resPath, resPath.getRoot()); + getterAccessor.getBody().addStatement(langSpec.getReturnStatement(getState.toImplementation(new String[] {null}))); + if (!platformSpec.isMonolithic()) { + ((RestApiSpecific) platformSpec).addGetAnnotations(getterAccessor); + if (resourcePath.length() > 0) { + ((RestApiSpecific) platformSpec).addPathAnnotation(getterAccessor, resourcePath); + } + } + rootComponent.addMethod(getterAccessor); + } + } + + public String getGetterResourcePathAndPathParams(ResourcePath resPath, List pathParams, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + int v = 1; + List params = new ArrayList<>(); + for (Expression pathParam: resPath.getPathParams()) { + if (pathParam instanceof Variable) { + Variable var = (Variable) pathParam; + String paramName = var.getName(); + params.add("{" + paramName + "}"); + VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); + pathParams.add(param); + } else if (pathParam instanceof Term) { + Term var = (Term) pathParam; + String paramName = "v" + v; + params.add("{" + paramName + "}"); + VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); + pathParams.add(param); + } + } + return resPath.getResourceHierarchy().toResourcePath(params); + } + + public void declareUpdateAccessorInTheRootResource(ResourceNode resourceNode, String updateMethodName, DataTransferChannel ch, ChannelMember cm, ResourcePath srcResPath, ResourcePath dstResPath, TypeDeclaration rootComponent, int inDegree, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + ArrayList parameters; + VariableDeclaration param; + parameters = new ArrayList<>(); + String resourcePath = getUpdateResourcePathAndPathParams(dstResPath, parameters, true, platformSpec, langSpec); // Path parameters to identify the self resource. + if (resourcePath.indexOf('/') > 0) { + // Remove the root resource from the path + resourcePath = resourcePath.substring(resourcePath.indexOf('/')); + } else { + resourcePath = ""; + } + ResourcePath resPath = new ResourcePath(dstResPath); + for (int i = 0; i < parameters.size(); i++) { + Parameter pathParam = new Parameter(parameters.get(i).getName()); + resPath.replacePathParam(i, pathParam, null); + } + for (Selector selector: ch.getAllSelectors()) { + if (selector.getExpression() instanceof Variable) { + Variable selVar = (Variable) selector.getExpression(); + VariableDeclaration chParam = langSpec.newVariableDeclaration(selVar.getType(), selVar.getName()); + if (!platformSpec.isMonolithic()) { + ((RestApiSpecific) platformSpec).addFormParamAnnotation(chParam, selVar.getName()); + } + parameters.add(chParam); // A channel parameter to specify the context of the collaboration. + } + } + Type srcType = srcResPath.getResourceStateType(); + String srcResName = langSpec.toVariableName(getComponentName(srcResPath.getResourceHierarchy(), langSpec)); + param = langSpec.newVariableDeclaration(srcType, srcResName); + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addFormParamAnnotation(param, srcResName); + parameters.add(param); // The state of the source resource to carry the data-flow. + for (ResourcePath refRes: ch.getReferenceResources()) { + if (!refRes.equals(resourceNode.getInSideResource(ch))) { + String refName = langSpec.toVariableName(getComponentName(refRes.getResourceHierarchy(), langSpec)); + param = langSpec.newVariableDeclaration(refRes.getResourceStateType(), refName); + if (!platformSpec.isMonolithic()) { + ((RestApiSpecific) platformSpec).addFormParamAnnotation(param, refName); + } + parameters.add(param); + } + } + MethodDeclaration updateAccessor = langSpec.newMethodDeclaration(updateMethodName, false, null, parameters); + if (!platformSpec.isMonolithic()) { + if (isPut(cm)) { + ((RestApiSpecific) platformSpec).addPutAnnotations(updateAccessor); + } else { + if (!isDelete(cm)) { + ((RestApiSpecific) platformSpec).addPostAnnotations(updateAccessor); + } else { + ((RestApiSpecific) platformSpec).addDeleteAnnotations(updateAccessor); + } + } + } + if (inDegree > 1) { + // For each source resource, a child resource is defined in the destination resource so that its state can be updated separately. + resourcePath += "/" + langSpec.toVariableName(srcResName); + } + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathAnnotation(updateAccessor, resourcePath); + + // To make the accessor call the update method. + Expression resExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(resPath, resPath.getRoot()); + List args = new ArrayList<>(); + if (resExp instanceof Term) { + // To access the parent resource if the leaf resource is primitive and cannot declare the update method, or to remove getValue(). + if (((Term) resExp).getChildren().size() > 1 && ((Term) resExp).getChild(1) instanceof Variable) { + args.add(((Variable)((Term) resExp).getChild(1)).getName()); + } + resExp = ((Term) resExp).getChild(0); + } + for (VariableDeclaration var: updateAccessor.getParameters()) { + args.add(var.getName()); + } + 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); + } + + public String getUpdateResourcePathAndPathParams(ResourcePath resPath, ArrayList pathParams, boolean isRestAPI, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + int v = 1; + List params = new ArrayList<>(); + for (Expression pathParam: resPath.getPathParams()) { + if (pathParam instanceof Variable) { + Variable var = (Variable) pathParam; + String paramName = null; + if (isRestAPI) { + paramName = var.getName(); + } else { + paramName = "self" + (v > 1 ? v : ""); + } + params.add("{" + paramName + "}"); + VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); + if (isRestAPI) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); + pathParams.add(param); + } else if (pathParam instanceof Term) { + Term var = (Term) pathParam; + String paramName = null; + if (isRestAPI) { + paramName = "v" + v; + } else { + paramName = "self" + (v > 1 ? v : ""); + } + params.add("{" + paramName + "}"); + VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); + if (isRestAPI) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); + pathParams.add(param); + } + v++; + } + return resPath.getResourceHierarchy().toResourcePath(params); + } + + public MethodDeclaration declareInputAccessorInTheRootResource(String inputMethodName, + ArrayList rootInputParams, ChannelMember cm, String resourcePath, + TypeDeclaration rootComponent, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + MethodDeclaration rootInputAccessor; + rootInputAccessor = langSpec.newMethodDeclaration(inputMethodName, false, null, rootInputParams); + if (!platformSpec.isMonolithic()) { + if (isPut(cm)) { + ((RestApiSpecific) platformSpec).addPutAnnotations(rootInputAccessor); + } else { + if (!isDelete(cm)) { + ((RestApiSpecific) platformSpec).addPostAnnotations(rootInputAccessor); + } else { + ((RestApiSpecific) platformSpec).addDeleteAnnotations(rootInputAccessor); + } + } + if (resourcePath.length() > 0) { + ((RestApiSpecific) platformSpec).addPathAnnotation(rootInputAccessor, resourcePath); + } + } + rootComponent.addMethod(rootInputAccessor); + return rootInputAccessor; + } + + public String getInputMethodResourcePathAndPathParams(ResourcePath resPath, ArrayList rootInputParams, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { + int v = 1; + List params = new ArrayList<>(); + if (resPath.getLastParam() != null) { + Expression pathParam = resPath.getLastParam(); + if (pathParam instanceof Variable) { + Variable var = (Variable) pathParam; + String paramName = var.getName(); + params.add("{" + paramName + "}"); + VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); + rootInputParams.add(param); + } else if (pathParam instanceof Term) { + Term var = (Term) pathParam; + String paramName = "v" + v; + params.add("{" + paramName + "}"); + VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); + rootInputParams.add(param); + } + v++; + } + if (resPath.getParent() != null) { + for (Expression pathParam: resPath.getParent().getPathParams()) { + if (pathParam instanceof Variable) { + Variable var = (Variable) pathParam; + String paramName = var.getName(); + params.add("{" + paramName + "}"); + VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); + rootInputParams.add(param); + } else if (pathParam instanceof Term) { + Term var = (Term) pathParam; + String paramName = "v" + v; + params.add("{" + paramName + "}"); + VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); + if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); + rootInputParams.add(param); + } + v++; + } + } + return resPath.getResourceHierarchy().toResourcePath(params); + } + + public boolean isPut(ChannelMember cm) { + return cm.getStateTransition().isRightUnary(); + } + + public boolean isDelete(ChannelMember cm) { + boolean isDelete = false; + Expression nextExp = cm.getStateTransition().getNextStateExpression(); + if (nextExp instanceof Term) { + Symbol rootSymbol = ((Term) nextExp).getSymbol(); + if (rootSymbol.equals(DataConstraintModel.delete) || rootSymbol.equals(DataConstraintModel.remove)) { + isDelete = true; + } else if (rootSymbol.equals(DataConstraintModel.cond)) { + Expression childExp = ((Term) nextExp).getChild(1); + if (childExp instanceof Term) { + rootSymbol = ((Term) childExp).getSymbol(); + if (rootSymbol.equals(DataConstraintModel.delete) || rootSymbol.equals(DataConstraintModel.remove)) { + isDelete = true; + } + } + childExp = ((Term) nextExp).getChild(2); + if (childExp instanceof Term) { + rootSymbol = ((Term) childExp).getSymbol(); + if (rootSymbol.equals(DataConstraintModel.delete) || rootSymbol.equals(DataConstraintModel.remove)) { + isDelete = true; + } + } + } + } + return isDelete; + } + + public IResourceStateAccessor getPushAccessor(IPlatformSpecific platformSpec) { + if (platformSpec.isMonolithic()) { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes= target.getResource(); + ResourcePath fromRes= from.getResource(); + if (targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // use the cached value as the current state + return new Field(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes= target.getResource(); + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null && targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + }; + } else { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + ResourcePath fromRes = from.getResource(); + if (targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // use the cached value as the current state + return new Field(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null && targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + return null; + } + }; + } + } + + public IResourceStateAccessor getPullAccessor(IPlatformSpecific platformSpec) { + if (platformSpec.isMonolithic()) { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes= target.getResource(); + if (from != null) { + ResourcePath fromRes= from.getResource(); + if (!target.isOutside()) { + return getDirectStateAccessorFor(targetRes, fromRes); + } + Term getter = null; + String targetComponentName = getComponentName(targetRes.getResourceHierarchy(), langSpec); + if (CodeGenerator.generatesComponent(targetRes.getResourceHierarchy())) { + getter = new Term(new Symbol(CodeGenerator.getterOfResourceState, 1, Symbol.Type.METHOD)); + getter.addChild(new Field(langSpec.toVariableName(targetComponentName), targetRes.getResourceStateType())); + } else { + String parentName = langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy().getParent(), langSpec)); + Type parentType = targetRes.getResourceHierarchy().getParent().getResourceStateType(); + getter = new Term(new Symbol(CodeGenerator.getterPrefix + targetComponentName, 1, Symbol.Type.METHOD)); + getter.addChild(new Field(parentName, parentType)); + } + return getter; + } else { + return getDirectStateAccessorFor(targetRes, null); + } + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes= target.getResource(); + if (from != null) { + ResourcePath fromRes= from.getResource(); + if (!target.isOutside()) { + return getDirectStateAccessorFor(targetRes, fromRes); + } + Term getter = null; + String targetComponentName = getComponentName(targetRes.getResourceHierarchy(), langSpec); + if (CodeGenerator.generatesComponent(targetRes.getResourceHierarchy())) { + getter = new Term(new Symbol(CodeGenerator.getterOfResourceState, 1, Symbol.Type.METHOD)); + getter.addChild(new Field(langSpec.toVariableName(targetComponentName), targetRes.getResourceStateType())); + } else { + String parentName = langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy().getParent(), langSpec)); + Type parentType = targetRes.getResourceHierarchy().getParent().getResourceStateType(); + getter = new Term(new Symbol(CodeGenerator.getterPrefix + targetComponentName, 1, Symbol.Type.METHOD)); + getter.addChild(new Field(parentName, parentType)); + } + return getter; + } else { + return getDirectStateAccessorFor(targetRes, null); + } + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null) { + if (targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + if (fromRes.isAncestorOf(targetRes)) { + Stack pathStack = new Stack<>(); + ResourcePath curPath = targetRes; + do { + pathStack.push(curPath); + curPath = curPath.getParent(); + } while (!curPath.equals(fromRes)); + // iterate from the fromRes resource + return getRelativePath(targetRes, pathStack); + } + if (CodeGenerator.generatesComponent(targetRes.getResourceHierarchy())) { + Term getter = new Term(new Symbol(CodeGenerator.getterOfResourceState, 1, Symbol.Type.METHOD)); + getter.addChild(new Field(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), targetRes.getResourceStateType())); + return getter; + } else { + return new Field(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), targetRes.getResourceStateType()); + } + } else { + // (#3) access from the outside of the hierarchy (must be kept consistent with #4) + Stack pathStack = new Stack<>(); + ResourcePath curPath = targetRes; + do { + pathStack.push(curPath); + curPath = curPath.getParent(); + } while (curPath != null); + // iterate from the root resource + return getRelativePath(targetRes, pathStack); + } + } + + private Expression getRelativePath(ResourcePath targetRes, Stack pathStack) { + ResourcePath curPath; + Term getter = null; + int arity = 2; + boolean doesChainInvocations = true; + while (!pathStack.empty()) { + curPath = pathStack.pop(); + String typeName = getComponentName(curPath.getResourceHierarchy(), langSpec); + if (getter == null && CodeGenerator.generatesComponent(curPath.getResourceHierarchy())) { + // root resource + String fieldName = langSpec.toVariableName(typeName); + getter = new Field(fieldName, getOrCreateComponentType(typeName)); + } else { + if (CodeGenerator.generatesComponent(curPath.getResourceHierarchy())) { + if (arity == 2) { + Term newGetter = new Term(new Symbol(CodeGenerator.getterPrefix + typeName, -1, Symbol.Type.METHOD)); + newGetter.addChild(getter); + if (curPath.getResourceHierarchy().getNumParameters() > 0) { + Expression param = curPath.getLastParam(); + if (param != null) { + newGetter.addChild(param); + newGetter.getSymbol().setArity(2); + } + } + getter = newGetter; + } else { + // add the last path parameter. + if (curPath.getResourceHierarchy().getNumParameters() > 0) { + Expression param = curPath.getLastParam(); + if (param != null) { + getter.getSymbol().setArity(arity); + getter.addChild(param); + } + } + } + arity = 2; + doesChainInvocations = true; + } else { + // 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(CodeGenerator.getterPrefix + typeName, -1, Symbol.Type.METHOD)); + newGetter.addChild(getter); + getter = newGetter; + doesChainInvocations = false; + } + if (curPath.getResourceHierarchy().getNumParameters() > 0) { + // may change the symbol name + getter.getSymbol().changeName(CodeGenerator.getterPrefix + typeName); + // add a path parameter. + Expression param = curPath.getLastParam(); + if (param != null) { + getter.getSymbol().setArity(arity); + getter.addChild(param); + arity++; + } + } + } + } + } + + if (CodeGenerator.generatesComponent(targetRes.getResourceHierarchy())) { + Term newGetter = new Term(new Symbol(CodeGenerator.getterOfResourceState, 1, Symbol.Type.METHOD)); + newGetter.addChild(getter); + getter = newGetter; + } + return getter; + } + }; + } else { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + if (from != null && !target.isOutside()) { + ResourcePath fromRes = from.getResource(); + if (targetRes.getCommonPrefix(fromRes) != null) { + return getDirectStateAccessorFor(targetRes, fromRes); + } + } + // for reference channel member + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + if (from != null && !target.isOutside()) { + ResourcePath fromRes = from.getResource(); + if (targetRes.getCommonPrefix(fromRes) != null) { + return getDirectStateAccessorFor(targetRes, fromRes); + } + } + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null && !fromRes.getResourceHierarchy().isAncestorOf(targetRes.getResourceHierarchy())) { + if (targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } else { + // (#3) access from an ancestor or outside of the hierarchy (must be kept consistent with #4) + Stack pathStack = new Stack<>(); + ResourcePath curPath = targetRes; + do { + if (fromRes != null && curPath.equals(fromRes)) break; + pathStack.push(curPath); + curPath = curPath.getParent(); + } while (curPath != null); + // iterate from the `from' resource + Term getter = null; + int arity = 2; + boolean doesChainInvocations = true; + while (!pathStack.empty()) { + curPath = pathStack.pop(); + String typeName = getComponentName(curPath.getResourceHierarchy(), langSpec); + if (getter == null && fromRes == null) { + // root resource + String fieldName = langSpec.toVariableName(typeName); + getter = new Field(fieldName, getOrCreateComponentType(typeName)); + } else { + if (CodeGenerator.generatesComponent(curPath.getResourceHierarchy())) { + if (arity == 2) { + Term newGetter = new Term(new Symbol(CodeGenerator.getterPrefix + typeName, -1, Symbol.Type.METHOD)); + newGetter.addChild(getter); + if (curPath.getResourceHierarchy().getNumParameters() > 0) { + Expression param = curPath.getLastParam(); + if (param != null) { + newGetter.addChild(param); + newGetter.getSymbol().setArity(2); + } + } + getter = newGetter; + } else { + // add the last path parameter. + if (curPath.getResourceHierarchy().getNumParameters() > 0) { + Expression param = curPath.getLastParam(); + if (param != null) { + getter.getSymbol().setArity(arity); + getter.addChild(param); + } + } + } + arity = 2; + doesChainInvocations = true; + } else { + // 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(CodeGenerator.getterPrefix + typeName, -1, Symbol.Type.METHOD)); + newGetter.addChild(getter); + getter = newGetter; + doesChainInvocations = false; + } + if (curPath.getResourceHierarchy().getNumParameters() > 0) { + // may change the symbol name + getter.getSymbol().changeName(CodeGenerator.getterPrefix + typeName); + // add a path parameter. + Expression param = curPath.getLastParam(); + if (param != null) { + getter.getSymbol().setArity(arity); + getter.addChild(param); + arity++; + } + } + } + } + } + + if (CodeGenerator.generatesComponent(targetRes.getResourceHierarchy())) { + Term newGetter = new Term(new Symbol(CodeGenerator.getterOfResourceState, 1, Symbol.Type.METHOD)); + newGetter.addChild(getter); + getter = newGetter; + } + return getter; + } + } + }; + } + } + + public IResourceStateAccessor getRefAccessor(IPlatformSpecific platformSpec) { + if (platformSpec.isMonolithic()) { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes= target.getResource(); + ResourcePath fromRes= from.getResource(); + if (targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // use the cached value as the current state + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes= target.getResource(); + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null && targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + }; + } else { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + ResourcePath fromRes = from.getResource(); + if (targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null && targetRes.equals(fromRes)) { + return new Field(CodeGenerator.fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + return null; + } + }; + } + } } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index fa3ad27..b78bae6 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -436,7 +436,7 @@ accessor = langSpec.newMethodDeclaration(getterPrefix + getComponentName(accessRes.getResourceHierarchy(), langSpec), false, getImplStateType(accessRes.getResourceHierarchy(), langSpec), mainGetterParams); } Block block = new Block(); - Expression getState = getPullAccessor(platformSpec).getDirectStateAccessorFor(accessResPath, null); + Expression getState = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(accessResPath, null); block.addStatement(langSpec.getReturnStatement(getState.toImplementation(new String[] {null}))); // if (stateGetter.getParameters() == null || stateGetter.getParameters().size() == 0) { // block.addStatement(langSpec.getReturnStatement(langSpec.getMethodInvocation(accessRes.getResourceName(), stateGetter.getName()))); @@ -468,218 +468,7 @@ } } } - - protected String getUpdateMethodName(ResourceHierarchy srcRes, ResourceHierarchy dstRes, DataTransferChannel ch) { - return generationContext.getOrPutUpdateMethodName(srcRes, ch, dstRes); - } - - protected MethodDeclaration getConstructor(TypeDeclaration component) { - for (MethodDeclaration m: component.getMethods()) { - if (m.isConstructor()) return m; - } - return null; - } - - protected static List getGetterMethods(TypeDeclaration component, String resourceName) { - List getters = new ArrayList<>(); - for (MethodDeclaration m: component.getMethods()) { - if (m.getName().equals(getterPrefix + resourceName)) { - getters.add(m); - } - } - return getters; - } - - protected MethodDeclaration getUpdateMethod(Edge inEdge, TypeDeclaration component, - Map>> dataFlowInform, ILanguageSpecific langSpec) { - List passedResoueces = dataFlowInform.get(inEdge).get(PushPullValue.PUSH); - String methodName = updateMethodPrefix; - for (ResourceNode rn: passedResoueces) { - methodName += langSpec.toComponentName(rn.getResourceName()); - } - return getMethod(component, methodName); - } - protected MethodDeclaration getInputMethod(ResourceNode resourceNode, DataTransferChannel ch, TypeDeclaration component) { - MethodDeclaration input = null; - for (ChannelMember out : ch.getOutputChannelMembers()) { - if (resourceNode.getInSideResources().contains(out.getResource())) { - Expression message = out.getStateTransition().getMessageExpression(); - if (message instanceof Term) { - input = getMethod(component, ((Term) message).getSymbol().getImplName()); - } else if (message instanceof Variable) { - // Declare an input method in this component. - input = getMethod(component, ((Variable) message).getName()); - } - break; - } - } - return input; - } - - - protected MethodDeclaration getMethod(TypeDeclaration component, String methodName, List params) { - for (MethodDeclaration m: component.getMethods()) { - if (m.getName().equals(methodName)) { - if (m.getParameters() == null && (params == null || params.size() == 0)) return m; - if (m.getParameters() != null && params != null && m.getParameters().size() == params.size()) { - boolean matchParams = true; - for (int i = 0; i < m.getParameters().size(); i++) { - if (!m.getParameters().get(i).getType().equals(params.get(i).getType())) { - matchParams = false; - break; - } - } - if (matchParams) return m; - } - } - } - return null; - } - - protected MethodDeclaration getMethod(TypeDeclaration component, String methodName) { - for (MethodDeclaration m: component.getMethods()) { - if (m.getName().equals(methodName)) return m; - } - return null; - } - - protected boolean isPut(ChannelMember cm) { - return cm.getStateTransition().isRightUnary(); - } - - protected boolean isDelete(ChannelMember cm) { - boolean isDelete = false; - Expression nextExp = cm.getStateTransition().getNextStateExpression(); - if (nextExp instanceof Term) { - Symbol rootSymbol = ((Term) nextExp).getSymbol(); - if (rootSymbol.equals(DataConstraintModel.delete) || rootSymbol.equals(DataConstraintModel.remove)) { - isDelete = true; - } else if (rootSymbol.equals(DataConstraintModel.cond)) { - Expression childExp = ((Term) nextExp).getChild(1); - if (childExp instanceof Term) { - rootSymbol = ((Term) childExp).getSymbol(); - if (rootSymbol.equals(DataConstraintModel.delete) || rootSymbol.equals(DataConstraintModel.remove)) { - isDelete = true; - } - } - childExp = ((Term) nextExp).getChild(2); - if (childExp instanceof Term) { - rootSymbol = ((Term) childExp).getSymbol(); - if (rootSymbol.equals(DataConstraintModel.delete) || rootSymbol.equals(DataConstraintModel.remove)) { - isDelete = true; - } - } - } - } - return isDelete; - } - - protected String getGetterResourcePathAndPathParams(ResourcePath resPath, List pathParams, - IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { - int v = 1; - List params = new ArrayList<>(); - for (Expression pathParam: resPath.getPathParams()) { - if (pathParam instanceof Variable) { - Variable var = (Variable) pathParam; - String paramName = var.getName(); - params.add("{" + paramName + "}"); - VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); - if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); - pathParams.add(param); - } else if (pathParam instanceof Term) { - Term var = (Term) pathParam; - String paramName = "v" + v; - params.add("{" + paramName + "}"); - VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); - if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); - pathParams.add(param); - } - } - return resPath.getResourceHierarchy().toResourcePath(params); - } - - protected String getUpdateResourcePathAndPathParams(ResourcePath resPath, ArrayList pathParams, boolean isRestAPI, - IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { - int v = 1; - List params = new ArrayList<>(); - for (Expression pathParam: resPath.getPathParams()) { - if (pathParam instanceof Variable) { - Variable var = (Variable) pathParam; - String paramName = null; - if (isRestAPI) { - paramName = var.getName(); - } else { - paramName = "self" + (v > 1 ? v : ""); - } - params.add("{" + paramName + "}"); - VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); - if (isRestAPI) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); - pathParams.add(param); - } else if (pathParam instanceof Term) { - Term var = (Term) pathParam; - String paramName = null; - if (isRestAPI) { - paramName = "v" + v; - } else { - paramName = "self" + (v > 1 ? v : ""); - } - params.add("{" + paramName + "}"); - VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); - if (isRestAPI) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); - pathParams.add(param); - } - v++; - } - return resPath.getResourceHierarchy().toResourcePath(params); - } - - protected String getInputMethodResourcePathAndPathParams(ResourcePath resPath, ArrayList rootInputParams, - IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { - int v = 1; - List params = new ArrayList<>(); - if (resPath.getLastParam() != null) { - Expression pathParam = resPath.getLastParam(); - if (pathParam instanceof Variable) { - Variable var = (Variable) pathParam; - String paramName = var.getName(); - params.add("{" + paramName + "}"); - VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); - if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); - rootInputParams.add(param); - } else if (pathParam instanceof Term) { - Term var = (Term) pathParam; - String paramName = "v" + v; - params.add("{" + paramName + "}"); - VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); - if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); - rootInputParams.add(param); - } - v++; - } - if (resPath.getParent() != null) { - for (Expression pathParam: resPath.getParent().getPathParams()) { - if (pathParam instanceof Variable) { - Variable var = (Variable) pathParam; - String paramName = var.getName(); - params.add("{" + paramName + "}"); - VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); - if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); - rootInputParams.add(param); - } else if (pathParam instanceof Term) { - Term var = (Term) pathParam; - String paramName = "v" + v; - params.add("{" + paramName + "}"); - VariableDeclaration param = langSpec.newVariableDeclaration(var.getType(), paramName); - if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathParamAnnotation(param, paramName); - rootInputParams.add(param); - } - v++; - } - } - return resPath.getResourceHierarchy().toResourcePath(params); - } - protected void generatePullDataTransfer(MethodDeclaration method, Block block, String fromResourceName, String fromResourcePath, Type fromResourceType, boolean doesAddFirst, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { if (block == null) { @@ -850,441 +639,8 @@ field.setInitializer(initializer); } } - - public IResourceStateAccessor getPushAccessor(IPlatformSpecific platformSpec) { - if (platformSpec.isMonolithic()) { - return new IResourceStateAccessor() { - @Override - public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes= target.getResource(); - ResourcePath fromRes= from.getResource(); - if (targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - // use the cached value as the current state - return new Field(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes= target.getResource(); - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { - if (fromRes != null && targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - // for reference channel member - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - }; - } else { - return new IResourceStateAccessor() { - @Override - public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes = target.getResource(); - ResourcePath fromRes = from.getResource(); - if (targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - // use the cached value as the current state - return new Field(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes = target.getResource(); - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { - if (fromRes != null && targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - return null; - } - }; - } - } public IResourceStateAccessor getPullAccessor(IPlatformSpecific platformSpec) { - if (platformSpec.isMonolithic()) { - return new IResourceStateAccessor() { - @Override - public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes= target.getResource(); - if (from != null) { - ResourcePath fromRes= from.getResource(); - if (!target.isOutside()) { - return getDirectStateAccessorFor(targetRes, fromRes); - } - Term getter = null; - String targetComponentName = getComponentName(targetRes.getResourceHierarchy(), langSpec); - if (generatesComponent(targetRes.getResourceHierarchy())) { - getter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); - getter.addChild(new Field(langSpec.toVariableName(targetComponentName), targetRes.getResourceStateType())); - } else { - String parentName = langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy().getParent(), langSpec)); - Type parentType = targetRes.getResourceHierarchy().getParent().getResourceStateType(); - getter = new Term(new Symbol(getterPrefix + targetComponentName, 1, Symbol.Type.METHOD)); - getter.addChild(new Field(parentName, parentType)); - } - return getter; - } else { - return getDirectStateAccessorFor(targetRes, null); - } - } - - @Override - public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes= target.getResource(); - if (from != null) { - ResourcePath fromRes= from.getResource(); - if (!target.isOutside()) { - return getDirectStateAccessorFor(targetRes, fromRes); - } - Term getter = null; - String targetComponentName = getComponentName(targetRes.getResourceHierarchy(), langSpec); - if (generatesComponent(targetRes.getResourceHierarchy())) { - getter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); - getter.addChild(new Field(langSpec.toVariableName(targetComponentName), targetRes.getResourceStateType())); - } else { - String parentName = langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy().getParent(), langSpec)); - Type parentType = targetRes.getResourceHierarchy().getParent().getResourceStateType(); - getter = new Term(new Symbol(getterPrefix + targetComponentName, 1, Symbol.Type.METHOD)); - getter.addChild(new Field(parentName, parentType)); - } - return getter; - } else { - return getDirectStateAccessorFor(targetRes, null); - } - } - - @Override - public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { - if (fromRes != null) { - if (targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - // for reference channel member - if (fromRes.isAncestorOf(targetRes)) { - Stack pathStack = new Stack<>(); - ResourcePath curPath = targetRes; - do { - pathStack.push(curPath); - curPath = curPath.getParent(); - } while (!curPath.equals(fromRes)); - // iterate from the fromRes resource - return getRelativePath(targetRes, pathStack); - } - if (generatesComponent(targetRes.getResourceHierarchy())) { - Term getter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); - getter.addChild(new Field(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), targetRes.getResourceStateType())); - return getter; - } else { - return new Field(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), targetRes.getResourceStateType()); - } - } else { - // (#3) access from the outside of the hierarchy (must be kept consistent with #4) - Stack pathStack = new Stack<>(); - ResourcePath curPath = targetRes; - do { - pathStack.push(curPath); - curPath = curPath.getParent(); - } while (curPath != null); - // iterate from the root resource - return getRelativePath(targetRes, pathStack); - } - } - - private Expression getRelativePath(ResourcePath targetRes, Stack pathStack) { - ResourcePath curPath; - Term getter = null; - int arity = 2; - boolean doesChainInvocations = true; - while (!pathStack.empty()) { - curPath = pathStack.pop(); - String typeName = getComponentName(curPath.getResourceHierarchy(), langSpec); - if (getter == null && generatesComponent(curPath.getResourceHierarchy())) { - // root resource - String fieldName = langSpec.toVariableName(typeName); - getter = new Field(fieldName, generationContext.getOrCreateComponentType(typeName)); - } else { - if (generatesComponent(curPath.getResourceHierarchy())) { - if (arity == 2) { - Term newGetter = new Term(new Symbol(getterPrefix + typeName, -1, Symbol.Type.METHOD)); - newGetter.addChild(getter); - if (curPath.getResourceHierarchy().getNumParameters() > 0) { - Expression param = curPath.getLastParam(); - if (param != null) { - newGetter.addChild(param); - newGetter.getSymbol().setArity(2); - } - } - getter = newGetter; - } else { - // add the last path parameter. - if (curPath.getResourceHierarchy().getNumParameters() > 0) { - Expression param = curPath.getLastParam(); - if (param != null) { - getter.getSymbol().setArity(arity); - getter.addChild(param); - } - } - } - arity = 2; - doesChainInvocations = true; - } else { - // 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)); - newGetter.addChild(getter); - getter = newGetter; - doesChainInvocations = false; - } - if (curPath.getResourceHierarchy().getNumParameters() > 0) { - // may change the symbol name - getter.getSymbol().changeName(getterPrefix + typeName); - // add a path parameter. - Expression param = curPath.getLastParam(); - if (param != null) { - getter.getSymbol().setArity(arity); - getter.addChild(param); - arity++; - } - } - } - } - } - - if (generatesComponent(targetRes.getResourceHierarchy())) { - Term newGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); - newGetter.addChild(getter); - getter = newGetter; - } - return getter; - } - }; - } else { - return new IResourceStateAccessor() { - @Override - public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes = target.getResource(); - if (from != null && !target.isOutside()) { - ResourcePath fromRes = from.getResource(); - if (targetRes.getCommonPrefix(fromRes) != null) { - return getDirectStateAccessorFor(targetRes, fromRes); - } - } - // for reference channel member - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes = target.getResource(); - if (from != null && !target.isOutside()) { - ResourcePath fromRes = from.getResource(); - if (targetRes.getCommonPrefix(fromRes) != null) { - return getDirectStateAccessorFor(targetRes, fromRes); - } - } - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { - if (fromRes != null && !fromRes.getResourceHierarchy().isAncestorOf(targetRes.getResourceHierarchy())) { - if (targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - // for reference channel member - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } else { - // (#3) access from an ancestor or outside of the hierarchy (must be kept consistent with #4) - Stack pathStack = new Stack<>(); - ResourcePath curPath = targetRes; - do { - if (fromRes != null && curPath.equals(fromRes)) break; - pathStack.push(curPath); - curPath = curPath.getParent(); - } while (curPath != null); - // iterate from the `from' resource - Term getter = null; - int arity = 2; - boolean doesChainInvocations = true; - while (!pathStack.empty()) { - curPath = pathStack.pop(); - String typeName = getComponentName(curPath.getResourceHierarchy(), langSpec); - if (getter == null && fromRes == null) { - // root resource - String fieldName = langSpec.toVariableName(typeName); - getter = new Field(fieldName, generationContext.getOrCreateComponentType(typeName)); - } else { - if (generatesComponent(curPath.getResourceHierarchy())) { - if (arity == 2) { - Term newGetter = new Term(new Symbol(getterPrefix + typeName, -1, Symbol.Type.METHOD)); - newGetter.addChild(getter); - if (curPath.getResourceHierarchy().getNumParameters() > 0) { - Expression param = curPath.getLastParam(); - if (param != null) { - newGetter.addChild(param); - newGetter.getSymbol().setArity(2); - } - } - getter = newGetter; - } else { - // add the last path parameter. - if (curPath.getResourceHierarchy().getNumParameters() > 0) { - Expression param = curPath.getLastParam(); - if (param != null) { - getter.getSymbol().setArity(arity); - getter.addChild(param); - } - } - } - arity = 2; - doesChainInvocations = true; - } else { - // 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)); - newGetter.addChild(getter); - getter = newGetter; - doesChainInvocations = false; - } - if (curPath.getResourceHierarchy().getNumParameters() > 0) { - // may change the symbol name - getter.getSymbol().changeName(getterPrefix + typeName); - // add a path parameter. - Expression param = curPath.getLastParam(); - if (param != null) { - getter.getSymbol().setArity(arity); - getter.addChild(param); - arity++; - } - } - } - } - } - - if (generatesComponent(targetRes.getResourceHierarchy())) { - Term newGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); - newGetter.addChild(getter); - getter = newGetter; - } - return getter; - } - } - }; - } - } - - public IResourceStateAccessor getRefAccessor(IPlatformSpecific platformSpec) { - if (platformSpec.isMonolithic()) { - return new IResourceStateAccessor() { - @Override - public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes= target.getResource(); - ResourcePath fromRes= from.getResource(); - if (targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - // use the cached value as the current state - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes= target.getResource(); - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { - if (fromRes != null && targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - // for reference channel member - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - }; - } else { - return new IResourceStateAccessor() { - @Override - public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes = target.getResource(); - ResourcePath fromRes = from.getResource(); - if (targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - // for reference channel member - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { - ResourcePath targetRes = target.getResource(); - return new Parameter(langSpec.toVariableName(getComponentName(targetRes.getResourceHierarchy(), langSpec)), - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - - @Override - public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { - if (fromRes != null && targetRes.equals(fromRes)) { - return new Field(fieldOfResourceState, - targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() - : DataConstraintModel.typeInt); - } - return null; - } - }; - } + return generationContext.getPullAccessor(platformSpec); } } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 36a2680..52e5279 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -203,7 +203,7 @@ if (!platformSpec.isMonolithic() && !generatedResources.contains(resourceHierarchy)) { // Declare the getter accessor in the root resource. - declareGetterAccessorInTheRootResource(resourceNode, rootComponent); + generationContext.declareGetterAccessorInTheRootResource(resourceNode, rootComponent); } // Declare input methods in this component and the main component. @@ -347,7 +347,7 @@ if (jsonTerm.getType().equals(replacedJsonType)) { // a json sub-term to replace if (jsonTerm instanceof JsonTerm || jsonTerm.getSymbol().equals(DataConstraintModel.addMember)) { - MethodDeclaration childConstructor = getConstructor(descendantComponent); + MethodDeclaration childConstructor = generationContext.getConstructor(descendantComponent); List params = new ArrayList<>(); if (childConstructor != null) { for (VariableDeclaration var: childConstructor.getParameters()) { @@ -1017,10 +1017,10 @@ if (((PushPullAttribute) dIn.getAttribute()).getSelectedOption() == PushPullValue.PUSH) { // PUSH transfer isContainedPush = true; - inputResourceToStateAccessor.put(in, getPushAccessor(platformSpec)); + inputResourceToStateAccessor.put(in, generationContext.getPushAccessor(platformSpec)); } else { // PULL transfer - inputResourceToStateAccessor.put(in, getPullAccessor(platformSpec)); + inputResourceToStateAccessor.put(in, generationContext.getPullAccessor(platformSpec)); ch = ((ChannelNode) resToCh.getDestination()).getChannel(); // pull containing input side channel is at most one. if (!platformSpec.isMonolithic() && !in.isOutside() @@ -1057,7 +1057,7 @@ // for reference channel members. ResourcePath dstResPath = resourceNode.getInSideResource(ch); for (ChannelMember rc: ch.getReferenceChannelMembers()) { - inputResourceToStateAccessor.put(rc, getPullAccessor(platformSpec)); // by pull data transfer + inputResourceToStateAccessor.put(rc, generationContext.getPullAccessor(platformSpec)); // by pull data transfer ResourcePath refResPath = rc.getResource(); if (!platformSpec.isMonolithic() && (rc.isOutside() @@ -1081,10 +1081,10 @@ Map.Entry>>, Term> resourcePathsAndMessage; if (!isContainedPush) { // All incoming edges are in PULL-style. - resourcePathsAndMessage = ch.fillOutsideResourcePaths(out, getPullAccessor(platformSpec), null); + resourcePathsAndMessage = ch.fillOutsideResourcePaths(out, generationContext.getPullAccessor(platformSpec), null); } else { // At least one incoming edge is in PUSH-style. - resourcePathsAndMessage = ch.fillOutsideResourcePaths(out, getPullAccessor(platformSpec), inputResourceToStateAccessor); + resourcePathsAndMessage = ch.fillOutsideResourcePaths(out, generationContext.getPullAccessor(platformSpec), inputResourceToStateAccessor); } Map>> resourcePaths = resourcePathsAndMessage.getKey(); Term messageTerm = resourcePathsAndMessage.getValue(); @@ -1134,7 +1134,7 @@ Type srcResType2 = src2.getResourceStateType(); String srcResName2 = langSpec.toVariableName(getComponentName(src2.getResourceHierarchy(), langSpec)); if (platformSpec.isMonolithic()) { - String srcGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[] {""}); + String srcGetter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[] {""}); stateGetter.addStatement(langSpec.newVariableDeclaration(srcResType2, srcResName2) + langSpec.getAssignment() + srcGetter + langSpec.getStatementDelimiter()); } else { @@ -1151,7 +1151,7 @@ Type srcResType2 = src2.getResourceStateType(); String srcResName2 = langSpec.toVariableName(getComponentName(src2.getResourceHierarchy(), langSpec)); if (platformSpec.isMonolithic()) { - String dependingGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[] {""}); + String dependingGetter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(src2, resourceNode.getInSideResource(curChannel)).toImplementation(new String[] {""}); stateGetter.addStatement(langSpec.newVariableDeclaration(srcResType2, srcResName2) + langSpec.getAssignment() + dependingGetter + langSpec.getStatementDelimiter()); } else { @@ -1165,7 +1165,7 @@ // collect the message constraints by a descendant channel. List varsForSideEffects = new ArrayList<>(); int v = 0; - resourcePathsAndMessage = curChannel.fillOutsideResourcePaths(out, getPullAccessor(platformSpec), null); + resourcePathsAndMessage = curChannel.fillOutsideResourcePaths(out, generationContext.getPullAccessor(platformSpec), null); if (resourcePathsAndMessage != null) { resourcePaths = resourcePathsAndMessage.getKey(); Term messageTermSub = resourcePathsAndMessage.getValue(); @@ -1235,12 +1235,12 @@ || insideResPath.getCommonPrefix(dstResPath) != null || !platformSpec.isDifferentTreesAsDifferentServices()) { if (!platformSpec.isMonolithic() && generatesComponent(insideResPath.getResourceHierarchy())) { - Expression parentGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, dstResPath); + Expression parentGetter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, dstResPath); Term valueGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); valueGetter.addChild(parentGetter); parent = valueGetter.toImplementation(new String[] {""}); } else { - parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, dstResPath).toImplementation(new String[] {""}); + parent = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, dstResPath).toImplementation(new String[] {""}); } } else { // for REST API @@ -1286,7 +1286,7 @@ // generate a return statement. String[] sideEffects = new String[] {""}; - String curState = ch.deriveUpdateExpressionOf(out, messageTerm, getPullAccessor(platformSpec)).toImplementation(sideEffects); + String curState = ch.deriveUpdateExpressionOf(out, messageTerm, generationContext.getPullAccessor(platformSpec)).toImplementation(sideEffects); stateGetter.addStatement(sideEffects[0] + langSpec.getReturnStatement(curState)); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined e) { @@ -1414,7 +1414,7 @@ } // Declare an update method in the type of the destination resource. ArrayList parameters = new ArrayList<>(); - getUpdateResourcePathAndPathParams(dstResPath, parameters, isRestAPI, platformSpec, langSpec); // Path parameters to identify the self resource. + generationContext.getUpdateResourcePathAndPathParams(dstResPath, parameters, isRestAPI, platformSpec, langSpec); // Path parameters to identify the self resource. for (Selector selector: ch.getAllSelectors()) { if (selector.getExpression() instanceof Variable) { Variable selVar = (Variable) selector.getExpression(); @@ -1436,7 +1436,7 @@ } } // Get or declare the update method. - MethodDeclaration update = getOrDeclareUpdateMethod(srcResPath.getResourceHierarchy(), resourceNode.getResourceHierarchy(), ch, parameters); + MethodDeclaration update = generationContext.getOrDeclareUpdateMethod(srcResPath.getResourceHierarchy(), resourceNode.getResourceHierarchy(), ch, parameters); // Calculate in-degree (PUSH transfer) of the destination resource. int inDegree = 0; @@ -1448,10 +1448,10 @@ } if (isRestAPI) { // Determine whether the update method is put or post or delete. - if (isPut(out)) { + if (generationContext.isPut(out)) { ((RestApiSpecific) platformSpec).addPutAnnotations(update); } else { - if (!isDelete(out)) { + if (!generationContext.isDelete(out)) { ((RestApiSpecific) platformSpec).addPostAnnotations(update); } else { ((RestApiSpecific) platformSpec).addDeleteAnnotations(update); @@ -1470,7 +1470,7 @@ Term unifiedMassage = null; for (ChannelNode srcChNode: ancestorSrcChannels) { DataTransferChannel abcestorSrcCh = (DataTransferChannel) srcChNode.getChannel(); - Term message = abcestorSrcCh.fillOutsideResourcePaths(out, getPushAccessor(platformSpec), null).getValue(); + Term message = abcestorSrcCh.fillOutsideResourcePaths(out, generationContext.getPushAccessor(platformSpec), null).getValue(); if (unifiedMassage == null) { unifiedMassage = message; } else { @@ -1479,29 +1479,29 @@ } Expression updateExp = null; if (ch.getReferenceChannelMembers().size() == 0) { - Term message = ch.fillOutsideResourcePaths(out, getPushAccessor(platformSpec), null).getValue(); + Term message = ch.fillOutsideResourcePaths(out, generationContext.getPushAccessor(platformSpec), null).getValue(); if (unifiedMassage == null) { unifiedMassage = message; } else { unifiedMassage = (Term) unifiedMassage.unify(message); } - updateExp = ch.deriveUpdateExpressionOf(out, unifiedMassage, getPushAccessor(platformSpec)); + updateExp = ch.deriveUpdateExpressionOf(out, unifiedMassage, generationContext.getPushAccessor(platformSpec)); } else { // if there exists one or more reference channel member. HashMap inputResourceToStateAccessor = new HashMap<>(); for (ChannelMember in: ch.getInputChannelMembers()) { - inputResourceToStateAccessor.put(in, getPushAccessor(platformSpec)); + inputResourceToStateAccessor.put(in, generationContext.getPushAccessor(platformSpec)); } for (ChannelMember ref: ch.getReferenceChannelMembers()) { - inputResourceToStateAccessor.put(ref, getRefAccessor(platformSpec)); + inputResourceToStateAccessor.put(ref, generationContext.getRefAccessor(platformSpec)); } - Term message = ch.fillOutsideResourcePaths(out, getPushAccessor(platformSpec), inputResourceToStateAccessor).getValue(); + Term message = ch.fillOutsideResourcePaths(out, generationContext.getPushAccessor(platformSpec), inputResourceToStateAccessor).getValue(); if (unifiedMassage == null) { unifiedMassage = message; } else { unifiedMassage = (Term) unifiedMassage.unify(message); } - updateExp = ch.deriveUpdateExpressionOf(out, unifiedMassage, getPushAccessor(platformSpec)); + updateExp = ch.deriveUpdateExpressionOf(out, unifiedMassage, generationContext.getPushAccessor(platformSpec)); } // Replace Json constructor with a constructor of the child resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); @@ -1588,7 +1588,7 @@ } else { Term conditions = null; int i = 1; - Map>> resourcePaths = ch.fillOutsideResourcePaths(out, getPushAccessor(platformSpec)); + Map>> resourcePaths = ch.fillOutsideResourcePaths(out, generationContext.getPushAccessor(platformSpec)); for (Expression pathParam: out.getResource().getPathParams()) { if (pathParam instanceof Variable) { String selfParamName = ((Variable) pathParam).getName(); @@ -1636,8 +1636,7 @@ if (!isRestAPI) { // If not a root resource. // Declare an update accessor method in the type of root resource. - declareUpdateAccessorInTheRootResource(resourceNode, update.getName(), ch, out, srcResPath, dstResPath, - rootComponent, inDegree, platformSpec, langSpec); + generationContext.declareUpdateAccessorInTheRootResource(resourceNode, update.getName(), ch, out, srcResPath, dstResPath, rootComponent, inDegree, platformSpec, langSpec); } // to convert a json param to a tuple, pair or map object. for (VariableDeclaration jsonParam: update.getParameters()) { @@ -1751,7 +1750,7 @@ for (ChannelMember out1: ch.getOutputChannelMembers()) { if (resourceNode.getInSideResources().contains(out1.getResource())) { try { - resourcePaths = ch.fillOutsideResourcePaths(out1, getPullAccessor(platformSpec)); + resourcePaths = ch.fillOutsideResourcePaths(out1, generationContext.getPullAccessor(platformSpec)); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined e) { e.printStackTrace(); @@ -1766,7 +1765,7 @@ // An outside input resource path depends on srcRes. ResourcePath outsidePath = resourcePaths.get(outsideMember).getKey(); String outsideResName = langSpec.toVariableName(getComponentName(outsidePath.getResourceHierarchy(), langSpec)); - Expression outsideExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); + Expression outsideExp = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); if (generatesComponent(outsidePath.getResourceHierarchy())) { outsideExp = ((Term) outsideExp).getChild(0); } @@ -1784,7 +1783,7 @@ update.addStatement(updateReference); // Update the reference field. // Update constructor. if (component != null) { - MethodDeclaration constructor = getConstructor(component); + MethodDeclaration constructor = generationContext.getConstructor(component); constructor.addStatement(updateReference); // Initialize the reference field. } else if (parentComponent != null){ constructorStatements.add(updateReference); @@ -1897,12 +1896,12 @@ || insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) != null || !platformSpec.isDifferentTreesAsDifferentServices()) { if (!platformSpec.isMonolithic() && generatesComponent(insideResPath.getResourceHierarchy())) { - Expression getter = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)); + Expression getter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)); Term valueGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); valueGetter.addChild(getter); parent = valueGetter.toImplementation(new String[] {""}); } else { - parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)).toImplementation(new String[] {""}); + parent = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)).toImplementation(new String[] {""}); } } else { // for REST API @@ -1978,7 +1977,7 @@ ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(parentComponent); } } else { - Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, srcRes); + Expression refGetter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, srcRes); String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); forLoopBlock.addStatement(sideEffects[0] + langSpec.newVariableDeclaration(ref.getResourceStateType(), refVarName) @@ -2023,7 +2022,7 @@ if (srcRes2.getParent().equals(dstRes2.getParent())) { Map>> resourcePaths = null; try { - resourcePaths = ch2.fillOutsideResourcePaths(out2, getPullAccessor(platformSpec)); + resourcePaths = ch2.fillOutsideResourcePaths(out2, generationContext.getPullAccessor(platformSpec)); if (resourcePaths != null && resourcePaths.size() > 0) { for (ChannelMember outsideMember: outsideInputMembers2) { for (ChannelMember dependedMember: resourcePaths.get(outsideMember).getValue()) { @@ -2034,7 +2033,7 @@ outsidePath = outsidePath.getParent(); } String outsideResName = langSpec.toVariableName(getComponentName(outsidePath.getResourceHierarchy(), langSpec)); - Expression outsideExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); + Expression outsideExp = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); if (generatesComponent(outsidePath.getResourceHierarchy())) { outsideExp = ((Term) outsideExp).getChild(0); } @@ -2044,7 +2043,7 @@ update.addStatement(updateReference); // Update the reference field. // Update constructor. if (component != null) { - MethodDeclaration constructor = getConstructor(component); + MethodDeclaration constructor = generationContext.getConstructor(component); constructor.addStatement(updateReference); // Initialize the reference field. } else if (parentComponent != null) { constructorStatements.add(updateReference); @@ -2097,7 +2096,7 @@ ArrayList rootInputParams = new ArrayList<>(); String resourcePath = null; if (!platformSpec.isMonolithic()) { - resourcePath = getInputMethodResourcePathAndPathParams(out.getResource(), rootInputParams, platformSpec, langSpec); // Path parameters for the input REST API. + resourcePath = generationContext.getInputMethodResourcePathAndPathParams(out.getResource(), rootInputParams, platformSpec, langSpec); // Path parameters for the input REST API. if (resourcePath.indexOf('/') > 0) { // Remove the root resource from the path resourcePath = resourcePath.substring(resourcePath.indexOf('/')); @@ -2207,7 +2206,7 @@ // Declare the accessor in the main component to call the input method. (for monolithic application) if (platformSpec.hasMain()) { String messageSymbol = ((Term) message).getSymbol().getImplName(); - mainInputAccessor = getMethod(mainComponent, messageSymbol); + mainInputAccessor = generationContext.getMethod(mainComponent, messageSymbol); if (mainInputAccessor == null) { mainInputAccessor = langSpec.newMethodDeclaration(messageSymbol, false, null, mainInputParams); mainComponent.addMethod(mainInputAccessor); @@ -2233,7 +2232,7 @@ // If out is the receiver of the input event. priorMemberForInputChannel.put(ch, out); String messageSymbol = ((Term) message).getSymbol().getImplName(); - rootInputAccessor = declareInputAccessorInTheRootResource(messageSymbol, rootInputParams, out, resourcePath, + rootInputAccessor = generationContext.declareInputAccessorInTheRootResource(messageSymbol, rootInputParams, out, resourcePath, rootComponent, platformSpec, langSpec); if (input == null) { input = rootInputAccessor; @@ -2315,7 +2314,7 @@ // Declare the accessor in the main component to call the input method. (for monolithic application) if (platformSpec.hasMain()) { String messageSymbol = ((Variable) message).getName(); - mainInputAccessor = getMethod(mainComponent, messageSymbol, mainInputParams); + mainInputAccessor = generationContext.getMethod(mainComponent, messageSymbol, mainInputParams); if (mainInputAccessor == null) { if (mainInputParams.size() == 0) { mainInputAccessor = langSpec.newMethodDeclaration(messageSymbol, null); @@ -2332,7 +2331,7 @@ // If out is the receiver of the input event. priorMemberForInputChannel.put(ch, out); ArrayList rootInputParams = new ArrayList<>(); - String resourcePath = getGetterResourcePathAndPathParams(out.getResource(), rootInputParams, platformSpec, langSpec); + String resourcePath = generationContext.getGetterResourcePathAndPathParams(out.getResource(), rootInputParams, platformSpec, langSpec); if (resourcePath.indexOf('/') > 0) { // Remove the root resource from the path resourcePath = resourcePath.substring(resourcePath.indexOf('/')); @@ -2340,7 +2339,7 @@ resourcePath = ""; } String messageSymbol = ((Variable) message).getName(); - rootInputAccessor = declareInputAccessorInTheRootResource(messageSymbol, rootInputParams, out, resourcePath, + rootInputAccessor = generationContext.declareInputAccessorInTheRootResource(messageSymbol, rootInputParams, out, resourcePath, rootComponent, platformSpec, langSpec); if (input == null) { input = rootInputAccessor; @@ -2359,7 +2358,7 @@ ResourcePath ref = rc.getResource(); if (!out.getResource().equals(ref)) { String refVarName = ref.getLeafResourceName(); - Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, null); + Expression refGetter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, null); String[] sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); @@ -2368,7 +2367,7 @@ } } } - Expression resExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(out.getResource(), null); + Expression resExp = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(out.getResource(), null); List args = new ArrayList<>(); if (resExp instanceof Term) { // To access the parent resource if the leaf resource is primitive and cannot declare the input method, or to remove getValue(). @@ -2417,7 +2416,7 @@ if (input != null) { // Add a statement to update the state field to the input method. try { - Expression updateExp = ((DataTransferChannel) ch).deriveUpdateExpressionOf(out, getRefAccessor(platformSpec)).getKey(); + Expression updateExp = ((DataTransferChannel) ch).deriveUpdateExpressionOf(out, generationContext.getRefAccessor(platformSpec)).getKey(); // 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) { @@ -2512,7 +2511,7 @@ ((RestApiSpecific) platformSpec).addHttpClientFieldDeclaration(parentComponent); } } else { - Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, dstRes); + Expression refGetter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, dstRes); String refExp = refGetter.toImplementation(sideEffects); String refTypeName = refResourceType.getInterfaceTypeName(); input.addFirstStatement(sideEffects[0] + langSpec.newVariableDeclaration(refResourceType, refResourceName) @@ -2530,7 +2529,7 @@ Parameter pathParam = new Parameter(rootInputAccessor.getParameters().get(i).getName()); outResPath.replacePathParam(i, pathParam, null); } - Expression resExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outResPath, outResPath.getRoot()); + Expression resExp = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(outResPath, outResPath.getRoot()); List args = new ArrayList<>(); if (resExp instanceof Term) { // To access the parent resource if the leaf resource is primitive and cannot declare the input method, or to remove getValue(). @@ -2684,12 +2683,12 @@ || insideResPath.getCommonPrefix(resourceNode.getOutSideResource(directDstCh)) != null || !platformSpec.isDifferentTreesAsDifferentServices()) { if (!platformSpec.isMonolithic() && generatesComponent(insideResPath.getResourceHierarchy())) { - Expression getter = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)); + Expression getter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)); Term valueGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD)); valueGetter.addChild(getter); parent = valueGetter.toImplementation(new String[] {""}); } else { - parent = getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)).toImplementation(new String[] {""}); + parent = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(insideResPath, resourceNode.getOutSideResource(directDstCh)).toImplementation(new String[] {""}); } } else { // for REST API @@ -2748,7 +2747,7 @@ if (!generatesComponent(srcRes.getResourceHierarchy())) { srcRes = srcRes.getParent(); } - Expression refGetter = getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, srcRes); + Expression refGetter = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(ref, srcRes); String[] sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); @@ -2790,7 +2789,7 @@ if (srcRes2.getParent().equals(dstRes2.getParent())) { Map>> resourcePaths = null; try { - resourcePaths = directDstCh.fillOutsideResourcePaths(out2, getPullAccessor(platformSpec)); + resourcePaths = directDstCh.fillOutsideResourcePaths(out2, generationContext.getPullAccessor(platformSpec)); if (resourcePaths != null && resourcePaths.size() > 0) { for (ChannelMember outsideMember: outsideInputMembers2) { for (ChannelMember dependedMember: resourcePaths.get(outsideMember).getValue()) { @@ -2801,7 +2800,7 @@ outsidePath = outsidePath.getParent(); } String outsideResName = langSpec.toVariableName(getComponentName(outsidePath.getResourceHierarchy(), langSpec)); - Expression outsideExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); + Expression outsideExp = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); if (generatesComponent(outsidePath.getResourceHierarchy())) { outsideExp = ((Term) outsideExp).getChild(0); } @@ -2811,7 +2810,7 @@ // Update constructor. String initializingStatement = langSpec.getFieldAccessor(outsideResName) + langSpec.getAssignment() + outsideAccessor + langSpec.getStatementDelimiter(); if (component != null) { - MethodDeclaration constructor = getConstructor(component); + MethodDeclaration constructor = generationContext.getConstructor(component); constructor.addStatement(initializingStatement); // initialize the reference field. } else { constructorStatements.add(initializingStatement); // initialize the reference field. @@ -2849,7 +2848,7 @@ // Update fields to refer to outside resources. ResourcePath filledOutsideResourcePath = null; try { - Map>> resourcePaths = ch.fillOutsideResourcePaths(out, getPullAccessor(platformSpec)); + Map>> resourcePaths = ch.fillOutsideResourcePaths(out, generationContext.getPullAccessor(platformSpec)); if (resourcePaths != null && resourcePaths.size() > 0) { for (ChannelMember outsideMember: resourcePaths.keySet()) { ResourcePath outsidePath = resourcePaths.get(outsideMember).getKey(); @@ -2860,7 +2859,7 @@ outsidePath = outsidePath.getParent(); } String outsideResName = langSpec.toVariableName(getComponentName(outsidePath.getResourceHierarchy(), langSpec)); - Expression outsideExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); + Expression outsideExp = generationContext.getPullAccessor(platformSpec).getDirectStateAccessorFor(outsidePath, null); if (generatesComponent(outsidePath.getResourceHierarchy())) { outsideExp = ((Term) outsideExp).getChild(0); } @@ -2955,7 +2954,7 @@ // Call the update method. ResourceHierarchy dstRes = dstNode.getResourceHierarchy(); - String updateMethodName = getUpdateMethodName(srcNode.getResourceHierarchy(), dstRes, ch); // Get the method name. + String updateMethodName = generationContext.getOrPutUpdateMethodName(srcNode.getResourceHierarchy(), ch, dstRes); // Get the method name. if (!generatesComponent(dstRes)) { dstRes = dstRes.getParent(); } @@ -2983,7 +2982,7 @@ } Map>> filledPaths = null; try { - filledPaths = ch.fillOutsideResourcePaths(out, getPushAccessor(platformSpec)); + filledPaths = ch.fillOutsideResourcePaths(out, generationContext.getPushAccessor(platformSpec)); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined e) { @@ -3127,22 +3126,22 @@ IResourceStateAccessor resouceStateAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { - return getPushAccessor(platformSpec).getCurrentStateAccessorFor(out, out); + return generationContext.getPushAccessor(platformSpec).getCurrentStateAccessorFor(out, out); } @Override public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { try { - return inCh.deriveUpdateExpressionOf(out, getPushAccessor(platformSpec)).getKey(); + return inCh.deriveUpdateExpressionOf(out, generationContext.getPushAccessor(platformSpec)).getKey(); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined e) { - return getPushAccessor(platformSpec).getNextStateAccessorFor(out, out); + return generationContext.getPushAccessor(platformSpec).getNextStateAccessorFor(out, out); } } @Override public Expression getDirectStateAccessorFor(ResourcePath target, ResourcePath from) { - return getPushAccessor(platformSpec).getDirectStateAccessorFor(target, from); + return generationContext.getPushAccessor(platformSpec).getDirectStateAccessorFor(target, from); } }; Map> substitutedPositionsInMessageFromChannels = new HashMap<>(); @@ -3158,182 +3157,4 @@ } catch (ResolvingMultipleDefinitionIsFutureWork | InvalidMessage e) { } } - - protected MethodDeclaration getOrDeclareUpdateMethod(ResourceHierarchy srcRes, ResourceHierarchy dstRes, DataTransferChannel ch, ArrayList parameters) { - MethodDeclaration update = null; - String updateMethodName = getUpdateMethodName(srcRes, dstRes, ch); - if (generatesComponent(dstRes)) { - // A component is created for this resource. - TypeDeclaration dstComponent = generationContext.getComponent(dstRes); - for (MethodDeclaration method: dstComponent.getMethods()) { - if (method.getName().equals(updateMethodName)) { - update = method; - break; - } - } - if (update == null) { - update = langSpec.newMethodDeclaration(updateMethodName, false, null, parameters); - dstComponent.addMethod(update); - } - } else if (dstRes.getParent() != null) { - // No component is created for this resource. - TypeDeclaration dstParentComponent = generationContext.getComponent(dstRes.getParent()); - for (MethodDeclaration method: dstParentComponent.getMethods()) { - if (method.getName().equals(updateMethodName)) { - update = method; - break; - } - } - if (update == null) { - update = langSpec.newMethodDeclaration(updateMethodName, false, null, parameters); - dstParentComponent.addMethod(update); - } - } - return update; - } - - protected void declareGetterAccessorInTheRootResource(ResourceNode resourceNode, TypeDeclaration rootComponent) { - if (resourceNode.getResourceHierarchy().getParent() != null) { - // For a non-root resource - MethodDeclaration getterAccessor = null; - List mainGetterParams = new ArrayList<>(); - String resourcePath = getGetterResourcePathAndPathParams(resourceNode.getPrimaryResourcePath(), mainGetterParams, platformSpec, langSpec); - if (resourcePath.indexOf('/') > 0) { - // Remove the root resource from the path - resourcePath = resourcePath.substring(resourcePath.indexOf('/')); - } else { - resourcePath = ""; - } - if (mainGetterParams.size() > 0) { - getterAccessor = langSpec.newMethodDeclaration(getterPrefix + getComponentName(resourceNode.getResourceHierarchy(), langSpec) + methoNameOfResourceState, - false, - getImplStateType(resourceNode.getResourceHierarchy(), langSpec), - mainGetterParams); - } else { - getterAccessor = langSpec.newMethodDeclaration(getterPrefix + getComponentName(resourceNode.getResourceHierarchy(), langSpec) + methoNameOfResourceState, - getImplStateType(resourceNode.getResourceHierarchy(), langSpec)); - } - getterAccessor.setBody(new Block()); - ResourcePath resPath = new ResourcePath(resourceNode.getPrimaryResourcePath()); - for (int i = 0; i < mainGetterParams.size(); i++) { - Parameter pathParam = new Parameter(mainGetterParams.get(i).getName()); - resPath.replacePathParam(i, pathParam, null); - } - Expression getState = getPullAccessor(platformSpec).getDirectStateAccessorFor(resPath, resPath.getRoot()); - getterAccessor.getBody().addStatement(langSpec.getReturnStatement(getState.toImplementation(new String[] {null}))); - if (!platformSpec.isMonolithic()) { - ((RestApiSpecific) platformSpec).addGetAnnotations(getterAccessor); - if (resourcePath.length() > 0) { - ((RestApiSpecific) platformSpec).addPathAnnotation(getterAccessor, resourcePath); - } - } - rootComponent.addMethod(getterAccessor); - } - } - - protected void declareUpdateAccessorInTheRootResource(ResourceNode resourceNode, String updateMethodName, - DataTransferChannel ch, ChannelMember cm, ResourcePath srcResPath, ResourcePath dstResPath, TypeDeclaration rootComponent, - int inDegree, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { - ArrayList parameters; - VariableDeclaration param; - parameters = new ArrayList<>(); - String resourcePath = getUpdateResourcePathAndPathParams(dstResPath, parameters, true, platformSpec, langSpec); // Path parameters to identify the self resource. - if (resourcePath.indexOf('/') > 0) { - // Remove the root resource from the path - resourcePath = resourcePath.substring(resourcePath.indexOf('/')); - } else { - resourcePath = ""; - } - ResourcePath resPath = new ResourcePath(dstResPath); - for (int i = 0; i < parameters.size(); i++) { - Parameter pathParam = new Parameter(parameters.get(i).getName()); - resPath.replacePathParam(i, pathParam, null); - } - for (Selector selector: ch.getAllSelectors()) { - if (selector.getExpression() instanceof Variable) { - Variable selVar = (Variable) selector.getExpression(); - VariableDeclaration chParam = langSpec.newVariableDeclaration(selVar.getType(), selVar.getName()); - if (!platformSpec.isMonolithic()) { - ((RestApiSpecific) platformSpec).addFormParamAnnotation(chParam, selVar.getName()); - } - parameters.add(chParam); // A channel parameter to specify the context of the collaboration. - } - } - Type srcType = srcResPath.getResourceStateType(); - String srcResName = langSpec.toVariableName(getComponentName(srcResPath.getResourceHierarchy(), langSpec)); - param = langSpec.newVariableDeclaration(srcType, srcResName); - if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addFormParamAnnotation(param, srcResName); - parameters.add(param); // The state of the source resource to carry the data-flow. - for (ResourcePath refRes: ch.getReferenceResources()) { - if (!refRes.equals(resourceNode.getInSideResource(ch))) { - String refName = langSpec.toVariableName(getComponentName(refRes.getResourceHierarchy(), langSpec)); - param = langSpec.newVariableDeclaration(refRes.getResourceStateType(), refName); - if (!platformSpec.isMonolithic()) { - ((RestApiSpecific) platformSpec).addFormParamAnnotation(param, refName); - } - parameters.add(param); - } - } - MethodDeclaration updateAccessor = langSpec.newMethodDeclaration(updateMethodName, false, null, parameters); - if (!platformSpec.isMonolithic()) { - if (isPut(cm)) { - ((RestApiSpecific) platformSpec).addPutAnnotations(updateAccessor); - } else { - if (!isDelete(cm)) { - ((RestApiSpecific) platformSpec).addPostAnnotations(updateAccessor); - } else { - ((RestApiSpecific) platformSpec).addDeleteAnnotations(updateAccessor); - } - } - } - if (inDegree > 1) { - // For each source resource, a child resource is defined in the destination resource so that its state can be updated separately. - resourcePath += "/" + langSpec.toVariableName(srcResName); - } - if (!platformSpec.isMonolithic()) ((RestApiSpecific) platformSpec).addPathAnnotation(updateAccessor, resourcePath); - - // To make the accessor call the update method. - Expression resExp = getPullAccessor(platformSpec).getDirectStateAccessorFor(resPath, resPath.getRoot()); - List args = new ArrayList<>(); - if (resExp instanceof Term) { - // To access the parent resource if the leaf resource is primitive and cannot declare the update method, or to remove getValue(). - if (((Term) resExp).getChildren().size() > 1 && ((Term) resExp).getChild(1) instanceof Variable) { - args.add(((Variable)((Term) resExp).getChild(1)).getName()); - } - resExp = ((Term) resExp).getChild(0); - } - for (VariableDeclaration var: updateAccessor.getParameters()) { - args.add(var.getName()); - } - 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); - } - - protected MethodDeclaration declareInputAccessorInTheRootResource(String inputMethodName, - ArrayList rootInputParams, ChannelMember cm, String resourcePath, - TypeDeclaration rootComponent, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { - MethodDeclaration rootInputAccessor; - rootInputAccessor = langSpec.newMethodDeclaration(inputMethodName, false, null, rootInputParams); - if (!platformSpec.isMonolithic()) { - if (isPut(cm)) { - ((RestApiSpecific) platformSpec).addPutAnnotations(rootInputAccessor); - } else { - if (!isDelete(cm)) { - ((RestApiSpecific) platformSpec).addPostAnnotations(rootInputAccessor); - } else { - ((RestApiSpecific) platformSpec).addDeleteAnnotations(rootInputAccessor); - } - } - if (resourcePath.length() > 0) { - ((RestApiSpecific) platformSpec).addPathAnnotation(rootInputAccessor, resourcePath); - } - } - rootComponent.addMethod(rootInputAccessor); - return rootInputAccessor; - } }