diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java index 87cd8a4..06ebf11 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -635,4 +635,44 @@ } }; } + + protected IResourceStateAccessor getRefAccessor() { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes= target.getResource(); + ResourcePath fromRes= from.getResource(); + if (targetRes.equals(fromRes)) { + return new Field(fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // use the cached value as the current state + return new Parameter(targetRes.getResourceName(), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targerRes= target.getResource(); + return new Parameter(targerRes.getResourceName(), + targerRes.getResourceStateType() != null ? targerRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null && targetRes.equals(fromRes)) { + return new Field(fieldOfResourceState, + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(targetRes.getResourceName(), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + }; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 26953ca..39de6cd 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -651,7 +651,20 @@ try { for (ChannelMember out: ch.getOutputChannelMembers()) { if (resourceNode.getInSideResources().contains(out.getResource())) { - Expression updateExp = ch.deriveUpdateExpressionOf(out, getPushAccessor()); + Expression updateExp = null; + if (ch.getReferenceChannelMembers().size() == 0) { + updateExp = ch.deriveUpdateExpressionOf(out, getPushAccessor()); + } else { + // if there exists one or more reference channel member. + HashMap inputResourceToStateAccessor = new HashMap<>(); + for (ChannelMember in: ch.getInputChannelMembers()) { + inputResourceToStateAccessor.put(in, getPushAccessor()); + } + for (ChannelMember c: ch.getReferenceChannelMembers()) { + inputResourceToStateAccessor.put(c, getRefAccessor()); + } + updateExp = ch.deriveUpdateExpressionOf(out, getPushAccessor(), inputResourceToStateAccessor); + } // Replace Json constructor with a constructor of the child resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { @@ -806,7 +819,7 @@ String[] sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); - update.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); + update.addStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } params.add(refVarName); } @@ -1140,7 +1153,7 @@ String[] sideEffects = new String[] {""}; String refExp = refGetter.toImplementation(sideEffects); String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); - input.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); + input.addStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); } params.add(refVarName); } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java index 034f160..b15569b 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java @@ -1148,4 +1148,42 @@ } } }; + + static public IResourceStateAccessor refAccessor = new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + ResourcePath fromRes = from.getResource(); + if (targetRes.equals(fromRes)) { + return new Field("value", + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(targetRes.getResourceName(), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + return new Parameter(targetRes.getResourceName(), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null && targetRes.equals(fromRes)) { + return new Field("value", + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(targetRes.getResourceName(), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + }; } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java index 42788c6..083520a 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java @@ -102,7 +102,20 @@ MethodDeclaration update = getUpdateMethod(dstComponent, srcResName); if (((StoreAttribute) dst.getAttribute()).isStored()) { // update stored state of dst side resource (when every incoming edge is in push style) - Expression updateExp = ch.deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); + Expression updateExp = null; + if (ch.getReferenceChannelMembers().size() == 0) { + updateExp = ch.deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); + } else { + // if there exists one or more reference channel member. + HashMap inputResourceToStateAccessor = new HashMap<>(); + for (ChannelMember in: ch.getInputChannelMembers()) { + inputResourceToStateAccessor.put(in, JavaCodeGenerator.pushAccessor); + } + for (ChannelMember c: ch.getReferenceChannelMembers()) { + inputResourceToStateAccessor.put(c, JavaCodeGenerator.refAccessor); + } + updateExp = ch.deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor, inputResourceToStateAccessor); + } // Replace Json constructor with a constructor of the child resource. ResourceHierarchy outRes = out.getResource().getResourceHierarchy(); if (outRes.getChildren().size() == 1 && outRes.getChildren().iterator().next().getNumParameters() > 0) { @@ -121,7 +134,7 @@ if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { updateStatement = sideEffects[0]; } else { - updateStatement = sideEffects[0] + "value = " + curState + ";"; + updateStatement = sideEffects[0] + "this.value = " + curState + ";"; } if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { update.addFirstStatement(updateStatement); diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java index c5eb874..7e81d3b 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java @@ -545,7 +545,7 @@ } if (rn.getResourceHierarchy().getParent() != null && rn.getResourceHierarchy().getParent().getParent() != null) { - MethodDeclaration input = new MethodDeclaration(((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(), + MethodDeclaration input = new MethodDeclaration(((Term) message).getSymbol().getImplName(), false, typeVoid, resInputParams); if (component != null) { // A component is created for this resource. @@ -557,7 +557,7 @@ } // For the root resource. - String str = ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(); + String str = ((Term) message).getSymbol().getImplName(); MethodDeclaration inputAccessor = new MethodDeclaration(str, false, typeVoid, rootInputParams); if (cm.getStateTransition().isRightUnary()) { inputAccessor.addAnnotation(new Annotation("PUT")); @@ -588,7 +588,7 @@ v++; } if (cm.getResource().getResourceHierarchy().getParent() != null && cm.getResource().getResourceHierarchy().getParent().getParent() != null) { - MethodDeclaration input = new MethodDeclaration(((Variable) cm.getStateTransition().getMessageExpression()).getName(), + MethodDeclaration input = new MethodDeclaration(((Variable) message).getName(), false, typeVoid, null); if (component != null) { // A component is created for this resource. @@ -607,7 +607,7 @@ } else { resourcePath = "\"" + resourcePath + "\""; } - String str = ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(); + String str = ((Variable) message).getName(); MethodDeclaration inputAccessor = new MethodDeclaration(str, false, typeVoid, rootInputParams); if (cm.getStateTransition().isRightUnary()) { inputAccessor.addAnnotation(new Annotation("PUT")); @@ -1024,4 +1024,38 @@ } } }; + static public IResourceStateAccessor refAccessor = new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + ResourcePath fromRes = from.getResource(); + if (targetRes.equals(fromRes)) { + return new Field("value", + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(targetRes.getResourceName(), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) { + ResourcePath targetRes = target.getResource(); + return new Parameter(targetRes.getResourceName(), + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) { + if (fromRes != null && targetRes.equals(fromRes)) { + return new Field("value", + targetRes.getResourceStateType() != null ? targetRes.getResourceStateType() + : DataConstraintModel.typeInt); + } + return null; + } + }; } diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java index 60c64c3..a04e044 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java @@ -119,7 +119,7 @@ } } for (ChannelMember c: ch.getReferenceChannelMembers()) { - inputResourceToStateAccessor.put(c, JerseyCodeGenerator.pullAccessor); + inputResourceToStateAccessor.put(c, JerseyCodeGenerator.refAccessor); } updateExp = ch.deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor, inputResourceToStateAccessor); } diff --git a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java index 022588b..126b47b 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java @@ -208,6 +208,7 @@ resourceHierarchy.setInitialValue(rightTerm); resourceHierarchy.setInitText(stream.getSourceText(fromLine, toLine)); } + if (stream.hasNext()) stream.next(); } public ChannelMember parseChannelMember(DataTransferModel model, final String inOrOutOrRef) @@ -521,6 +522,7 @@ } if (!stream.hasNext()) throw new WrongPathExpression(stream.getLine()); if (stream.checkNext().equals(LEFT_BRACKET)) break; + if (stream.checkNext().equals(COLON)) break; } while (stream.next().equals(DOT)); return hierarchy; }