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.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; public class DataFlowGraph extends DirectedGraph { 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); } 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; } }