diff --git a/AlgebraicDataflowArchitectureModel/src/models/DirectedGraph.java b/AlgebraicDataflowArchitectureModel/src/models/DirectedGraph.java index 3b9d1d3..42b7208 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/DirectedGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/models/DirectedGraph.java @@ -64,4 +64,8 @@ edge.getSource().removeOutEdge(edge); edge.getDestination().removeInEdge(edge); } + + protected void simpleAddEdge(Edge edge) { + edges.add(edge); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/Node.java b/AlgebraicDataflowArchitectureModel/src/models/Node.java index 3fa1e28..f2537f6 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/Node.java +++ b/AlgebraicDataflowArchitectureModel/src/models/Node.java @@ -1,11 +1,13 @@ package models; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.Set; public class Node implements Cloneable { - private Set inEdges = null; - private Set outEdges = null; + protected Collection inEdges = null; + protected Collection outEdges = null; private NodeAttribute attribute; public Node() { @@ -13,19 +15,19 @@ outEdges = new HashSet<>(); } - public Set getInEdges() { + public Collection getInEdges() { return inEdges; } - public void setInEdges(Set inEdges) { + public void setInEdges(Collection inEdges) { this.inEdges = inEdges; } - public Set getOutEdges() { + public Collection getOutEdges() { return outEdges; } - public void setOutEdges(Set outEdges) { + public void setOutEdges(Collection outEdges) { this.outEdges = outEdges; } @@ -61,16 +63,16 @@ return outEdges.size(); } - public Set getPredecessors() { - Set predecessors = new HashSet(); + public Collection getPredecessors() { + Collection predecessors = new ArrayList(); for (Edge edge: inEdges) { predecessors.add(edge.getSource()); } return predecessors; } - public Set getSuccessors() { - Set successors = new HashSet(); + public Collection getSuccessors() { + Collection successors = new ArrayList(); for (Edge edge: outEdges) { successors.add(edge.getDestination()); } diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdge.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdge.java new file mode 100644 index 0000000..cfe1c83 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdge.java @@ -0,0 +1,11 @@ +package models.controlFlowModel; + +import models.Edge; + +public class CallEdge extends Edge { + + public CallEdge(ObjectNode src, ObjectNode dst) { + super(src, dst); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java new file mode 100644 index 0000000..c533f09 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java @@ -0,0 +1,52 @@ +package models.controlFlowModel; + +import java.util.HashMap; +import java.util.Map; + +import models.DirectedGraph; +import models.Node; +import models.dataFlowModel.ResourceNode; + +public class CallGraph extends DirectedGraph { + protected Map statefulObjMap = null; + + public CallGraph() { + statefulObjMap = new HashMap<>(); + } + + public void addNode(Node node) { + super.addNode(node); + if (node instanceof ResourceNode) { + ResourceNode resNode = (ResourceNode) node; + StatefulObjectNode objNode = statefulObjMap.get(resNode); + if (objNode == null) { + objNode = new StatefulObjectNode(resNode); + statefulObjMap.put(resNode, objNode); + } + } else if (node instanceof StatefulObjectNode) { + StatefulObjectNode objNode = (StatefulObjectNode) node; + if (statefulObjMap.get(objNode.getResource()) == null) { + statefulObjMap.put(objNode.getResource(), objNode); + } + } + } + + public void addEdge(ResourceNode srcResNode, ResourceNode dstResNode) { + addNode(srcResNode); + addNode(dstResNode); + addEdge(new CallEdge(getStatefulObjectNode(srcResNode), getStatefulObjectNode(dstResNode))); + } + + public void insertEdge(ObjectNode srcObjNode, ObjectNode dstObjNode, int n) { + CallEdge edge = new CallEdge(srcObjNode, dstObjNode); + simpleAddEdge(edge); + addNode(srcObjNode); + addNode(dstObjNode); + srcObjNode.insertOutEdge(edge, n); + dstObjNode.addInEdge(edge); + } + + public StatefulObjectNode getStatefulObjectNode(ResourceNode resNode) { + return statefulObjMap.get(resNode); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java new file mode 100644 index 0000000..6f07049 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java @@ -0,0 +1,80 @@ +package models.controlFlowModel; + +import java.util.Map; +import java.util.Set; + +import models.DirectedGraph; +import models.Edge; +import models.Node; +import models.dataFlowModel.DataFlowGraph; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.DataFlowEdge; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; + +public class ControlFlowGraph { + private DataFlowGraph dataFlowGraph; + private CallGraph pushCallGraph; + private CallGraph pullCallGraph; + + public ControlFlowGraph(DataFlowGraph dataFlowGraph) { + this.dataFlowGraph = dataFlowGraph; + this.pushCallGraph = new CallGraph(); + this.pullCallGraph = new CallGraph(); + for (Edge e: dataFlowGraph.getEdges()) { + PushPullAttribute pushPull = ((PushPullAttribute) ((DataFlowEdge) e).getAttribute()); + ResourceNode srcNode = (ResourceNode) e.getSource(); + ResourceNode dstNode = (ResourceNode) e.getDestination(); + if (pushPull.getOptions().get(0) == PushPullValue.PUSH) { + // same direction as the data flow + pushCallGraph.addEdge(srcNode, dstNode); + } else { + // reverse direction to the data flow + pullCallGraph.addEdge(dstNode, srcNode); + } + } + } + + public ControlFlowGraph(DataFlowGraph dataFlowGraph, PushPullValue priority) { + this.dataFlowGraph = dataFlowGraph; + this.pushCallGraph = new CallGraph(); + this.pullCallGraph = new CallGraph(); + if (priority == PushPullValue.PUSH) { + // push-first + for (Edge e: dataFlowGraph.getEdges()) { + ResourceNode srcNode = (ResourceNode) e.getSource(); + ResourceNode dstNode = (ResourceNode) e.getDestination(); + // same direction as the data flow + pullCallGraph.addEdge(srcNode, dstNode); + } + } else { + // pull-first + for (Edge e: dataFlowGraph.getEdges()) { + ResourceNode srcNode = (ResourceNode) e.getSource(); + ResourceNode dstNode = (ResourceNode) e.getDestination(); + PushPullAttribute pushPull = ((PushPullAttribute) ((DataFlowEdge) e).getAttribute()); + if (pushPull.getOptions().contains(PushPullValue.PULL)) { + // Pull style is selectable + // reverse direction to the data flow + pullCallGraph.addEdge(dstNode, srcNode); + } else { + // Pull style is not selectable + // same direction as the data flow + pushCallGraph.addEdge(srcNode, dstNode); + } + } + } + } + + public DataFlowGraph getDataFlowGraph() { + return dataFlowGraph; + } + + public CallGraph getPushCallGraph() { + return pushCallGraph; + } + + public CallGraph getPullCallGraph() { + return pullCallGraph; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java new file mode 100644 index 0000000..d54d57d --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java @@ -0,0 +1,30 @@ +package models.controlFlowModel; + +import java.util.ArrayList; +import java.util.List; + +import models.Edge; +import models.Node; + +public class ObjectNode extends Node { + public ObjectNode() { + inEdges = new ArrayList<>(); + outEdges = new ArrayList<>(); + } + + public CallEdge getOutEdge(int i) { + return (CallEdge) ((List) outEdges).get(i); + } + + public void insertOutEdge(CallEdge edge, int n) { + ((List) outEdges).add(n, edge); + } + + public int getChildrenNum() { + return outEdges.size(); + } + + public ObjectNode getChildren(int i) { + return (ObjectNode) ((List) outEdges).get(i).getDestination(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/StatefulObjectNode.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/StatefulObjectNode.java new file mode 100644 index 0000000..d15155c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/StatefulObjectNode.java @@ -0,0 +1,16 @@ +package models.controlFlowModel; + +import models.dataFlowModel.ResourceNode; + +public class StatefulObjectNode extends ObjectNode { + private ResourceNode resource; + + public StatefulObjectNode(ResourceNode resource) { + this.resource = resource; + } + + public ResourceNode getResource() { + return resource; + } + +}