diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index ea45a55..e1bf0ae 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -675,18 +675,51 @@ break; } } - // Add statements to the input method. + // Add statements to the update method. String[] sideEffects = new String[] {""}; - String curState = updateExp.toImplementation(sideEffects); - String updateStatement; - if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; + String newState = updateExp.toImplementation(sideEffects); + if (generatesComponent(outRes)) { + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + } else { + updateStatement = sideEffects[0] + langSpec.getFieldAccessor(fieldOfResourceState) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); // this.value = ... + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + update.addFirstStatement(updateStatement); + } } else { - updateStatement = sideEffects[0] + langSpec.getFieldAccessor(fieldOfResourceState) + langSpec.getAssignment() + curState + langSpec.getStatementDelimiter(); // this.value = ... + String updateStatement = null; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + String resourceName = langSpec.toVariableName(getComponentName(outRes, langSpec)); + updateStatement = updateStatement.replace(langSpec.getFieldAccessor(fieldOfResourceState), langSpec.getFieldAccessor(resourceName)); + } else { + if (DataConstraintModel.typeList.isAncestorOf(resourceNode.getParent().getResourceStateType())) { + Term selector = new Term(DataConstraintModel.set); + selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); + selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); + selector.addChild(new Constant(newState)); + String[] sideEffects2 = new String[] {""}; + String newList = selector.toImplementation(sideEffects2); + updateStatement = sideEffects[0] + sideEffects2[0]; + } else if (DataConstraintModel.typeMap.isAncestorOf(resourceNode.getParent().getResourceStateType())) { + Term selector = new Term(DataConstraintModel.insert); + selector.addChild(new Constant(langSpec.getFieldAccessor(fieldOfResourceState))); + selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); + selector.addChild(new Constant(newState)); + String[] sideEffects2 = new String[] {""}; + String newMap = selector.toImplementation(sideEffects2); + updateStatement = sideEffects[0] + sideEffects2[0]; + } else { + String resourceName = langSpec.toVariableName(getComponentName(outRes, langSpec)); + updateStatement = sideEffects[0] + langSpec.getFieldAccessor(resourceName) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); + } + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + update.addFirstStatement(updateStatement); + } } - if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { - update.addFirstStatement(updateStatement); - } break; } } @@ -955,10 +988,23 @@ } else { // var has not come from a reference resource. resInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); - mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + boolean bExists = false; + for (VariableDeclaration mainParam: mainInputParams) { + if (mainParam.getName().equals(var.getName()) ) { + bExists = true; + break; + } + } + if (!bExists) { + mainInputParams.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + } } } - input = langSpec.newMethodDeclaration(((Term) message).getSymbol().getImplName(), false, null, resInputParams); + String inputMethodName = ((Term) message).getSymbol().getImplName(); + if (((DataTransferChannel) ch).getOutputChannelMembers().size() > 1) { + inputMethodName += getComponentName(out.getResource().getResourceHierarchy(), langSpec); + } + input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); if (component != null) { // A component is created for this resource. component.addMethod(input); @@ -968,10 +1014,10 @@ } // Declare the accessor in the main component to call the input method. - String str = ((Term) message).getSymbol().getImplName(); - inputAccessor = getMethod(mainComponent, str); + String messageSymbol = ((Term) message).getSymbol().getImplName(); + inputAccessor = getMethod(mainComponent, messageSymbol); if (inputAccessor == null) { - inputAccessor = langSpec.newMethodDeclaration(str, false, null, mainInputParams); + inputAccessor = langSpec.newMethodDeclaration(messageSymbol, false, null, mainInputParams); mainComponent.addMethod(inputAccessor); } else { // Add type to a parameter without type. @@ -1017,10 +1063,14 @@ v++; } } + String inputMethodName = ((Variable) message).getName(); + if (((DataTransferChannel) ch).getOutputChannelMembers().size() > 1) { + inputMethodName += getComponentName(out.getResource().getResourceHierarchy(), langSpec); + } if (resInputParams.size() == 0) { - input = langSpec.newMethodDeclaration(((Variable) message).getName(), null); + input = langSpec.newMethodDeclaration(inputMethodName, null); } else { - input = langSpec.newMethodDeclaration(((Variable) message).getName(), false, null, resInputParams); + input = langSpec.newMethodDeclaration(inputMethodName, false, null, resInputParams); } if (component != null) { // A component is created for this resource. @@ -1031,13 +1081,13 @@ } // Declare the accessor in the main component to call the input method. - String str = ((Variable) message).getName(); - inputAccessor = getMethod(mainComponent, str); + String messageSymbol = ((Variable) message).getName(); + inputAccessor = getMethod(mainComponent, messageSymbol); if (inputAccessor == null) { if (mainInputParams.size() == 0) { - inputAccessor = langSpec.newMethodDeclaration(str, null); + inputAccessor = langSpec.newMethodDeclaration(messageSymbol, null); } else { - inputAccessor = langSpec.newMethodDeclaration(str, false, null, mainInputParams); + inputAccessor = langSpec.newMethodDeclaration(messageSymbol, false, null, mainInputParams); } mainComponent.addMethod(inputAccessor); } @@ -1117,8 +1167,9 @@ } else { String updateStatement = null; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - // ToDo. updateStatement = sideEffects[0]; + String resourceName = langSpec.toVariableName(getComponentName(resource, langSpec)); + updateStatement = updateStatement.replace(langSpec.getFieldAccessor(fieldOfResourceState), langSpec.getFieldAccessor(resourceName)); } else { if (DataConstraintModel.typeList.isAncestorOf(resourceNode.getParent().getResourceStateType())) { Term selector = new Term(DataConstraintModel.set); @@ -1140,9 +1191,9 @@ String resourceName = langSpec.toVariableName(getComponentName(resource, langSpec)); updateStatement = sideEffects[0] + langSpec.getFieldAccessor(resourceName) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); } - if (updateStatement != null) { - input.addFirstStatement(updateStatement); - } + } + if (updateStatement != null) { + input.addFirstStatement(updateStatement); } } } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java index 76971ed..90e8e70 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java @@ -145,17 +145,17 @@ mainComponent.addMethod(mainConstructor); // For each resource node. - for (ResourceNode rn: resources) { + for (ResourceNode resourceNode: resources) { TypeDeclaration component = null; - if (generatesComponent(rn.getResourceHierarchy())) { + if (generatesComponent(resourceNode.getResourceHierarchy())) { boolean f = false; - String resourceName = getComponentName(rn.getResourceHierarchy()); + String resourceName = getComponentName(resourceNode.getResourceHierarchy()); - component = resourceComponents.get(rn.getResourceHierarchy()); + component = resourceComponents.get(resourceNode.getResourceHierarchy()); if (component == null) { // Add compilation unit for each resource. component = new TypeDeclaration(resourceName); - resourceComponents.put(rn.getResourceHierarchy(), component); + resourceComponents.put(resourceNode.getResourceHierarchy(), component); CompilationUnit cu = new CompilationUnit(component); cu.addImport(new ImportDeclaration("java.util.*")); codes.add(cu); @@ -163,10 +163,10 @@ // Declare the field to refer to each resource in the main type. Set depends = new HashSet<>(); Set refs = new HashSet<>(); - if (rn.getResourceHierarchy().getParent() == null) { + if (resourceNode.getResourceHierarchy().getParent() == null) { // For a root resource String fieldInitializer = "new " + resourceName + "("; - for (Edge resToCh: rn.getOutEdges()) { + for (Edge resToCh: resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { for (Edge chToRes: re.getDestination().getOutEdges()) { @@ -178,7 +178,7 @@ } } } - for (Edge chToRes : rn.getInEdges()) { + for (Edge chToRes : resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(); @@ -201,7 +201,7 @@ } for (ResourceHierarchy dependedRes: dependedRootComponentGraph.keySet()) { for (ResourceHierarchy dependingRes: dependedRootComponentGraph.get(dependedRes)) { - if (rn.getResourceHierarchy().equals(dependingRes)) { + if (resourceNode.getResourceHierarchy().equals(dependingRes)) { // Declare a field to refer to outside resources. depends.add(dependedRes); String resName = getComponentName(dependedRes); @@ -212,7 +212,7 @@ } for (Channel ch : model.getChannels()) { DataTransferChannel c = (DataTransferChannel) ch; - if (c.getInputResources().contains(rn.getOutSideResource())) { + if (c.getInputResources().contains(resourceNode.getOutSideResource())) { for (ResourcePath res: c.getReferenceResources()) { if (!refs.contains(res) && !depends.contains(res.getResourceHierarchy())) { refs.add(res); @@ -225,27 +225,27 @@ } if (f) fieldInitializer = fieldInitializer.substring(0, fieldInitializer.length() - 1); fieldInitializer += ")"; - FieldDeclaration field = new FieldDeclaration(new Type(resourceName, resourceName), rn.getResourceName()); + FieldDeclaration field = new FieldDeclaration(new Type(resourceName, resourceName), resourceNode.getResourceName()); mainComponent.addField(field); Block mainConstructorBody = mainConstructor.getBody(); if (mainConstructorBody == null) { mainConstructorBody = new Block(); mainConstructor.setBody(mainConstructorBody); } - mainConstructorBody.addStatement(rn.getResourceName() + " = " + fieldInitializer + ";"); + mainConstructorBody.addStatement(resourceNode.getResourceName() + " = " + fieldInitializer + ";"); } // Declare a constructor, fields and update methods in the type of each resource. MethodDeclaration constructor = new MethodDeclaration(resourceName, true); Block block = new Block(); depends = new HashSet<>(); - for (Edge resToCh : rn.getOutEdges()) { + for (Edge resToCh : resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); // Check if the input resource is outside of the channel scope. boolean outsideInputResource = false; for (ChannelMember cm: ch.getInputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(rn.getResourceHierarchy()) && cm.isOutside()) { + if (cm.getResource().getResourceHierarchy().equals(resourceNode.getResourceHierarchy()) && cm.isOutside()) { outsideInputResource = true; // Regarded as pull transfer. break; } @@ -253,7 +253,7 @@ // Check if the output resource is outside of the channel scope. boolean outsideOutputResource = false; for (ChannelMember cm: ch.getOutputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(rn.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { + if (cm.getResource().getResourceHierarchy().equals(resourceNode.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { outsideOutputResource = true; // Regarded as push transfer. break; } @@ -283,7 +283,7 @@ } } } - for (Edge chToRes : rn.getInEdges()) { + for (Edge chToRes : resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(); @@ -299,7 +299,7 @@ // Check if the output resource is outside of the channel scope. boolean outsideOutputResource = false; for (ChannelMember cm: ch.getOutputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(rn.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { + if (cm.getResource().getResourceHierarchy().equals(resourceNode.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { outsideOutputResource = true; // Regarded as push transfer. break; } @@ -334,7 +334,7 @@ vars.add(new VariableDeclaration(srcRes.getResourceStateType(), srcRes.getResourceName())); DataTransferChannel c = ((ChannelNode) resToCh.getDestination()).getChannel(); for (ResourcePath ref: c.getReferenceResources()) { - if (!ref.equals(rn.getOutSideResource())) { + if (!ref.equals(resourceNode.getOutSideResource())) { vars.add(new VariableDeclaration(ref.getResourceStateType(), ref.getResourceName())); } } @@ -343,10 +343,10 @@ } } // Declare a field to refer to outside resources. - if (rn.getParent() == null) { + if (resourceNode.getParent() == null) { for (ResourceHierarchy dependedRes: dependedRootComponentGraph.keySet()) { for (ResourceHierarchy dependingRes: dependedRootComponentGraph.get(dependedRes)) { - if (rn.getResourceHierarchy().equals(dependingRes)) { + if (resourceNode.getResourceHierarchy().equals(dependingRes)) { // Declare a field to refer to outside resources. depends.add(dependedRes); String resName = getComponentName(dependedRes); @@ -361,7 +361,7 @@ refs = new HashSet<>(); for (Channel ch : model.getChannels()) { DataTransferChannel c = (DataTransferChannel) ch; - if (c.getInputResources().contains(rn.getOutSideResource())) { + if (c.getInputResources().contains(resourceNode.getOutSideResource())) { for (ResourcePath res: c.getReferenceResources()) { if (!refs.contains(res) && !depends.contains(res.getResourceHierarchy())) { refs.add(res); @@ -376,19 +376,19 @@ constructor.setBody(block); if (constructor.getParameters() != null) { component.addMethod(constructor); - resourceConstructors.put(rn.getResourceHierarchy(), constructor); + resourceConstructors.put(resourceNode.getResourceHierarchy(), constructor); } } // Declare the field to store the state in the type of each resource. - if (((StoreAttribute) rn.getAttribute()).isStored()) { - ResourcePath res = rn.getOutSideResource(); - Set children = rn.getResourceHierarchy().getChildren(); + 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<>(rn.getResourceHierarchy(), new VariableDeclaration(fieldType, toVariableName(resourceName)))); + 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) { @@ -411,7 +411,7 @@ } // Declare the getter methods to obtain the children resources. - for (ResourceNode child: rn.getChildren()) { + for (ResourceNode child: resourceNode.getChildren()) { if (generatesComponent(child.getResourceHierarchy())) { // A component for the child is generated. List params = new ArrayList<>(); @@ -443,7 +443,7 @@ if (component == null) { // Declare reference fields for push/pull data transfer. boolean noPullTransfer = true; - for (Edge resToCh : rn.getOutEdges()) { + for (Edge resToCh : resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); for (Edge chToRes: re.getDestination().getOutEdges()) { @@ -462,20 +462,20 @@ } String dstResName = getComponentName(dstRes.getResourceHierarchy()); FieldDeclaration refFieldForPush = new FieldDeclaration(new Type(dstResName, dstResName), toVariableName(dstResName)); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), refFieldForPush)); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refFieldForPush)); if (dstRes.getParent() != null) { // Reference to root resource. ResourcePath dstRootRes = dstRes.getRoot(); String dstRootResName = getComponentName(dstRootRes.getResourceHierarchy()); Type dstRootResType = new Type(dstRootResName, dstRootResName); FieldDeclaration refRootFieldForPush = new FieldDeclaration(dstRootResType, toVariableName(dstRootResName)); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), refRootFieldForPush)); - constructorParams.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), new VariableDeclaration(dstRootResType, toVariableName(dstRootResName)))); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refRootFieldForPush)); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), new VariableDeclaration(dstRootResType, toVariableName(dstRootResName)))); } } } } - for (Edge chToRes : rn.getInEdges()) { + for (Edge chToRes : resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(); @@ -494,40 +494,40 @@ } String srcResName = getComponentName(srcRes.getResourceHierarchy()); FieldDeclaration refFieldForPull = new FieldDeclaration(new Type(srcResName, srcResName), toVariableName(srcResName)); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), refFieldForPull)); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refFieldForPull)); if (srcRes.getParent() != null) { // Reference to root resource. ResourcePath srcRootRes = srcRes.getRoot(); String srcRootResName = getComponentName(srcRootRes.getResourceHierarchy()); Type srcRootResType = new Type(srcRootResName, srcRootResName); FieldDeclaration refRootFieldForPull = new FieldDeclaration(srcRootResType, toVariableName(srcRootResName)); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), refRootFieldForPull)); - constructorParams.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), new VariableDeclaration(srcRootResType, toVariableName(srcRootResName)))); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refRootFieldForPull)); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), new VariableDeclaration(srcRootResType, toVariableName(srcRootResName)))); } noPullTransfer = false; } } } // Declare the state field in the parent component. - ResourceHierarchy res = rn.getOutSideResource().getResourceHierarchy(); - if (((StoreAttribute) rn.getAttribute()).isStored() && noPullTransfer && res.getNumParameters() == 0) { + ResourceHierarchy res = resourceNode.getOutSideResource().getResourceHierarchy(); + if (((StoreAttribute) resourceNode.getAttribute()).isStored() && noPullTransfer && res.getNumParameters() == 0) { String resName = getComponentName(res); FieldDeclaration stateField = new FieldDeclaration(res.getResourceStateType(), toVariableName(resName)); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), stateField)); - constructorParams.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), new VariableDeclaration(res.getResourceStateType(), toVariableName(resName)))); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), stateField)); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), new VariableDeclaration(res.getResourceStateType(), toVariableName(resName)))); } } // 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(rn.getResourceHierarchy())); + 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: rn.getSelectors()) { + for (Selector param: resourceNode.getSelectors()) { if (param.getExpression() instanceof Variable) { Variable var = (Variable) param.getExpression(); getterParams.add(new VariableDeclaration(var.getType(), var.getName())); @@ -537,22 +537,22 @@ } v++; } - String resCompName = getComponentName(rn.getResourceHierarchy()); - Type resType = getImplStateType(rn.getResourceHierarchy()); + 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); } - getters.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), stateGetter)); + getters.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), stateGetter)); } // Declare the accessor method in the main type to call the getter method. MethodDeclaration accessor = null; List mainGetterParams = new ArrayList<>(); int v = 1; - for (Selector param: rn.getAllSelectors()) { + for (Selector param: resourceNode.getAllSelectors()) { if (param.getExpression() instanceof Variable) { Variable var = (Variable) param.getExpression(); mainGetterParams.add(new VariableDeclaration(var.getType(), var.getName())); @@ -563,23 +563,23 @@ v++; } if (mainGetterParams.size() > 0) { - accessor = new MethodDeclaration("get" + getComponentName(rn.getResourceHierarchy()), + accessor = new MethodDeclaration("get" + getComponentName(resourceNode.getResourceHierarchy()), false, - getImplStateType(rn.getResourceHierarchy()), + getImplStateType(resourceNode.getResourceHierarchy()), mainGetterParams); } else { - accessor = new MethodDeclaration("get" + getComponentName(rn.getResourceHierarchy()), - getImplStateType(rn.getResourceHierarchy())); + accessor = new MethodDeclaration("get" + getComponentName(resourceNode.getResourceHierarchy()), + getImplStateType(resourceNode.getResourceHierarchy())); } accessor.setBody(new Block()); - Expression getState = JavaCodeGenerator.pullAccessor.getDirectStateAccessorFor(rn.getOutSideResource(), null); + Expression getState = JavaCodeGenerator.pullAccessor.getDirectStateAccessorFor(resourceNode.getOutSideResource(), null); accessor.getBody().addStatement("return " + getState.toImplementation(new String[] {null}) + ";"); mainComponent.addMethod(accessor); // Declare the input method in this component and the main component. for (Channel ch : model.getIOChannels()) { for (ChannelMember cm : ((DataTransferChannel) ch).getOutputChannelMembers()) { - if (rn.getInSideResources().contains(cm.getResource())) { + if (resourceNode.getInSideResources().contains(cm.getResource())) { Expression message = cm.getStateTransition().getMessageExpression(); if (message instanceof Term) { // In each resource. @@ -629,25 +629,36 @@ } else { // var has not come from a reference resource. resInputParams.add(new VariableDeclaration(var.getType(), var.getName())); - mainInputParams.add(new VariableDeclaration(var.getType(), var.getName())); + boolean bExists = false; + for (VariableDeclaration mainParam: mainInputParams) { + if (mainParam.getName().equals(var.getName()) ) { + bExists = true; + break; + } + } + if (!bExists) { + mainInputParams.add(new VariableDeclaration(var.getType(), var.getName())); + } } } - MethodDeclaration input = new MethodDeclaration( - ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(), - false, typeVoid, resInputParams); + String inputMethodName = ((Term) message).getSymbol().getImplName(); + if (((DataTransferChannel) ch).getOutputChannelMembers().size() > 1) { + inputMethodName += getComponentName(cm.getResource().getResourceHierarchy()); + } + MethodDeclaration input = new MethodDeclaration(inputMethodName, false, typeVoid, resInputParams); if (component != null) { // A component is created for this resource. component.addMethod(input); } else { // No component is created for this resource. - inputs.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), input)); + inputs.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), input)); } // In the main type. - String str = ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(); - input = getMethod(mainComponent, str, mainInputParams); + String messageSymbol = ((Term) message).getSymbol().getImplName(); + input = getMethod(mainComponent, messageSymbol, mainInputParams); if (input == null) { - input = new MethodDeclaration(str, false, typeVoid, mainInputParams); + input = new MethodDeclaration(messageSymbol, false, typeVoid, mainInputParams); mainComponent.addMethod(input); } else { // Add type to a parameter without type. @@ -691,32 +702,32 @@ v++; } } + String inputMethodName = ((Variable) message).getName(); + if (((DataTransferChannel) ch).getOutputChannelMembers().size() > 1) { + inputMethodName += getComponentName(cm.getResource().getResourceHierarchy()); + } MethodDeclaration input = null; if (resInputParams.size() > 0) { - input = new MethodDeclaration( - ((Variable) cm.getStateTransition().getMessageExpression()).getName(), - false, typeVoid, resInputParams); + input = new MethodDeclaration(inputMethodName, false, typeVoid, resInputParams); } else { - input = new MethodDeclaration( - ((Variable) cm.getStateTransition().getMessageExpression()).getName(), - false, typeVoid, null); + input = new MethodDeclaration(inputMethodName, false, typeVoid, null); } if (component != null) { // A component is created for this resource. component.addMethod(input); } else { // No component is created for this resource. - inputs.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), input)); + inputs.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), input)); } // In the main type. - String str = ((Variable) cm.getStateTransition().getMessageExpression()).getName(); - input = getMethod(mainComponent, str, mainInputParams); + String messageSymbol = ((Variable) message).getName(); + input = getMethod(mainComponent, messageSymbol, mainInputParams); if (input == null) { if (mainInputParams.size() > 0) { - input = new MethodDeclaration(str, false, typeVoid, mainInputParams); + input = new MethodDeclaration(messageSymbol, false, typeVoid, mainInputParams); } else { - input = new MethodDeclaration(str, false, typeVoid, null); + input = new MethodDeclaration(messageSymbol, false, typeVoid, null); } mainComponent.addMethod(input); } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java index 443d7bf..a089a26 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java @@ -129,15 +129,46 @@ } // Add statements to the update method. String[] sideEffects = new String[] {""}; - String curState = updateExp.toImplementation(sideEffects); - String updateStatement; - if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; + String newState = updateExp.toImplementation(sideEffects); + if (JavaCodeGenerator.generatesComponent(outRes)) { + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + } else { + updateStatement = sideEffects[0] + "this.value = " + newState + ";"; + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + update.addFirstStatement(updateStatement); + } } else { - updateStatement = sideEffects[0] + "this.value = " + curState + ";"; - } - if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { - update.addFirstStatement(updateStatement); + String updateStatement = null; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + updateStatement = updateStatement.replace(".value", "." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(outRes))); + } else { + if (DataConstraintModel.typeList.isAncestorOf(outRes.getParent().getResourceStateType())) { + Term selector = new Term(DataConstraintModel.set); + selector.addChild(new Field("value")); + selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); + selector.addChild(new Constant(newState)); + String[] sideEffects2 = new String[] {""}; + String newList = selector.toImplementation(sideEffects2); + updateStatement = sideEffects[0] + sideEffects2[0]; + } else if (DataConstraintModel.typeMap.isAncestorOf(outRes.getParent().getResourceStateType())) { + Term selector = new Term(DataConstraintModel.insert); + selector.addChild(new Field("value")); + selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); + selector.addChild(new Constant(newState)); + String[] sideEffects2 = new String[] {""}; + String newMap = selector.toImplementation(sideEffects2); + updateStatement = sideEffects[0] + sideEffects2[0]; + } else { + updateStatement = sideEffects[0] + "this." + JavaCodeGenerator.toVariableName(JavaCodeGenerator.getComponentName(outRes)) + " = " + newState + ";"; + } + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + update.addFirstStatement(updateStatement); + } } } if (resToCh.getDestination().getIndegree() > 1 @@ -341,7 +372,8 @@ DataTransferChannel ch2 = ((ChannelNode) chToRes2.getSource()).getChannel(); if (ch2.getInputChannelMembers().size() == 0) { // In an input method of the parent component. - MethodDeclaration input = getInputMethod(dependingComponent, ch2.getOutputChannelMembers().iterator().next()); + Set outs = ch2.getOutputChannelMembers(); + MethodDeclaration input = getInputMethod(dependingComponent, outs.iterator().next(), outs.size()); String[] sideEffects = new String[] {""}; String outsideAccessor = outsideExp.toImplementation(sideEffects); input.addStatement("this." + outsideResName + " = " + outsideAccessor + ";"); // change the reference field. @@ -498,13 +530,13 @@ MethodDeclaration input = null; if (JavaCodeGenerator.generatesComponent(resource)) { // A component is generated for this resource. - input = getInputMethod(component, out); + input = getInputMethod(component, out, entry.getKey().getOutputChannelMembers().size()); } else { // No component is generated for this resource. ResourceHierarchy parent = resource.getParent(); if (parent != null) { TypeDeclaration parentType = componentMap.get(JavaCodeGenerator.getComponentName(parent)); - input = getInputMethod(parentType, out); + input = getInputMethod(parentType, out, entry.getKey().getOutputChannelMembers().size()); } } if (input != null) { @@ -537,8 +569,8 @@ } else { String updateStatement = null; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - // ToDo. updateStatement = sideEffects[0]; + updateStatement = updateStatement.replace(".value", "." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(resource))); } else { if (DataConstraintModel.typeList.isAncestorOf(resource.getParent().getResourceStateType())) { Term selector = new Term(DataConstraintModel.set); @@ -559,15 +591,22 @@ } else { updateStatement = sideEffects[0] + "this." + JavaCodeGenerator.toVariableName(JavaCodeGenerator.getComponentName(resource)) + " = " + newState + ";"; } - if (updateStatement != null && (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement))) { - input.addFirstStatement(updateStatement); - } + } + if (updateStatement != null && (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement))) { + input.addFirstStatement(updateStatement); } } // In the main type if (mainComponent != null) { - MethodDeclaration inputAccessor = getMethod(mainComponent, input.getName()); + Expression message = out.getStateTransition().getMessageExpression(); + String inputAccessorName = input.getName(); + if (message instanceof Term) { + inputAccessorName = ((Term) message).getSymbol().getImplName(); + } else if (message instanceof Variable) { + inputAccessorName = ((Variable) message).getName(); + } + MethodDeclaration inputAccessor = getMethod(mainComponent, inputAccessorName); if (inputAccessor != null) { Set referredSet = referredResources.get(input); for (ChannelMember rc: entry.getKey().getReferenceChannelMembers()) { @@ -601,8 +640,7 @@ resExp = ((Term) resExp).getChild(0); } String resourceAccess = resExp.toImplementation(new String[] {null}); - if (out.getStateTransition().getMessageExpression() instanceof Term) { - Term message = (Term) out.getStateTransition().getMessageExpression(); + if (message instanceof Term) { for (Map.Entry varEnt: message.getVariables().entrySet()) { String refVarName = null; for (ChannelMember rc: entry.getKey().getReferenceChannelMembers()) { @@ -723,7 +761,7 @@ // I/O channel for (ChannelMember out: channel.getOutputChannelMembers()) { if (resource.getInSideResources().contains(out.getResource())) { - MethodDeclaration input = getInputMethod(component, out); + MethodDeclaration input = getInputMethod(component, out, channel.getOutputChannelMembers().size()); inputs.add(input); } } @@ -738,7 +776,7 @@ // I/O channel for (ChannelMember out: channel.getOutputChannelMembers()) { if (resource.equals(out.getResource().getResourceHierarchy())) { - MethodDeclaration input = getInputMethod(component, out); + MethodDeclaration input = getInputMethod(component, out, channel.getOutputChannelMembers().size()); inputs.add(input); } } @@ -746,15 +784,19 @@ return inputs; } - private static MethodDeclaration getInputMethod(TypeDeclaration component, ChannelMember cm) { - MethodDeclaration input = null; + private static MethodDeclaration getInputMethod(TypeDeclaration component, ChannelMember cm, int outNumber) { + String inputMethodName = null; if (cm.getStateTransition().getMessageExpression() instanceof Term) { Term message = (Term) cm.getStateTransition().getMessageExpression(); - input = getMethod(component, message.getSymbol().getImplName()); + inputMethodName =message.getSymbol().getImplName(); } else if (cm.getStateTransition().getMessageExpression() instanceof Variable) { Variable message = (Variable) cm.getStateTransition().getMessageExpression(); - input = getMethod(component, message.getName()); + inputMethodName = message.getName(); } + if (outNumber > 1) { + inputMethodName += JavaCodeGenerator.getComponentName(cm.getResource().getResourceHierarchy()); + } + MethodDeclaration input = getMethod(component, inputMethodName); return input; } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java index b791f97..9a47929 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java @@ -138,28 +138,29 @@ Map getterAccessors = new HashMap<>(); Map inputAccessors = new HashMap<>(); List> constructorParams = new ArrayList<>(); + Map priorMemberForInputChannel = new HashMap<>(); // For each resource node. for (Node n : resources) { - ResourceNode rn = (ResourceNode) n; + ResourceNode resourceNode = (ResourceNode) n; TypeDeclaration component = null; - if (generatesComponent(rn.getResourceHierarchy())) { - String resourceName = getComponentName(rn.getResourceHierarchy()); + if (generatesComponent(resourceNode.getResourceHierarchy())) { + String resourceName = getComponentName(resourceNode.getResourceHierarchy()); - component = resourceComponents.get(rn.getResourceHierarchy()); + component = resourceComponents.get(resourceNode.getResourceHierarchy()); if (component == null) { // Add compilation unit for each resource. component = new TypeDeclaration(resourceName); - if (rn.getResourceHierarchy().getParent() == null) { + if (resourceNode.getResourceHierarchy().getParent() == null) { // For a root node. component.addAnnotation(new Annotation("Component")); - component.addAnnotation(new Annotation("Path", "\"/" + rn.getResourceName() + "\"")); + component.addAnnotation(new Annotation("Path", "\"/" + resourceNode.getResourceName() + "\"")); } - resourceComponents.put(rn.getResourceHierarchy(), component); + resourceComponents.put(resourceNode.getResourceHierarchy(), component); CompilationUnit cu = new CompilationUnit(component); cu.addImport(new ImportDeclaration("java.util.*")); - if (rn.getResourceHierarchy().getParent() == null) { + if (resourceNode.getResourceHierarchy().getParent() == null) { // For a root node. cu.addImport(new ImportDeclaration("javax.ws.rs.*")); cu.addImport(new ImportDeclaration("javax.ws.rs.client.*")); @@ -172,13 +173,13 @@ // Declare a client field and update methods from other resources. boolean bDeclareClientField = false; - for (Edge resToCh: rn.getOutEdges()) { + for (Edge resToCh: resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); // Check if the input resource is outside of the channel scope. boolean outsideInputResource = false; for (ChannelMember cm: ch.getInputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(rn.getResourceHierarchy()) && cm.isOutside()) { + if (cm.getResource().getResourceHierarchy().equals(resourceNode.getResourceHierarchy()) && cm.isOutside()) { outsideInputResource = true; // Regarded as pull transfer. break; } @@ -192,7 +193,7 @@ } else { dstResName = getComponentName(dstRes.getResourceHierarchy().getParent()); } - if (rn.getOutSideResource().getCommonPrefix(dstRes) == null && differentTreesAsDifferentServices) { + if (resourceNode.getOutSideResource().getCommonPrefix(dstRes) == null && differentTreesAsDifferentServices) { // Inter-service if (bDeclareClientField) { // Declare a client field to connect to the destination resource of push transfer. @@ -207,7 +208,7 @@ } } } - for (Edge chToRes : rn.getInEdges()) { + for (Edge chToRes : resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(); @@ -222,7 +223,7 @@ } boolean outsideOutputResource = false; for (ChannelMember cm: ch.getOutputChannelMembers()) { - if (cm.getResource().getResourceHierarchy().equals(rn.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { + if (cm.getResource().getResourceHierarchy().equals(resourceNode.getOutSideResource().getResourceHierarchy()) && cm.isOutside()) { outsideOutputResource = true; // Regarded as push transfer. break; } @@ -234,7 +235,7 @@ srcResName = getComponentName(srcRes.getResourceHierarchy().getParent()); } if ((((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH && !outsideOutputResource) || outsideInputResource) { - if (rn.getOutSideResource().getCommonPrefix(srcRes) == null && differentTreesAsDifferentServices) { + if (resourceNode.getOutSideResource().getCommonPrefix(srcRes) == null && differentTreesAsDifferentServices) { // Inter-service if (!bDeclareClientField) { // Declare a client field to connect to the source resource of pull transfer. @@ -255,7 +256,7 @@ param.addAnnotation(new Annotation("FormParam", "\"" + srcName + "\"")); vars.add(param); for (ResourcePath refRes: ((ChannelNode) re.getDestination()).getChannel().getReferenceResources()) { - if (!refRes.equals(rn.getOutSideResource())) { + if (!refRes.equals(resourceNode.getOutSideResource())) { param = new VariableDeclaration(refRes.getResourceStateType(), refRes.getResourceName()); param.addAnnotation(new Annotation("FormParam", "\"" + refRes.getResourceName() + "\"")); vars.add(param); @@ -263,7 +264,7 @@ } MethodDeclaration update = new MethodDeclaration("update" + srcResName, false, typeVoid, vars); for (ChannelMember cm: ((ChannelNode) re.getDestination()).getChannel().getOutputChannelMembers()) { - if (rn.getInSideResources().contains(cm.getResource())) { + if (resourceNode.getInSideResources().contains(cm.getResource())) { if (cm.getStateTransition().isRightUnary()) { update.addAnnotation(new Annotation("PUT")); } else { @@ -306,14 +307,14 @@ // } // Declare the field to store the state in the type of each resource. - if (((StoreAttribute) rn.getAttribute()).isStored()) { - ResourcePath res = rn.getOutSideResource(); - Set children = rn.getResourceHierarchy().getChildren(); + 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<>(rn.getResourceHierarchy(), new VariableDeclaration(fieldType, toVariableName(resourceName)))); + 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) { @@ -336,7 +337,7 @@ } // Declare the getter methods to obtain the children resources. - for (ResourceNode child: rn.getChildren()) { + for (ResourceNode child: resourceNode.getChildren()) { if (generatesComponent(child.getResourceHierarchy())) { // The child generates a component. List pathParams = new ArrayList<>(); @@ -369,7 +370,7 @@ // Declare reference fields for push/pull data transfer. boolean bDeclareClientField = false; boolean noPullTransfer = true; - for (Edge resToCh : rn.getOutEdges()) { + for (Edge resToCh : resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); for (Edge chToRes: re.getDestination().getOutEdges()) { @@ -389,24 +390,24 @@ } else { dstResName = getComponentName(dstRes.getResourceHierarchy().getParent()); } - if (rn.getOutSideResource().getCommonPrefix(dstRes) == null && differentTreesAsDifferentServices) { + if (resourceNode.getOutSideResource().getCommonPrefix(dstRes) == null && differentTreesAsDifferentServices) { // Inter-service if (!bDeclareClientField) { // Declare a client field to connect to the destination resource of push transfer. FieldDeclaration clientField = new FieldDeclaration(typeClient, "client", "ClientBuilder.newClient()"); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), clientField)); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), clientField)); bDeclareClientField = true; } } else { // Inner-service // Declare a field to directly refer to the destination resource of push transfer. FieldDeclaration refFieldForPush = new FieldDeclaration(new Type(dstResName, dstResName), toVariableName(dstResName)); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), refFieldForPush)); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refFieldForPush)); } } } } - for (Edge chToRes : rn.getInEdges()) { + for (Edge chToRes : resourceNode.getInEdges()) { for (Edge resToCh: chToRes.getSource().getInEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(); @@ -426,39 +427,39 @@ } else { srcResName = getComponentName(srcRes.getResourceHierarchy().getParent()); } - if (rn.getOutSideResource().getCommonPrefix(srcRes) == null && differentTreesAsDifferentServices) { + if (resourceNode.getOutSideResource().getCommonPrefix(srcRes) == null && differentTreesAsDifferentServices) { // Inter-service if (!bDeclareClientField) { // Declare a client field to connect to the source resource of pull transfer. FieldDeclaration clientField = new FieldDeclaration(typeClient, "client", "ClientBuilder.newClient()"); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), clientField)); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), clientField)); bDeclareClientField = true; } } else { // Inner-service // Declare a field to directly refer to the source resource of pull transfer. FieldDeclaration refFieldForPull = new FieldDeclaration(new Type(srcResName, srcResName), toVariableName(srcResName)); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), refFieldForPull)); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), refFieldForPull)); noPullTransfer = false; } } } } // Declare the state field in the parent component. - ResourceHierarchy res = rn.getOutSideResource().getResourceHierarchy(); - if (((StoreAttribute) rn.getAttribute()).isStored() && noPullTransfer && res.getNumParameters() == 0) { + ResourceHierarchy res = resourceNode.getOutSideResource().getResourceHierarchy(); + if (((StoreAttribute) resourceNode.getAttribute()).isStored() && noPullTransfer && res.getNumParameters() == 0) { String resName = getComponentName(res); FieldDeclaration stateField = new FieldDeclaration(res.getResourceStateType(), toVariableName(resName)); - fields.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), stateField)); - constructorParams.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), new VariableDeclaration(res.getResourceStateType(), toVariableName(resName)))); + fields.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), stateField)); + constructorParams.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), new VariableDeclaration(res.getResourceStateType(), toVariableName(resName)))); } } // 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(rn.getResourceHierarchy())); - if (rn.getResourceHierarchy().getParent() == null) { + 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")); @@ -468,7 +469,7 @@ // No component is created for this resource. List pathParams = new ArrayList<>(); int v = 1; - for (Selector pathParam: rn.getSelectors()) { + for (Selector pathParam: resourceNode.getSelectors()) { if (pathParam.getExpression() instanceof Variable) { Variable var = (Variable) pathParam.getExpression(); pathParams.add(new VariableDeclaration(var.getType(), var.getName())); @@ -478,63 +479,66 @@ } v++; } - String resCompName = getComponentName(rn.getResourceHierarchy()); - Type resType = getImplStateType(rn.getResourceHierarchy()); + 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); } - getters.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), stateGetter)); + getters.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), stateGetter)); } // Declare the getter accessor in the root resource. - if (rn.getResourceHierarchy().getParent() != null) { + if (resourceNode.getResourceHierarchy().getParent() != null) { // For a non-root resource MethodDeclaration getterAccessor = null; List mainGetterParams = new ArrayList<>(); - String resourcePath = getGetterResourcePathAndPathParams(rn.getOutSideResource(), mainGetterParams); + String resourcePath = getGetterResourcePathAndPathParams(resourceNode.getOutSideResource(), mainGetterParams); if (resourcePath.indexOf('/') > 0) { - resourcePath = "\"" + resourcePath.substring(resourcePath.indexOf('/')) + "\""; - } else { - resourcePath = "\"" + resourcePath + "\""; + resourcePath = resourcePath.substring(resourcePath.indexOf('/')); } if (mainGetterParams.size() > 0) { - getterAccessor = new MethodDeclaration("get" + getComponentName(rn.getResourceHierarchy()) + "Value", + getterAccessor = new MethodDeclaration("get" + getComponentName(resourceNode.getResourceHierarchy()) + "Value", false, - getImplStateType(rn.getResourceHierarchy()), + getImplStateType(resourceNode.getResourceHierarchy()), mainGetterParams); } else { - getterAccessor = new MethodDeclaration("get" + getComponentName(rn.getResourceHierarchy()) + "Value", - getImplStateType(rn.getResourceHierarchy())); + getterAccessor = new MethodDeclaration("get" + getComponentName(resourceNode.getResourceHierarchy()) + "Value", + getImplStateType(resourceNode.getResourceHierarchy())); } getterAccessor.setBody(new Block()); - Expression getState = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(rn.getOutSideResource(), rn.getOutSideResource().getRoot()); + Expression getState = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(resourceNode.getOutSideResource(), resourceNode.getOutSideResource().getRoot()); getterAccessor.getBody().addStatement("return " + getState.toImplementation(new String[] {null}) + ";"); getterAccessor.addAnnotation(new Annotation("Produces", "MediaType.APPLICATION_JSON")); getterAccessor.addAnnotation(new Annotation("GET")); - if (rn.getAllSelectors().size() > 0) { - getterAccessor.addAnnotation(new Annotation("Path", resourcePath)); + if (resourcePath.length() > 0) { + getterAccessor.addAnnotation(new Annotation("Path", "\"" + resourcePath + "\"")); } - getterAccessors.put(rn.getResourceHierarchy(), getterAccessor); + getterAccessors.put(resourceNode.getResourceHierarchy(), getterAccessor); } // Declare the input method in each resource and the root resource. for (Channel ch : model.getIOChannels()) { for (ChannelMember cm : ((DataTransferChannel) ch).getOutputChannelMembers()) { - if (rn.getInSideResources().contains(cm.getResource())) { + if (!cm.isOutside()) { + if (priorMemberForInputChannel.get(ch) == null) { + priorMemberForInputChannel.put(ch, cm); // The receiver of the input event when multiple output resources are defined for the channel. + } + } + } + for (ChannelMember cm : ((DataTransferChannel) ch).getOutputChannelMembers()) { + if (resourceNode.getInSideResources().contains(cm.getResource())) { Expression message = cm.getStateTransition().getMessageExpression(); if (message instanceof Term) { // In each resource. ArrayList resInputParams = new ArrayList<>(); ArrayList rootInputParams = new ArrayList<>(); - String resourcePath = getInputMethodResourcePathaAndPathParams(cm.getResource(), resInputParams, rootInputParams); + String resourcePath = getInputMethodResourcePathAndPathParams(cm.getResource(), resInputParams, rootInputParams); if (resourcePath.indexOf('/') > 0) { - resourcePath = "\"" + resourcePath.substring(resourcePath.indexOf('/')) + "\""; - } else { - resourcePath = "\"" + resourcePath + "\""; + resourcePath = resourcePath.substring(resourcePath.indexOf('/')); } for (Map.Entry varEnt: message.getVariables().entrySet()) { Variable var = varEnt.getValue(); @@ -557,36 +561,45 @@ String paramName = var.getName(); VariableDeclaration param = new VariableDeclaration(var.getType(), paramName); resInputParams.add(param); - param = new VariableDeclaration(var.getType(), paramName); - param.addAnnotation(new Annotation("FormParam", "\"" + paramName + "\"")); - rootInputParams.add(param); + if (!resourcePath.contains("{" + paramName+ "}")) { + param = new VariableDeclaration(var.getType(), paramName); + param.addAnnotation(new Annotation("FormParam", "\"" + paramName + "\"")); + rootInputParams.add(param); + } } } - if (rn.getResourceHierarchy().getParent() != null && rn.getResourceHierarchy().getParent().getParent() != null) { - MethodDeclaration input = new MethodDeclaration(((Term) message).getSymbol().getImplName(), - false, typeVoid, resInputParams); + if (resourceNode.getResourceHierarchy().getParent() != null && resourceNode.getResourceHierarchy().getParent().getParent() != null) { + String inputMethodName = ((Term) message).getSymbol().getImplName(); + if (((DataTransferChannel) ch).getOutputChannelMembers().size() > 1) { + inputMethodName += getComponentName(cm.getResource().getResourceHierarchy()); + } + MethodDeclaration input = new MethodDeclaration(inputMethodName, false, typeVoid, resInputParams); if (component != null) { // A component is created for this resource. component.addMethod(input); } else { // No component is created for this resource. - inputs.add(new AbstractMap.SimpleEntry<>(rn.getParent().getResourceHierarchy(), input)); + inputs.add(new AbstractMap.SimpleEntry<>(resourceNode.getParent().getResourceHierarchy(), input)); } } // For the root resource. - String str = ((Term) message).getSymbol().getImplName(); - MethodDeclaration inputAccessor = new MethodDeclaration(str, false, typeVoid, rootInputParams); - if (cm.getStateTransition().isRightUnary()) { - inputAccessor.addAnnotation(new Annotation("PUT")); - } else { - inputAccessor.addAnnotation(new Annotation("POST")); + if (priorMemberForInputChannel.get(ch) ==null || cm == priorMemberForInputChannel.get(ch)) { + // If cm is the receiver of the input event. + priorMemberForInputChannel.put(ch, cm); + String messageSymbol = ((Term) message).getSymbol().getImplName(); + MethodDeclaration inputAccessor = new MethodDeclaration(messageSymbol, false, typeVoid, rootInputParams); + if (cm.getStateTransition().isRightUnary()) { + inputAccessor.addAnnotation(new Annotation("PUT")); + } else { + inputAccessor.addAnnotation(new Annotation("POST")); + } + if (resourcePath.length() > 0) { + inputAccessor.addAnnotation(new Annotation("Path", "\"" + resourcePath + "\"")); + } + inputAccessors.put(resourceNode.getResourceHierarchy(), inputAccessor); } - if (ch.getAllSelectors().size() > 0) { - inputAccessor.addAnnotation(new Annotation("Path", resourcePath)); - } - inputAccessors.put(rn.getResourceHierarchy(), inputAccessor); } else if (message instanceof Variable) { // In each resource. ArrayList resInputParams = new ArrayList<>(); @@ -607,8 +620,11 @@ v++; } if (cm.getResource().getResourceHierarchy().getParent() != null && cm.getResource().getResourceHierarchy().getParent().getParent() != null) { - MethodDeclaration input = new MethodDeclaration(((Variable) message).getName(), - false, typeVoid, null); + String inputMethodName = ((Variable) message).getName(); + if (((DataTransferChannel) ch).getOutputChannelMembers().size() > 1) { + inputMethodName += getComponentName(cm.getResource().getResourceHierarchy()); + } + MethodDeclaration input = new MethodDeclaration(inputMethodName, false, typeVoid, null); if (component != null) { // A component is created for this resource. component.addMethod(input); @@ -619,24 +635,26 @@ } // For the root resource. - ArrayList rootInputParams = new ArrayList<>(); - String resourcePath = getGetterResourcePathAndPathParams(cm.getResource(), rootInputParams); - if (resourcePath.indexOf('/') > 0) { - resourcePath = "\"" + resourcePath.substring(resourcePath.indexOf('/')) + "\""; - } else { - resourcePath = "\"" + resourcePath + "\""; + if (priorMemberForInputChannel.get(ch) ==null || cm == priorMemberForInputChannel.get(ch)) { + // If cm is the receiver of the input event. + priorMemberForInputChannel.put(ch, cm); + ArrayList rootInputParams = new ArrayList<>(); + String resourcePath = getGetterResourcePathAndPathParams(cm.getResource(), rootInputParams); + if (resourcePath.indexOf('/') > 0) { + resourcePath = resourcePath.substring(resourcePath.indexOf('/')); + } + String messageSymbol = ((Variable) message).getName(); + MethodDeclaration inputAccessor = new MethodDeclaration(messageSymbol, false, typeVoid, rootInputParams); + if (cm.getStateTransition().isRightUnary()) { + inputAccessor.addAnnotation(new Annotation("PUT")); + } else { + inputAccessor.addAnnotation(new Annotation("POST")); + } + if (resourcePath.length() > 0) { + inputAccessor.addAnnotation(new Annotation("Path", "\"" + resourcePath + "\"")); + } + inputAccessors.put(resourceNode.getResourceHierarchy(), inputAccessor); } - String str = ((Variable) message).getName(); - MethodDeclaration inputAccessor = new MethodDeclaration(str, false, typeVoid, rootInputParams); - if (cm.getStateTransition().isRightUnary()) { - inputAccessor.addAnnotation(new Annotation("PUT")); - } else { - inputAccessor.addAnnotation(new Annotation("POST")); - } - if (ch.getAllSelectors().size() > 0) { - inputAccessor.addAnnotation(new Annotation("Path", resourcePath)); - } - inputAccessors.put(rn.getResourceHierarchy(), inputAccessor); } } } @@ -808,7 +826,7 @@ return resPath.getResourceHierarchy().toResourcePath(params); } - private static String getInputMethodResourcePathaAndPathParams(ResourcePath resPath, ArrayList resInputParams, + private static String getInputMethodResourcePathAndPathParams(ResourcePath resPath, ArrayList resInputParams, ArrayList rootInputParams) { int v = 1; List params = new ArrayList<>(); diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java index e04d2c6..921cdeb 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java @@ -136,16 +136,48 @@ } // Add statements to the update method. String[] sideEffects = new String[] {""}; - String curState = updateExp.toImplementation(sideEffects); - String updateStatement; - if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; + String newState = updateExp.toImplementation(sideEffects); + if (JerseyCodeGenerator.generatesComponent(outRes)) { + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + } else { + updateStatement = sideEffects[0] + "this.value = " + newState + ";"; + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + // add an update statement of the state of dst side resource. + update.addFirstStatement(updateStatement); + } } else { - updateStatement = sideEffects[0] + "this.value = " + curState + ";"; - } - if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { - // add an update statement of the state of dst side resource. - update.addFirstStatement(updateStatement); + String updateStatement = null; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + updateStatement = updateStatement.replace(".value", "." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(outRes))); + } else { + if (DataConstraintModel.typeList.isAncestorOf(outRes.getParent().getResourceStateType())) { + Term selector = new Term(DataConstraintModel.set); + selector.addChild(new Field("value")); + selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); + selector.addChild(new Constant(newState)); + String[] sideEffects2 = new String[] {""}; + String newList = selector.toImplementation(sideEffects2); + updateStatement = sideEffects[0] + sideEffects2[0]; + } else if (DataConstraintModel.typeMap.isAncestorOf(outRes.getParent().getResourceStateType())) { + Term selector = new Term(DataConstraintModel.insert); + selector.addChild(new Field("value")); + selector.addChild(new Variable(update.getParameters().get(update.getParameters().size() - 2).getName())); + selector.addChild(new Constant(newState)); + String[] sideEffects2 = new String[] {""}; + String newMap = selector.toImplementation(sideEffects2); + updateStatement = sideEffects[0] + sideEffects2[0]; + } else { + updateStatement = sideEffects[0] + "this." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(outRes)) + " = " + newState + ";"; + } + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + // add an update statement of the state of dst side resource. + update.addFirstStatement(updateStatement); + } } } if (resToCh.getDestination().getIndegree() > 1 @@ -512,13 +544,13 @@ MethodDeclaration input = null; if (JerseyCodeGenerator.generatesComponent(resource)) { // A component is generated for this resource. - input = getInputMethod(component, out); + input = getInputMethod(component, out, entry.getKey().getOutputChannelMembers().size()); } else { // No component is generated for this resource. ResourceHierarchy parent = resource.getParent(); if (parent != null) { TypeDeclaration parentType = componentMap.get(JerseyCodeGenerator.getComponentName(parent)); - input = getInputMethod(parentType, out); + input = getInputMethod(parentType, out, entry.getKey().getOutputChannelMembers().size()); } } if (input != null) { @@ -568,8 +600,8 @@ } else { String updateStatement = null; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - // ToDo. updateStatement = sideEffects[0]; + updateStatement = updateStatement.replace(".value", "." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(resource))); } else { if (DataConstraintModel.typeList.isAncestorOf(resource.getParent().getResourceStateType())) { Term selector = new Term(DataConstraintModel.set); @@ -590,15 +622,22 @@ } else { updateStatement = sideEffects[0] + "this." + JerseyCodeGenerator.toVariableName(JerseyCodeGenerator.getComponentName(resource)) + " = " + newState + ";"; } - if (updateStatement != null && (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement))) { - input.addStatement(updateStatement); - } + } + if (updateStatement != null && (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement))) { + input.addStatement(updateStatement); } } if (out.getResource().getParent() != null && out.getResource().getParent().getParent() != null) { // In the root resource - MethodDeclaration inputAccessor = getMethod(componentMap.get(JerseyCodeGenerator.getComponentName(resource.getRoot())), input.getName()); + Expression message = out.getStateTransition().getMessageExpression(); + String inputAccessorName = input.getName(); + if (message instanceof Term) { + inputAccessorName = ((Term) message).getSymbol().getImplName(); + } else if (message instanceof Variable) { + inputAccessorName = ((Variable) message).getName(); + } + MethodDeclaration inputAccessor = getMethod(componentMap.get(JerseyCodeGenerator.getComponentName(resource.getRoot())), inputAccessorName); if (inputAccessor != null) { Expression resExp = JerseyCodeGenerator.pullAccessor.getDirectStateAccessorFor(out.getResource(), out.getResource().getRoot()); String args = ""; @@ -612,8 +651,7 @@ resExp = ((Term) resExp).getChild(0); } String resourceAccess = resExp.toImplementation(new String[] {null}); - if (out.getStateTransition().getMessageExpression() instanceof Term) { - Term message = (Term) out.getStateTransition().getMessageExpression(); + if (message instanceof Term) { for (Variable var: message.getVariables().values()) { args += delimiter + var.getName(); delimiter = ", "; @@ -904,7 +942,7 @@ // I/O channel for (ChannelMember out: channel.getOutputChannelMembers()) { if (resource.getInSideResources().contains(out.getResource())) { - MethodDeclaration input = getInputMethod(component, out); + MethodDeclaration input = getInputMethod(component, out, channel.getOutputChannelMembers().size()); inputs.add(input); } } @@ -912,15 +950,19 @@ return inputs; } - private static MethodDeclaration getInputMethod(TypeDeclaration component, ChannelMember out) { - MethodDeclaration input = null; - if (out.getStateTransition().getMessageExpression() instanceof Term) { - Term message = (Term) out.getStateTransition().getMessageExpression(); - input = getMethod(component, message.getSymbol().getImplName()); - } else if (out.getStateTransition().getMessageExpression() instanceof Variable) { - Variable message = (Variable) out.getStateTransition().getMessageExpression(); - input = getMethod(component, message.getName()); + private static MethodDeclaration getInputMethod(TypeDeclaration component, ChannelMember cm, int outNumber) { + String inputMethodName = null; + if (cm.getStateTransition().getMessageExpression() instanceof Term) { + Term message = (Term) cm.getStateTransition().getMessageExpression(); + inputMethodName = message.getSymbol().getImplName(); + } else if (cm.getStateTransition().getMessageExpression() instanceof Variable) { + Variable message = (Variable) cm.getStateTransition().getMessageExpression(); + inputMethodName = message.getName(); } + if (outNumber > 1) { + inputMethodName += JerseyCodeGenerator.getComponentName(cm.getResource().getResourceHierarchy()); + } + MethodDeclaration input = getMethod(component, inputMethodName); return input; } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/Channel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/Channel.java index a778387..7f418be 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/Channel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/Channel.java @@ -102,6 +102,8 @@ if (!params.containsAll(channelMember.getResource().getPathParams())) { channelMember.setOutside(true); } + } else { + channelMember.setOutside(true); } }