diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java index 7675b30..94d3caf 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java @@ -351,46 +351,41 @@ static private ArrayList determineResourceOrder(ResourceDependencyGraph graph) { ArrayList resources = new ArrayList<>(); + Set visited = new HashSet<>(); for (Node n : graph.getNodes()) { ResourceNode rn = (ResourceNode) n; - boolean flag = true; - for (Edge e : rn.getOutEdges()) { - ResourceDependency re = (ResourceDependency) e; - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { - flag = false; - } - } - for (Edge e : rn.getInEdges()) { - ResourceDependency re = (ResourceDependency) e; - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { - flag = false; - } - } - if (flag) - resources.add(rn); - } - List initialResources = (List) resources.clone(); - for (ResourceNode r: initialResources) { - trackNode(r, resources); + topologicalSort(graph, rn, visited, resources); } return resources; } - - static private void trackNode(ResourceNode current, ArrayList resources) { - if (!resources.contains(current)) - resources.add(current); - for (Edge e : current.getOutEdges()) { - ResourceDependency re = (ResourceDependency) e; - if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { - trackNode((ResourceNode) re.getDestination(), resources); - } - } - for (Edge e : current.getInEdges()) { + + static private void topologicalSort(ResourceDependencyGraph graph, ResourceNode curNode, Set visited, List orderedList) { + if (visited.contains(curNode)) return; + visited.add(curNode); + for (Edge e : curNode.getInEdges()) { ResourceDependency re = (ResourceDependency) e; if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { - trackNode((ResourceNode) re.getSource(), resources); + topologicalSort(graph, (ResourceNode) re.getSource(), visited, orderedList); } } + for (Edge e : curNode.getOutEdges()) { + ResourceDependency re = (ResourceDependency) e; + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + topologicalSort(graph, (ResourceNode) re.getDestination(), visited, orderedList); + } + } + for (Node n: graph.getNodes()) { // for reference resources. + ResourceNode rn = (ResourceNode) n; + for (Edge e : rn.getInEdges()) { + ResourceDependency re = (ResourceDependency) e; + for (ChannelMember m: re.getChannelGenerator().getReferenceChannelMembers()) { + if (m.getIdentifierTemplate() == curNode.getIdentifierTemplate()) { + topologicalSort(graph, rn, visited, orderedList); + } + } + } + } + orderedList.add(0, curNode); } private static MethodDeclaration getMethod(TypeDeclaration type, String methodName) { diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java index 4278567..6662ab9 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java @@ -3,8 +3,10 @@ import java.util.AbstractMap; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import code.ast.CompilationUnit; import code.ast.MethodDeclaration; @@ -156,34 +158,36 @@ getter.addStatement("return " + resource.getIdentifierTemplate().getResourceName() + ";"); } // methods for input events - Map.Entry ioChannelAndMember = getIOChannelAndMember(resource, model); - if (ioChannelAndMember != null) { - ChannelMember out = ioChannelAndMember.getValue(); - Term message = (Term) out.getStateTransition().getMessageExpression(); - MethodDeclaration input = getMethod(type, message.getSymbol().getName()); - if (input != null) { - String[] sideEffects = new String[] {""}; - Expression updateExp = ioChannelAndMember.getKey().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); - String newState = updateExp.toImplementation(sideEffects); - String updateStatement; - if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; - } else { - updateStatement = sideEffects[0] + "this." + resourceName + " = " + newState + ";"; - } - if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { - input.addFirstStatement(updateStatement); - } - if (mainType != null) { - MethodDeclaration mainInput = getMethod(mainType, input.getName()); - if (mainInput != null) { - String args = ""; - String delimitar = ""; - for (Variable var: message.getVariables().values()) { - args += delimitar + var.getName(); - delimitar = ", "; + Map.Entry> ioChannelAndMembers = getIOChannelAndMembers(resource, model); + if (ioChannelAndMembers != null) { + Set outs = ioChannelAndMembers.getValue(); + for (ChannelMember out: outs) { + Term message = (Term) out.getStateTransition().getMessageExpression(); + MethodDeclaration input = getMethod(type, message.getSymbol().getName()); + if (input != null) { + String[] sideEffects = new String[] {""}; + Expression updateExp = ioChannelAndMembers.getKey().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); + String newState = updateExp.toImplementation(sideEffects); + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + } else { + updateStatement = sideEffects[0] + "this." + resourceName + " = " + newState + ";"; + } + if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { + input.addFirstStatement(updateStatement); + } + if (mainType != null) { + MethodDeclaration mainInput = getMethod(mainType, input.getName()); + if (mainInput != null) { + String args = ""; + String delimitar = ""; + for (Variable var: message.getVariables().values()) { + args += delimitar + var.getName(); + delimitar = ", "; + } + mainInput.addStatement("this." + resourceName + "." + input.getName() + "(" + args + ");"); } - mainInput.addStatement("this." + resourceName + "." + input.getName() + "(" + args + ");"); } } } @@ -221,20 +225,24 @@ return null; } - private static Map.Entry getIOChannelAndMember(ResourceNode resource, DataFlowModel model) { + private static Map.Entry> getIOChannelAndMembers(ResourceNode resource, DataFlowModel model) { + Set channelMembers = new HashSet<>(); + DataflowChannelGenerator channel = null; for (ChannelGenerator c: model.getIOChannelGenerators()) { - DataflowChannelGenerator channel = (DataflowChannelGenerator) c; + DataflowChannelGenerator ch = (DataflowChannelGenerator) c; // I/O channel - for (ChannelMember out: channel.getOutputChannelMembers()) { + for (ChannelMember out: ch.getOutputChannelMembers()) { if (out.getIdentifierTemplate().equals(resource.getIdentifierTemplate())) { if (out.getStateTransition().getMessageExpression() instanceof Term) { // not an identity element - return new AbstractMap.SimpleEntry<>(channel, out); + channel = ch; + channelMembers.add(out); } } } } - return null; + if (channel == null) return null; + return new AbstractMap.SimpleEntry<>(channel, channelMembers); } private static MethodDeclaration getInputMethod(TypeDeclaration type, ResourceNode resource, DataFlowModel model) { diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java index c7e5ae5..89446db 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java @@ -220,23 +220,25 @@ getter.addStatement("return " + resource.getIdentifierTemplate().getResourceName() + ";"); } // methods for input events - Map.Entry ioChannelAndMember = getIOChannelAndMember(resource, model); - if (ioChannelAndMember != null) { - ChannelMember out = ioChannelAndMember.getValue(); - Term message = (Term) out.getStateTransition().getMessageExpression(); - MethodDeclaration input = getMethod(type, message.getSymbol().getName()); - if (input != null) { - Expression updateExp = ioChannelAndMember.getKey().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor); - String[] sideEffects = new String[] {""}; - String newState = updateExp.toImplementation(sideEffects); - String updateStatement; - if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = sideEffects[0]; - } else { - updateStatement = sideEffects[0] + "this." + resourceName + " = " + newState + ";"; - } - if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { - input.addFirstStatement(updateStatement); + Map.Entry> ioChannelAndMembers = getIOChannelAndMembers(resource, model); + if (ioChannelAndMembers != null) { + Set outs = ioChannelAndMembers.getValue(); + for (ChannelMember out: outs) { + Term message = (Term) out.getStateTransition().getMessageExpression(); + MethodDeclaration input = getMethod(type, message.getSymbol().getName()); + if (input != null) { + Expression updateExp = ioChannelAndMembers.getKey().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor); + String[] sideEffects = new String[] {""}; + String newState = updateExp.toImplementation(sideEffects); + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + } else { + updateStatement = sideEffects[0] + "this." + resourceName + " = " + newState + ";"; + } + if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { + input.addFirstStatement(updateStatement); + } } } } @@ -380,20 +382,24 @@ return null; } - private static Map.Entry getIOChannelAndMember(ResourceNode resource, DataFlowModel model) { + private static Map.Entry> getIOChannelAndMembers(ResourceNode resource, DataFlowModel model) { + Set channelMembers = new HashSet<>(); + DataflowChannelGenerator channel = null; for (ChannelGenerator c: model.getIOChannelGenerators()) { - DataflowChannelGenerator channel = (DataflowChannelGenerator) c; + DataflowChannelGenerator ch = (DataflowChannelGenerator) c; // I/O channel - for (ChannelMember out: channel.getOutputChannelMembers()) { + for (ChannelMember out: ch.getOutputChannelMembers()) { if (out.getIdentifierTemplate().equals(resource.getIdentifierTemplate())) { if (out.getStateTransition().getMessageExpression() instanceof Term) { // not an identity element - return new AbstractMap.SimpleEntry<>(channel, out); + channel = ch; + channelMembers.add(out); } } } } - return null; + if (channel == null) return null; + return new AbstractMap.SimpleEntry<>(channel, channelMembers); } private static MethodDeclaration getInputMethod(TypeDeclaration type, ResourceNode resource, DataFlowModel model) {