diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index ae86204..722a4a7 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -66,6 +66,7 @@ if (generatesComponent(resourceNode.getResourceHierarchy())) { // A component will be generated for this resource. String resourceName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); + Type resStateType = getImplStateType(resourceNode.getResourceHierarchy(), langSpec); component = resourceComponents.get(resourceNode.getResourceHierarchy()); List depends = new ArrayList<>(); if (component == null) { @@ -92,6 +93,20 @@ } else { resourceConstructors.put(resourceNode.getResourceHierarchy(), constructor); } + + // Declare the field to store the state in this resource. + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + declareStateField(resourceNode, resourceName, component, resStateType, constructorParams, langSpec); + } + + // Declare the getter method in this resource to obtain the state. + MethodDeclaration stateGetter = declareStateGetterMethod(resourceNode, component, resStateType, langSpec); + + // Declare the accessor method in the main component to call the getter method. + declareAccessorInMainComponent(mainComponent, resourceNode, stateGetter, langSpec); + + // Declare the getter methods in this resource to obtain the children resources. + declareChildGetterMethod(resourceNode, component, langSpec); } } } @@ -104,16 +119,7 @@ TypeDeclaration component = null; TypeDeclaration parentComponent = null; if (generatesComponent(resourceNode.getResourceHierarchy())) { - String resourceName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); - component = resourceComponents.get(resourceNode.getResourceHierarchy()); - - // Declare the field in this resource to store the state. - if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { - declareStateField(resourceNode, resourceName, component, resStateType, constructorParams, langSpec); - } - - // Declare the getter methods in this resource to obtain the children resources. - declareChildGetterMethod(resourceNode, component, langSpec); + component = resourceComponents.get(resourceNode.getResourceHierarchy()); } if (resourceNode.getResourceHierarchy().getParent() != null) { parentComponent = resourceComponents.get(resourceNode.getResourceHierarchy().getParent()); @@ -137,10 +143,14 @@ } // Declare the getter method in this resource to obtain the state. - MethodDeclaration stateGetter = declareStateGetterMethod(resourceNode, component, parentComponent, resStateType, langSpec); - - // Declare the accessor method in the main component to call the getter method. - declareAccessorInMainComponent(mainComponent, resourceNode, stateGetter, langSpec); + if (component == null) { + MethodDeclaration stateGetter = declareStateGetterMethodInParent(resourceNode, parentComponent, resStateType, langSpec); + + if (stateGetter != null) { + // Declare the accessor method in the main component to call the getter method. + declareAccessorInMainComponent(mainComponent, resourceNode, stateGetter, langSpec); + } + } // Declare input methods in this component and the main component. Map.Entry, Map>> initStatementsAndInputUpdates = declareInputMethodsInThisAndMainComponents(resourceNode, component, parentComponent, mainComponent, model, langSpec); @@ -477,132 +487,148 @@ } } - private MethodDeclaration declareStateGetterMethod(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, Type resStateType, ILanguageSpecific langSpec) { + + private MethodDeclaration declareStateGetterMethod(ResourceNode resourceNode, TypeDeclaration component, Type resStateType, ILanguageSpecific langSpec) { // Declare the getter method of the resource state. - MethodDeclaration stateGetter = null; - if (component != null) { - // A component is created for this resource. - stateGetter = langSpec.newMethodDeclaration(getterOfResourceState, resStateType); - component.addMethod(stateGetter); - } else { - // No component is created for this resource. - List getterParams = new ArrayList<>(); - int v = 1; - for (Selector param: resourceNode.getSelectors()) { - if (param.getExpression() instanceof Variable) { - Variable var = (Variable) param.getExpression(); - getterParams.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (param.getExpression() instanceof Term) { - Term var = (Term) param.getExpression(); - getterParams.add(new VariableDeclaration(var.getType(), "v" + v)); - } - v++; - } - String resCompName = getComponentName(resourceNode.getResourceHierarchy(), langSpec); - if (getterParams.size() == 0) { - stateGetter = new MethodDeclaration(getterPrefix + resCompName, resStateType); - } else { - stateGetter = new MethodDeclaration(getterPrefix + resCompName, false, resStateType, getterParams); - } - if (parentComponent != null) { - parentComponent.addMethod(stateGetter); - } - } + MethodDeclaration stateGetter = langSpec.newMethodDeclaration(getterOfResourceState, resStateType); + component.addMethod(stateGetter); if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { - if (component != null) { - // A component is created for this resource. - fillStateGetterMethod(stateGetter, resourceNode.getResourceHierarchy(), resStateType, langSpec); - } else { - // No component is created for this resource. - fillChildGetterMethod(stateGetter, resourceNode.getResourceHierarchy(), resourceNode.getResourceHierarchy().getParent().getResourceStateType(), langSpec); - } + fillStateGetterMethod(stateGetter, resourceNode.getResourceHierarchy(), resStateType, langSpec); } else { // invocations to other getter methods when at least one incoming data-flow edges is PULL-style. - boolean isContainedPush = false; - DataTransferChannel ch = null; - HashMap inputResourceToStateAccessor = new HashMap<>(); - for (Edge chToRes: resourceNode.getInEdges()) { - DataTransferChannel ch2 = ((ChannelNode) chToRes.getSource()).getChannel(); - for (Edge resToCh: chToRes.getSource().getInEdges()) { - DataFlowEdge dIn = (DataFlowEdge) resToCh; - ChannelMember in = null; - for (ChannelMember cm: ch2.getInputChannelMembers()) { - if (cm.getResource().equals(((ResourceNode) dIn.getSource()).getOutSideResource())) { - in = cm; - break; - } - } - if (((PushPullAttribute) dIn.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { - // PUSH transfer - isContainedPush = true; - inputResourceToStateAccessor.put(in, getPushAccessor()); - } else { - // PULL transfer - inputResourceToStateAccessor.put(in, getPullAccessor()); - ch = ((ChannelNode) resToCh.getDestination()).getChannel(); // pull containing input side channel is always one. - } - } - } - // for reference channel members. - for (ChannelMember c: ch.getReferenceChannelMembers()) { - inputResourceToStateAccessor.put(c, getPullAccessor()); // by pull data transfer - } - - // generate a return statement. - try { - for (ChannelMember out: ch.getOutputChannelMembers()) { - if (resourceNode.getInSideResources().contains(out.getResource())) { - String[] sideEffects = new String[] {""}; - if (!isContainedPush) { - // All incoming edges are in PULL-style. - String curState = ch.deriveUpdateExpressionOf(out, getPullAccessor()).toImplementation(sideEffects); - stateGetter.addStatement(sideEffects[0] + langSpec.getReturnStatement(curState) + langSpec.getStatementDelimiter()); - } else { - // At least one incoming edge is in PUSH-style. - String curState = ch.deriveUpdateExpressionOf(out, getPullAccessor(), inputResourceToStateAccessor).toImplementation(sideEffects); - stateGetter.addStatement(sideEffects[0] + langSpec.getReturnStatement(curState) + langSpec.getStatementDelimiter()); - } - break; - } - } - } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined e) { - e.printStackTrace(); - } + addOtherGetterInvocationsToStateGatter(stateGetter, resourceNode, langSpec); } return stateGetter; } + private MethodDeclaration declareStateGetterMethodInParent(ResourceNode resourceNode, TypeDeclaration parentComponent, Type resStateType, ILanguageSpecific langSpec) { + // Check duplication. + String getterName = getterPrefix + getComponentName(resourceNode.getResourceHierarchy(), langSpec); + for (MethodDeclaration method: parentComponent.getMethods()) { + if (method.getName().equals(getterName)) return null; + } + + // Declare the getter method of the resource state. + List getterParams = new ArrayList<>(); + int v = 1; + for (Selector param: resourceNode.getSelectors()) { + if (param.getExpression() instanceof Variable) { + Variable var = (Variable) param.getExpression(); + getterParams.add(new VariableDeclaration(var.getType(), var.getName())); + } else if (param.getExpression() instanceof Term) { + Term var = (Term) param.getExpression(); + getterParams.add(new VariableDeclaration(var.getType(), "v" + v)); + } + v++; + } + MethodDeclaration stateGetter = null; + if (getterParams.size() == 0) { + stateGetter = new MethodDeclaration(getterName, resStateType); + } else { + stateGetter = new MethodDeclaration(getterName, false, resStateType, getterParams); + } + if (parentComponent != null) { + parentComponent.addMethod(stateGetter); + } + + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + fillChildGetterMethod(stateGetter, resourceNode.getResourceHierarchy(), resourceNode.getResourceHierarchy().getParent().getResourceStateType(), langSpec); + } else { + addOtherGetterInvocationsToStateGatter(stateGetter, resourceNode, langSpec); + } + + return stateGetter; + } + + private void addOtherGetterInvocationsToStateGatter(MethodDeclaration stateGetter, ResourceNode resourceNode, + ILanguageSpecific langSpec) { + boolean isContainedPush = false; + DataTransferChannel ch = null; + HashMap inputResourceToStateAccessor = new HashMap<>(); + for (Edge chToRes: resourceNode.getInEdges()) { + DataTransferChannel ch2 = ((ChannelNode) chToRes.getSource()).getChannel(); + for (Edge resToCh: chToRes.getSource().getInEdges()) { + DataFlowEdge dIn = (DataFlowEdge) resToCh; + ChannelMember in = null; + for (ChannelMember cm: ch2.getInputChannelMembers()) { + if (cm.getResource().equals(((ResourceNode) dIn.getSource()).getOutSideResource())) { + in = cm; + break; + } + } + if (((PushPullAttribute) dIn.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + // PUSH transfer + isContainedPush = true; + inputResourceToStateAccessor.put(in, getPushAccessor()); + } else { + // PULL transfer + inputResourceToStateAccessor.put(in, getPullAccessor()); + ch = ((ChannelNode) resToCh.getDestination()).getChannel(); // pull containing input side channel is always one. + } + } + } + // for reference channel members. + for (ChannelMember c: ch.getReferenceChannelMembers()) { + inputResourceToStateAccessor.put(c, getPullAccessor()); // by pull data transfer + } + + // generate a return statement. + try { + for (ChannelMember out: ch.getOutputChannelMembers()) { + if (resourceNode.getInSideResources().contains(out.getResource())) { + String[] sideEffects = new String[] {""}; + if (!isContainedPush) { + // All incoming edges are in PULL-style. + String curState = ch.deriveUpdateExpressionOf(out, getPullAccessor()).toImplementation(sideEffects); + stateGetter.addStatement(sideEffects[0] + langSpec.getReturnStatement(curState) + langSpec.getStatementDelimiter()); + } else { + // At least one incoming edge is in PUSH-style. + String curState = ch.deriveUpdateExpressionOf(out, getPullAccessor(), inputResourceToStateAccessor).toImplementation(sideEffects); + stateGetter.addStatement(sideEffects[0] + langSpec.getReturnStatement(curState) + langSpec.getStatementDelimiter()); + } + break; + } + } + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { + e.printStackTrace(); + } + } + private void declareChildGetterMethod(ResourceNode resourceNode, TypeDeclaration component, ILanguageSpecific langSpec) { // Declare the getter methods in this resource to obtain the children resources. + Set children = new HashSet<>(); for (ResourceNode child: resourceNode.getChildren()) { if (generatesComponent(child.getResourceHierarchy())) { // A component for the child is generated. - List params = new ArrayList<>(); - int v = 1; - for (Selector param: child.getSelectors()) { - if (param.getExpression() instanceof Variable) { - Variable var = (Variable) param.getExpression(); - params.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); - } else if (param.getExpression() instanceof Term) { - Term var = (Term) param.getExpression(); - params.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); + if (!children.contains(child.getResourceHierarchy())) { + children.add(child.getResourceHierarchy()); + List params = new ArrayList<>(); + int v = 1; + for (Selector param: child.getSelectors()) { + if (param.getExpression() instanceof Variable) { + Variable var = (Variable) param.getExpression(); + params.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + } else if (param.getExpression() instanceof Term) { + Term var = (Term) param.getExpression(); + params.add(langSpec.newVariableDeclaration(var.getType(), "v" + v)); + } + v++; } - v++; + String childCompName = getComponentName(child.getResourceHierarchy(), langSpec); + Type childType = new Type(childCompName, childCompName); + MethodDeclaration childGetter = null; + if (params.size() == 0) { + childGetter = langSpec.newMethodDeclaration(getterPrefix + childCompName, childType); + } else { + childGetter = langSpec.newMethodDeclaration(getterPrefix + childCompName, false, childType, params); + } + + fillChildGetterMethod(childGetter, child.getResourceHierarchy(), resourceNode.getResourceStateType(), langSpec); + component.addMethod(childGetter); } - String childCompName = getComponentName(child.getResourceHierarchy(), langSpec); - Type childType = new Type(childCompName, childCompName); - MethodDeclaration childGetter = null; - if (params.size() == 0) { - childGetter = langSpec.newMethodDeclaration(getterPrefix + childCompName, childType); - } else { - childGetter = langSpec.newMethodDeclaration(getterPrefix + childCompName, false, childType, params); - } - - fillChildGetterMethod(childGetter, child.getResourceHierarchy(), resourceNode.getResourceStateType(), langSpec); - component.addMethod(childGetter); } } } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java index b41d37e..72c4200 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java @@ -148,6 +148,7 @@ // For each resource node. for (ResourceNode resourceNode: resources) { TypeDeclaration component = null; + boolean bComponentCreated = false; Set depends = new HashSet<>(); Set refs = new HashSet<>(); if (generatesComponent(resourceNode.getResourceHierarchy())) { @@ -157,6 +158,7 @@ component = resourceComponents.get(resourceNode.getResourceHierarchy()); if (component == null) { // Add compilation unit for each resource. + bComponentCreated = true; component = new TypeDeclaration(resourceName); resourceComponents.put(resourceNode.getResourceHierarchy(), component); CompilationUnit cu = new CompilationUnit(component); @@ -235,65 +237,76 @@ } mainConstructorBody.addStatement(resourceNode.getResourceName() + " = " + fieldInitializer + ";"); } - } - - // Declare the field to store the state in the type of each resource. - if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { - ResourcePath res = resourceNode.getOutSideResource(); - Set children = resourceNode.getResourceHierarchy().getChildren(); - if (children == null || children.size() == 0) { - // leaf resource. - Type fieldType = getImplStateType(res.getResourceHierarchy()); - component.addField(new FieldDeclaration(fieldType, "value", getInitializer(res))); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), new VariableDeclaration(fieldType, toVariableName(resourceName)))); - } else { - ResourceHierarchy child = children.iterator().next(); - if (children.size() == 1 && child.getNumParameters() > 0) { - // map or list. - component.addField(new FieldDeclaration(getImplStateType(res.getResourceHierarchy()), "value", getInitializer(res))); + + // Declare the field to store the state in the type of each resource. + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + ResourcePath res = resourceNode.getOutSideResource(); + Set children = resourceNode.getResourceHierarchy().getChildren(); + if (children == null || children.size() == 0) { + // leaf resource. + Type fieldType = getImplStateType(res.getResourceHierarchy()); + component.addField(new FieldDeclaration(fieldType, "value", getInitializer(res))); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), new VariableDeclaration(fieldType, toVariableName(resourceName)))); } else { - // class - for (ResourceHierarchy c: children) { - String childTypeName = getComponentName(c); - Type childType = null; - if (generatesComponent(c)) { - // The child has a component. - childType = new Type(childTypeName, childTypeName); - String fieldName = toVariableName(childTypeName); - component.addField(new FieldDeclaration(childType, fieldName, getInitializer(res))); + ResourceHierarchy child = children.iterator().next(); + if (children.size() == 1 && child.getNumParameters() > 0) { + // map or list. + component.addField(new FieldDeclaration(getImplStateType(res.getResourceHierarchy()), "value", getInitializer(res))); + } else { + // class + for (ResourceHierarchy c: children) { + String childTypeName = getComponentName(c); + Type childType = null; + if (generatesComponent(c)) { + // The child has a component. + childType = new Type(childTypeName, childTypeName); + String fieldName = toVariableName(childTypeName); + component.addField(new FieldDeclaration(childType, fieldName, getInitializer(res))); + } } } } } - } - - // Declare the getter methods to obtain the children resources. - for (ResourceNode child: resourceNode.getChildren()) { - if (generatesComponent(child.getResourceHierarchy())) { - // A component for the child is generated. - List params = new ArrayList<>(); - int v = 1; - for (Selector param: child.getSelectors()) { - if (param.getExpression() instanceof Variable) { - Variable var = (Variable) param.getExpression(); - params.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (param.getExpression() instanceof Term) { - Term var = (Term) param.getExpression(); - params.add(new VariableDeclaration(var.getType(), "v" + v)); + + // Declare the getter method to obtain the resource state in this component. + MethodDeclaration stateGetter = new MethodDeclaration("getValue", getImplStateType(resourceNode.getResourceHierarchy())); + component.addMethod(stateGetter); + + // Declare the accessor method in the main type to call the getter method. + declareAccessorMethodInMainComponent(resourceNode, mainComponent); + + // Declare the getter methods to obtain the children resources. + Set children = new HashSet<>(); + for (ResourceNode child: resourceNode.getChildren()) { + if (generatesComponent(child.getResourceHierarchy())) { + // A component for the child is generated. + if (!children.contains(child.getResourceHierarchy())) { + children.add(child.getResourceHierarchy()); + List params = new ArrayList<>(); + int v = 1; + for (Selector param: child.getSelectors()) { + if (param.getExpression() instanceof Variable) { + Variable var = (Variable) param.getExpression(); + params.add(new VariableDeclaration(var.getType(), var.getName())); + } else if (param.getExpression() instanceof Term) { + Term var = (Term) param.getExpression(); + params.add(new VariableDeclaration(var.getType(), "v" + v)); + } + v++; + } + String childCompName = getComponentName(child.getResourceHierarchy()); + Type childType = new Type(childCompName, childCompName); + MethodDeclaration childGetter = null; + if (params.size() == 0) { + childGetter = new MethodDeclaration("get" + childCompName, childType); + } else { + childGetter = new MethodDeclaration("get" + childCompName, false, childType, params); + } + component.addMethod(childGetter); } - v++; } - String childCompName = getComponentName(child.getResourceHierarchy()); - Type childType = new Type(childCompName, childCompName); - MethodDeclaration childGetter = null; - if (params.size() == 0) { - childGetter = new MethodDeclaration("get" + childCompName, childType); - } else { - childGetter = new MethodDeclaration("get" + childCompName, false, childType, params); - } - component.addMethod(childGetter); } - } + } } // Declare the state field and reference fields in the parent component. @@ -375,64 +388,44 @@ } } - // Declare the getter method in this component to obtain the resource state. - if (component != null) { - // A component is created for this resource. - MethodDeclaration stateGetter = new MethodDeclaration("getValue", getImplStateType(resourceNode.getResourceHierarchy())); - component.addMethod(stateGetter); - } else { - // No component is created for this resource. - List getterParams = new ArrayList<>(); - int v = 1; - for (Selector param: resourceNode.getSelectors()) { - if (param.getExpression() instanceof Variable) { - Variable var = (Variable) param.getExpression(); - getterParams.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (param.getExpression() instanceof Term) { - Term var = (Term) param.getExpression(); - getterParams.add(new VariableDeclaration(var.getType(), "v" + v)); + // Declare the getter method to obtain the resource state in the parent component. + if (component == null) { + // No component is created for this resource. + String getterName = "get" + getComponentName(resourceNode.getResourceHierarchy()); + boolean bExists = false; + for (Map.Entry entry: getters) { + if (entry.getKey() == resourceNode.getParent().getResourceHierarchy() && entry.getValue().getName().equals(getterName)) { + bExists = true; + break; } - v++; } - String resCompName = getComponentName(resourceNode.getResourceHierarchy()); - Type resType = getImplStateType(resourceNode.getResourceHierarchy()); - MethodDeclaration stateGetter = null; - if (getterParams.size() == 0) { - stateGetter = new MethodDeclaration("get" + resCompName, resType); - } else { - stateGetter = new MethodDeclaration("get" + resCompName, false, resType, getterParams); + if (!bExists) { + List getterParams = new ArrayList<>(); + int v = 1; + for (Selector param: resourceNode.getSelectors()) { + if (param.getExpression() instanceof Variable) { + Variable var = (Variable) param.getExpression(); + getterParams.add(new VariableDeclaration(var.getType(), var.getName())); + } else if (param.getExpression() instanceof Term) { + Term var = (Term) param.getExpression(); + getterParams.add(new VariableDeclaration(var.getType(), "v" + v)); + } + v++; + } + Type resType = getImplStateType(resourceNode.getResourceHierarchy()); + MethodDeclaration stateGetter = null; + if (getterParams.size() == 0) { + stateGetter = new MethodDeclaration(getterName, resType); + } else { + stateGetter = new MethodDeclaration(getterName, false, resType, getterParams); + } + getters.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), stateGetter)); + + // Declare the accessor method in the main type to call the getter method. + declareAccessorMethodInMainComponent(resourceNode, mainComponent); } - getters.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), stateGetter)); } - // Declare the accessor method in the main type to call the getter method. - MethodDeclaration getterAccessor = null; - List mainGetterParams = new ArrayList<>(); - int v = 1; - for (Selector param: resourceNode.getAllSelectors()) { - if (param.getExpression() instanceof Variable) { - Variable var = (Variable) param.getExpression(); - mainGetterParams.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (param.getExpression() instanceof Term) { - Term var = (Term) param.getExpression(); - mainGetterParams.add(new VariableDeclaration(var.getType(), "v" + v)); - } - v++; - } - if (mainGetterParams.size() > 0) { - getterAccessor = new MethodDeclaration("get" + getComponentName(resourceNode.getResourceHierarchy()), - false, - getImplStateType(resourceNode.getResourceHierarchy()), - mainGetterParams); - } else { - getterAccessor = new MethodDeclaration("get" + getComponentName(resourceNode.getResourceHierarchy()), - getImplStateType(resourceNode.getResourceHierarchy())); - } - getterAccessor.setBody(new Block()); - Expression getState = JavaCodeGenerator.pullAccessor.getDirectStateAccessorFor(resourceNode.getOutSideResource(), null); - getterAccessor.getBody().addStatement("return " + getState.toImplementation(new String[] {null}) + ";"); - mainComponent.addMethod(getterAccessor); - // Declare fields and update methods in the type of each resource. for (Edge resToCh : resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; @@ -629,7 +622,7 @@ // In each resource. ArrayList resInputParams = new ArrayList<>(); ArrayList mainInputParams = new ArrayList<>(); - v = 1; + int v = 1; if (cm.getResource().getLastParam() != null) { Expression param = cm.getResource().getLastParam(); if (param instanceof Variable) { @@ -720,7 +713,7 @@ // In each resource. ArrayList resInputParams = new ArrayList<>(); ArrayList mainInputParams = new ArrayList<>(); - v = 1; + int v = 1; if (cm.getResource().getLastParam() != null) { Expression param = cm.getResource().getLastParam(); if (param instanceof Variable) { @@ -952,6 +945,35 @@ orderedList.add(0, curResNode); } + private static void declareAccessorMethodInMainComponent(ResourceNode resourceNode, TypeDeclaration mainComponent) { + MethodDeclaration getterAccessor = null; + List mainGetterParams = new ArrayList<>(); + int v = 1; + for (Selector param: resourceNode.getAllSelectors()) { + if (param.getExpression() instanceof Variable) { + Variable var = (Variable) param.getExpression(); + mainGetterParams.add(new VariableDeclaration(var.getType(), var.getName())); + } else if (param.getExpression() instanceof Term) { + Term var = (Term) param.getExpression(); + mainGetterParams.add(new VariableDeclaration(var.getType(), "v" + v)); + } + v++; + } + if (mainGetterParams.size() > 0) { + getterAccessor = new MethodDeclaration("get" + getComponentName(resourceNode.getResourceHierarchy()), + false, + getImplStateType(resourceNode.getResourceHierarchy()), + mainGetterParams); + } else { + getterAccessor = new MethodDeclaration("get" + getComponentName(resourceNode.getResourceHierarchy()), + getImplStateType(resourceNode.getResourceHierarchy())); + } + getterAccessor.setBody(new Block()); + Expression getState = JavaCodeGenerator.pullAccessor.getDirectStateAccessorFor(resourceNode.getOutSideResource(), null); + getterAccessor.getBody().addStatement("return " + getState.toImplementation(new String[] {null}) + ";"); + mainComponent.addMethod(getterAccessor); + } + private static List addConstructorParameters(ResourceHierarchy resource, Map resourceComponents, Map resourceConstructors, diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java index f78b8f7..ca7b332 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java @@ -171,6 +171,77 @@ cu.addImport(new ImportDeclaration("com.fasterxml.jackson.core.JsonProcessingException")); } codes.add(cu); + + // Declare the field to store the state in the type of each resource. + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + ResourcePath res = resourceNode.getOutSideResource(); + Set children = resourceNode.getResourceHierarchy().getChildren(); + if (children == null || children.size() == 0) { + // leaf resource. + Type fieldType = getImplStateType(res.getResourceHierarchy()); + component.addField(new FieldDeclaration(fieldType, "value", getInitializer(res))); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), new VariableDeclaration(fieldType, toVariableName(resourceName)))); + } else { + ResourceHierarchy child = children.iterator().next(); + if (children.size() == 1 && child.getNumParameters() > 0) { + // map or list. + component.addField(new FieldDeclaration(getImplStateType(res.getResourceHierarchy()), "value", getInitializer(res))); + } else { + // class + for (ResourceHierarchy c: children) { + String childTypeName = getComponentName(c); + Type childType = null; + if (generatesComponent(c)) { + // The child has a component. + childType = new Type(childTypeName, childTypeName); + String fieldName = toVariableName(childTypeName); + component.addField(new FieldDeclaration(childType, fieldName, getInitializer(res))); + } + } + } + } + } + + // Declare the getter method to obtain the resource state in the component of each resource. + MethodDeclaration stateGetter = new MethodDeclaration("getValue", getImplStateType(resourceNode.getResourceHierarchy())); + if (resourceNode.getResourceHierarchy().getParent() == null) { + // Since this getter is also an accessor. + stateGetter.addAnnotation(new Annotation("Produces", "MediaType.APPLICATION_JSON")); + stateGetter.addAnnotation(new Annotation("GET")); + } + component.addMethod(stateGetter); + + // Declare the getter methods to obtain the children resources. + Set children = new HashSet<>(); + for (ResourceNode child: resourceNode.getChildren()) { + if (generatesComponent(child.getResourceHierarchy())) { + // The child generates a component. + if (!children.contains(child.getResourceHierarchy())) { + children.add(child.getResourceHierarchy()); + List pathParams = new ArrayList<>(); + int v = 1; + for (Selector pathParam: child.getSelectors()) { + if (pathParam.getExpression() instanceof Variable) { + Variable var = (Variable) pathParam.getExpression(); + pathParams.add(new VariableDeclaration(var.getType(), var.getName())); + } else if (pathParam.getExpression() instanceof Term) { + Term var = (Term) pathParam.getExpression(); + pathParams.add(new VariableDeclaration(var.getType(), "v" + v)); + } + v++; + } + String childCompName = getComponentName(child.getResourceHierarchy()); + Type childType = new Type(childCompName, childCompName); + MethodDeclaration childGetter = null; + if (pathParams.size() == 0) { + childGetter = new MethodDeclaration("get" + childCompName, childType); + } else { + childGetter = new MethodDeclaration("get" + childCompName, false, childType, pathParams); + } + component.addMethod(childGetter); + } + } + } } // // Declare a client field to connect to the source resource of reference transfer. @@ -190,64 +261,6 @@ // if (bDeclareClientField) break; // } // } - - // Declare the field to store the state in the type of each resource. - if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { - ResourcePath res = resourceNode.getOutSideResource(); - Set children = resourceNode.getResourceHierarchy().getChildren(); - if (children == null || children.size() == 0) { - // leaf resource. - Type fieldType = getImplStateType(res.getResourceHierarchy()); - component.addField(new FieldDeclaration(fieldType, "value", getInitializer(res))); - constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getResourceHierarchy(), new VariableDeclaration(fieldType, toVariableName(resourceName)))); - } else { - ResourceHierarchy child = children.iterator().next(); - if (children.size() == 1 && child.getNumParameters() > 0) { - // map or list. - component.addField(new FieldDeclaration(getImplStateType(res.getResourceHierarchy()), "value", getInitializer(res))); - } else { - // class - for (ResourceHierarchy c: children) { - String childTypeName = getComponentName(c); - Type childType = null; - if (generatesComponent(c)) { - // The child has a component. - childType = new Type(childTypeName, childTypeName); - String fieldName = toVariableName(childTypeName); - component.addField(new FieldDeclaration(childType, fieldName, getInitializer(res))); - } - } - } - } - } - - // Declare the getter methods to obtain the children resources. - for (ResourceNode child: resourceNode.getChildren()) { - if (generatesComponent(child.getResourceHierarchy())) { - // The child generates a component. - List pathParams = new ArrayList<>(); - int v = 1; - for (Selector pathParam: child.getSelectors()) { - if (pathParam.getExpression() instanceof Variable) { - Variable var = (Variable) pathParam.getExpression(); - pathParams.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (pathParam.getExpression() instanceof Term) { - Term var = (Term) pathParam.getExpression(); - pathParams.add(new VariableDeclaration(var.getType(), "v" + v)); - } - v++; - } - String childCompName = getComponentName(child.getResourceHierarchy()); - Type childType = new Type(childCompName, childCompName); - MethodDeclaration childGetter = null; - if (pathParams.size() == 0) { - childGetter = new MethodDeclaration("get" + childCompName, childType); - } else { - childGetter = new MethodDeclaration("get" + childCompName, false, childType, pathParams); - } - component.addMethod(childGetter); - } - } } // Declare the state field and reference fields in the parent component. @@ -340,39 +353,39 @@ } } - // Declare the getter method to obtain the resource state in the component of each resource. - if (component != null) { - // A component is created for this resource. - MethodDeclaration stateGetter = new MethodDeclaration("getValue", getImplStateType(resourceNode.getResourceHierarchy())); - if (resourceNode.getResourceHierarchy().getParent() == null) { - // Since this getter is also an accessor. - stateGetter.addAnnotation(new Annotation("Produces", "MediaType.APPLICATION_JSON")); - stateGetter.addAnnotation(new Annotation("GET")); - } - component.addMethod(stateGetter); - } else { + // Declare the getter method to obtain the resource state in the parent component. + if (component == null) { // No component is created for this resource. - List pathParams = new ArrayList<>(); - int v = 1; - for (Selector pathParam: resourceNode.getSelectors()) { - if (pathParam.getExpression() instanceof Variable) { - Variable var = (Variable) pathParam.getExpression(); - pathParams.add(new VariableDeclaration(var.getType(), var.getName())); - } else if (pathParam.getExpression() instanceof Term) { - Term var = (Term) pathParam.getExpression(); - pathParams.add(new VariableDeclaration(var.getType(), "v" + v)); + String getterName = "get" + getComponentName(resourceNode.getResourceHierarchy()); + boolean bExists = false; + for (Map.Entry entry: getters) { + if (entry.getKey() == resourceNode.getParent().getResourceHierarchy() && entry.getValue().getName().equals(getterName)) { + bExists = true; + break; } - v++; } - String resCompName = getComponentName(resourceNode.getResourceHierarchy()); - Type resType = getImplStateType(resourceNode.getResourceHierarchy()); - MethodDeclaration stateGetter = null; - if (pathParams.size() == 0) { - stateGetter = new MethodDeclaration("get" + resCompName, resType); - } else { - stateGetter = new MethodDeclaration("get" + resCompName, false, resType, pathParams); + if (!bExists) { + List pathParams = new ArrayList<>(); + int v = 1; + for (Selector pathParam: resourceNode.getSelectors()) { + if (pathParam.getExpression() instanceof Variable) { + Variable var = (Variable) pathParam.getExpression(); + pathParams.add(new VariableDeclaration(var.getType(), var.getName())); + } else if (pathParam.getExpression() instanceof Term) { + Term var = (Term) pathParam.getExpression(); + pathParams.add(new VariableDeclaration(var.getType(), "v" + v)); + } + v++; + } + Type resType = getImplStateType(resourceNode.getResourceHierarchy()); + MethodDeclaration stateGetter = null; + if (pathParams.size() == 0) { + stateGetter = new MethodDeclaration(getterName, resType); + } else { + stateGetter = new MethodDeclaration(getterName, false, resType, pathParams); + } + getters.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), stateGetter)); } - getters.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), stateGetter)); } // Declare the getter accessor in the root resource.