package models.dataFlowModel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import models.DirectedGraph;
import models.Node;
import models.dataConstraintModel.ResourceHierarchy;
import models.dataConstraintModel.ResourcePath;
public class DataFlowGraph extends DirectedGraph implements IFlowGraph {
protected Set<ResourceNode> rootResourceNodes = null;
protected Set<ChannelNode> rootChannelNodes = null;
protected Map<DataTransferChannel, ChannelNode> channelNodeMap = null;
protected Map<Integer, ResourceNode> resourceNodeMap = null;
public DataFlowGraph() {
super();
rootResourceNodes = new HashSet<>();
rootChannelNodes = new HashSet<>();
channelNodeMap = new HashMap<>();
resourceNodeMap = new HashMap<>();
}
public ResourceNode addResourceNode(ResourceNode parent,
ResourcePath outSideResource,
DataTransferChannel outSideChannel) {
ResourceNode node = null;
if (outSideResource.getNumberOfParameters() == 0) {
// a global (possibly non-root) resource node
Collection<ResourceNode> nodes = getResourceNodes(outSideResource.getResourceHierarchy());
if (nodes.size() > 0) {
node = nodes.iterator().next();
if (outSideChannel != null) {
// not a terminal node
node.addOutSideResource(outSideChannel, outSideResource);
}
}
} else {
// a channel local resource node
node = resourceNodeMap.get(System.identityHashCode(outSideResource));
}
if (node != null) return node;
node = new ResourceNode(parent, outSideResource, outSideChannel);
addNode(node);
if (parent == null) {
rootResourceNodes.add(node);
} else {
parent.addChild(node);
}
resourceNodeMap.put(System.identityHashCode(outSideResource), node);
return node;
}
public ResourceNode addTerminalResourceNode(ResourceNode parent,
DataTransferChannel inSideChannel,
ResourcePath inSideResource) {
ResourceNode node = null;
if (inSideResource.getNumberOfParameters() == 0) {
// a global (possibly non-root) terminal resource node
Collection<ResourceNode> nodes = getResourceNodes(inSideResource.getResourceHierarchy());
if (nodes.size() > 0) {
node = nodes.iterator().next();
}
} else {
// a channel local terminal resource node
node = resourceNodeMap.get(System.identityHashCode(inSideResource));
}
if (node != null) return node;
node = new ResourceNode(parent, inSideResource, inSideChannel, true);
addNode(node);
if (parent == null) {
rootResourceNodes.add(node);
} else {
parent.addChild(node);
}
resourceNodeMap.put(System.identityHashCode(inSideResource), node);
return node;
}
public ResourceNode addResourceNode(ResourceNode parent,
Map<DataTransferChannel, ResourcePath> inSide,
Map<DataTransferChannel, ResourcePath> outSide) {
ResourceNode node = null;
for (ResourcePath outRes: outSide.values()) {
node = resourceNodeMap.get(System.identityHashCode(outRes));
if (node != null) return node;
}
for (ResourcePath inRes: inSide.values()) {
node = resourceNodeMap.get(System.identityHashCode(inRes));
if (node != null) return node;
}
node = new ResourceNode(parent, inSide, outSide);
addNode(node);
if (parent == null) {
rootResourceNodes.add(node);
} else {
parent.addChild(node);
}
for (ResourcePath outRes: outSide.values()) {
resourceNodeMap.put(System.identityHashCode(outRes), node);
}
for (ResourcePath inRes: inSide.values()) {
resourceNodeMap.put(System.identityHashCode(inRes), node);
}
return node;
}
public ChannelNode addChannelNode(ChannelNode parent, DataTransferChannel ch) {
ChannelNode node = channelNodeMap.get(ch);
if (node != null) return node;
node = new ChannelNode(parent, ch);
addNode(node);
if (parent == null) {
rootChannelNodes.add(node);
} else {
parent.addChild(node);
}
channelNodeMap.put(ch, node);
return node;
}
public ResourceNode getResourceNode(ResourcePath resPath) {
return resourceNodeMap.get(System.identityHashCode(resPath));
}
public ChannelNode getChannelNode(DataTransferChannel channel) {
return channelNodeMap.get(channel);
}
@Override
public Map<Node, Set<Node>> getAllComponentNodes() {
Map<Node, Set<Node>> allNodeSets = new HashMap<>();
for (Node n: getResourceNodes()) {
Set<Node> nodeSet = new HashSet<>();
nodeSet.add(n);
allNodeSets.put(n, nodeSet);
}
return allNodeSets;
}
public Collection<ResourceNode> getResourceNodes() {
HashSet<ResourceNode> result = new HashSet<>(resourceNodeMap.values());
return result;
}
public Collection<ResourceNode> getResourceNodes(ResourceHierarchy resourceHierarchy) {
Collection<ResourceNode> resourceNodes = new ArrayList<>();
for (ResourceNode rn: resourceNodeMap.values()) {
if (rn.getResourceHierarchy() == resourceHierarchy) {
resourceNodes.add(rn);
}
}
return resourceNodes;
}
public Collection<ChannelNode> getChannelNodes() {
return channelNodeMap.values();
}
public Set<ResourceNode> getRootResourceNodes() {
return rootResourceNodes;
}
public Set<ChannelNode> getRootChannelNodes() {
return rootChannelNodes;
}
public DataFlowEdge addEdge(ResourceNode srcNode, ChannelNode dstNode) {
DataFlowEdge edge =new DataFlowEdge(srcNode, dstNode);
addEdge(edge);
return edge;
}
public DataFlowEdge addEdge(ChannelNode srcNode, ResourceNode dstNode) {
DataFlowEdge edge = new DataFlowEdge(srcNode, dstNode);
addEdge(edge);
return edge;
}
}