diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java index a3d2687..d5ca291 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java @@ -375,7 +375,7 @@ Map channelsIn = new HashMap<>(); Map channelsOut = new HashMap<>(); - Map resources = new HashMap<>(); + Map resources = new HashMap<>(); // create channel vertices for (ChannelNode c: dataFlowGraph.getRootChannelNodes()) { @@ -455,7 +455,7 @@ Object resource = graph.insertVertex(parent, null, res.getResourceName(), 20, 20, w, h, "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - resources.put(res, resource); + resources.put(System.identityHashCode(res), resource); getChildResource(resource, resNode, resources, w, h); } @@ -466,7 +466,7 @@ // output edge DataTransferChannel channel = ((ChannelNode) dfEdge.getSource()).getChannel(); ResourcePath dstRes = ((ResourceNode) dfEdge.getDestination()).getOutSideResource(); - graph.insertEdge(parent, null, new SrcDstAttribute(channel, dstRes), channelsOut.get(channel), resources.get(dstRes), "movable=false"); + graph.insertEdge(parent, null, new SrcDstAttribute(channel, dstRes), channelsOut.get(channel), resources.get(System.identityHashCode(dstRes)), "movable=false"); } else { // input edge ResourcePath srcRes = ((ResourceNode) dfEdge.getSource()).getOutSideResource(); @@ -474,10 +474,11 @@ Set> toRes = getResourceDependencyForChannel(channel, model, dataFlowGraph); for(Map.Entry RtoR : toRes) { graph.insertEdge(parent, null, null, - resources.get(RtoR.getValue().getOutSideResource()), resources.get(RtoR.getKey().getOutSideResource()), "dashed=true;movable=false"); + resources.get(System.identityHashCode(RtoR.getValue().getOutSideResource())), + resources.get(System.identityHashCode(RtoR.getKey().getOutSideResource())), "dashed=true;movable=false"); } - graph.insertEdge(parent, null, new SrcDstAttribute(srcRes, channel), resources.get(srcRes), channelsIn.get(channel), "movable=false"); + graph.insertEdge(parent, null, new SrcDstAttribute(srcRes, channel), resources.get(System.identityHashCode(srcRes)), channelsIn.get(channel), "movable=false"); } } @@ -485,7 +486,7 @@ // reference edges DataTransferChannel channel = (DataTransferChannel) ch; for (ResourcePath refRes: channel.getReferenceResources()) { - graph.insertEdge(parent, null, null, resources.get(refRes), channelsIn.get(channel), "dashed=true;movable=false"); + graph.insertEdge(parent, null, null, resources.get(System.identityHashCode(refRes)), channelsIn.get(channel), "dashed=true;movable=false"); } } } finally { @@ -497,7 +498,7 @@ return graph; } - public void getChildResource(Object resource, ResourceNode resNode, Map resources, int w, int h) { + public void getChildResource(Object resource, ResourceNode resNode, Map resources, int w, int h) { for (ResourceNode c: resNode.getChildren()) { // w = w - 100; @@ -509,7 +510,7 @@ Object chResource = graph.insertVertex(resource, null, chRes.getName(), 0, 0, w, h, "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - resources.put(chRes, chResource); + resources.put(System.identityHashCode(chRes), chResource); getChildResource(chResource, c, resources, w, h); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataFlowGraph.java index b241023..6be124c 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataFlowGraph.java @@ -13,7 +13,7 @@ protected Set rootResourceNodes = null; protected Set rootChannelNodes = null; protected Map channelNodeMap = null; - protected Map resourceNodeMap = null; + protected Map resourceNodeMap = null; public DataFlowGraph() { super(); @@ -26,7 +26,7 @@ public ResourceNode addResourceNode(ResourceNode parent, DataTransferChannel outSideChannel, ResourcePath outSideResource) { - ResourceNode node = resourceNodeMap.get(outSideResource); + ResourceNode node = resourceNodeMap.get(System.identityHashCode(outSideResource)); if (node != null) return node; node = new ResourceNode(parent, outSideChannel, outSideResource); addNode(node); @@ -35,14 +35,14 @@ } else { parent.addChild(node); } - resourceNodeMap.put(outSideResource, node); + resourceNodeMap.put(System.identityHashCode(outSideResource), node); return node; } public ResourceNode addResourceNode(ResourceNode parent, Map inSide, Map.Entry outSide) { - ResourceNode node = resourceNodeMap.get(outSide.getValue()); + ResourceNode node = resourceNodeMap.get(System.identityHashCode(outSide.getValue())); if (node != null) return node; node = new ResourceNode(parent, inSide, outSide); addNode(node); @@ -51,7 +51,7 @@ } else { parent.addChild(node); } - resourceNodeMap.put(outSide.getValue(), node); + resourceNodeMap.put(System.identityHashCode(outSide.getValue()), node); return node; } @@ -70,7 +70,7 @@ } public ResourceNode getResourceNode(ResourcePath outSide) { - return resourceNodeMap.get(outSide); + return resourceNodeMap.get(System.identityHashCode(outSide)); } public ChannelNode getChannelNode(DataTransferChannel channel) { diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataTransferModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataTransferModel.java index b339a66..8bef89f 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataTransferModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataTransferModel.java @@ -13,7 +13,7 @@ public class DataTransferModel extends DataConstraintModel { public DataFlowGraph getDataFlowGraph() { DataFlowGraph dataFlowGraph = new DataFlowGraph(); - Map> resourceMap = new HashMap<>(); + Map>> resourceMap = new HashMap<>(); for (Channel channel: getChannels()) { addResourceToChannelEdges(dataFlowGraph, channel, null, resourceMap); } @@ -27,13 +27,38 @@ } private void addResourceToChannelEdges(DataFlowGraph dataFlowGraph, Channel dstChannel, ChannelNode parentChannelNode, - Map> resourceMap) { - DataTransferChannel dstDfChannel = (DataTransferChannel)dstChannel; + Map>> resourceMap) { + DataTransferChannel dstDfChannel = (DataTransferChannel) dstChannel; ChannelNode dstChannelNode = dataFlowGraph.addChannelNode(parentChannelNode, dstDfChannel); - Set inputResources = dstDfChannel.getInputResources(); - for (ResourcePath srcRes: inputResources) { - ResourceNode srcResNode = addResourceNodes(dataFlowGraph, srcRes, dstDfChannel, resourceMap); - dataFlowGraph.addEdge(srcResNode, dstChannelNode); + for (ResourcePath srcRes: dstDfChannel.getInputResources()) { + Map> chToNodes = resourceMap.get(srcRes.getResourceHierarchy()); + if (srcRes.getNumberOfParameters() == 0) { + if (chToNodes == null || chToNodes.get(null) == null) { + // ResourcePath without parameter corresponds to a global ResourceNode. + ResourceNode srcResNode = addResourceNodes(dataFlowGraph, srcRes, null, resourceMap); + dataFlowGraph.addEdge(srcResNode, dstChannelNode); + } + } else { + if (chToNodes == null || chToNodes.get(dstChannel) == null) { + // There is no channel-local ResourcePath. + ResourceNode srcResNode = addResourceNodes(dataFlowGraph, srcRes, dstDfChannel, resourceMap); + dataFlowGraph.addEdge(srcResNode, dstChannelNode); + } else { + // There already has been a channel-local ResourceNode. + Set nodes = chToNodes.get(dstChannel); // channel-local ResourceNodes. + boolean bExists = false; + for (ResourceNode node: nodes) { + if (node.getOutSideResource().toString().equals(srcRes.toString())) { + bExists = true; + break; + } + } + if (!bExists) { + ResourceNode srcResNode = addResourceNodes(dataFlowGraph, srcRes, dstDfChannel, resourceMap); + dataFlowGraph.addEdge(srcResNode, dstChannelNode); + } + } + } } for (Channel childChannel: dstDfChannel.getChildren()) { addResourceToChannelEdges(dataFlowGraph, childChannel, dstChannelNode, resourceMap); @@ -41,45 +66,144 @@ } private void addChannelToResourceEdges(DataFlowGraph dataFlowGraph, Channel srcChannel, ChannelNode parentChannelNode, - Map> resourceMap) { - DataTransferChannel srcDfChannel = (DataTransferChannel)srcChannel; - Set outputResources = srcDfChannel.getOutputResources(); + Map>> resourceMap) { + DataTransferChannel srcDfChannel = (DataTransferChannel) srcChannel; ChannelNode srcChannelNode = dataFlowGraph.addChannelNode(parentChannelNode, srcDfChannel); - for (ResourcePath dstRes: outputResources) { - Set dstResSet = resourceMap.get(dstRes.getResourceHierarchy()); // ResourceNodes that have the same ResourceHierarchy. - if (dstResSet == null || dstResSet.size() == 0) { - ResourceNode dstResNode = addResourceNodes(dataFlowGraph, dstRes, srcDfChannel, resourceMap); - if (dstResSet == null) { - dstResSet = new HashSet<>(); - resourceMap.put(dstRes.getResourceHierarchy(), dstResSet); + for (ResourcePath dstRes: srcDfChannel.getOutputResources()) { + Map> chToNodes = resourceMap.get(dstRes.getResourceHierarchy()); // ResourceNodes that have the same ResourceHierarchy. + if (dstRes.getNumberOfParameters() == 0) { + // ResourcePath without parameter corresponds to a global ResourceNode. + if (chToNodes == null) { + ResourceNode dstResNode = addResourceNodes(dataFlowGraph, dstRes, null, resourceMap); } - dstResSet.add(dstResNode); + } else { + if (chToNodes == null) { + // There is no ResourcePath. + ResourceNode dstResNode = addResourceNodes(dataFlowGraph, dstRes, srcDfChannel, resourceMap); + } else { + // There already has been a ResourceNode. + boolean bExists = false; + for (Set nodes: chToNodes.values()) { + for (ResourceNode node: nodes) { + for (ResourcePath res: node.getInSideResources()) { + if (res.toString().equals(dstRes.toString())) { + bExists = true; + break; + } + } + if (bExists) break; + if (node.getOutSideResource() != null && node.getOutSideResource().toString().equals(dstRes.toString())) { + bExists = true; + break; + } + } + if (bExists) break; + } + if (!bExists) { + ResourceNode dstResNode = addResourceNodes(dataFlowGraph, dstRes, srcDfChannel, resourceMap); + } + } } - for (ResourceNode dstResNode: dstResSet) { - dstResNode.addInSideResource(srcDfChannel, dstRes); - dataFlowGraph.addEdge(srcChannelNode, dstResNode); // Connect to each ResourceNode that has the same ResourceHierarchy. + for (Set dstResSet: resourceMap.get(dstRes.getResourceHierarchy()).values()) { + for (ResourceNode dstResNode: dstResSet) { + dstResNode.addInSideResource(srcDfChannel, dstRes); + dataFlowGraph.addEdge(srcChannelNode, dstResNode); // Connect to each ResourceNode that has the same ResourceHierarchy. + } } } for (Channel childChannel: srcDfChannel.getChildren()) { addChannelToResourceEdges(dataFlowGraph, childChannel, srcChannelNode, resourceMap); } } - + private ResourceNode addResourceNodes(DataFlowGraph dataFlowGraph, ResourcePath resPath, DataTransferChannel dfChannel, - Map> resourceMap) { + Map>> resourceMap) { ResourceNode resNode = null; if (resPath.getParent() == null) { resNode = dataFlowGraph.addResourceNode(null, dfChannel, resPath); } else { - ResourceNode parent = addResourceNodes(dataFlowGraph, resPath.getParent(), null, resourceMap); + // Search a parent ResourceNode that does not have resPath as its child. + ResourceNode parent = null; + if (resourceMap.get(resPath.getResourceHierarchy().getParent()) != null) { + for (Set nodes: resourceMap.get(resPath.getResourceHierarchy().getParent()).values()) { + for (ResourceNode node: nodes) { + // For each node, every child should be unique. + if (resPath.getResourceHierarchy().getNumParameters() > 0) { + // Children that have parameters are distinguished. + parent = node; + break; + } + boolean bExists = false; + for (ResourceNode child: node.getChildren()) { + if (child.getResourceHierarchy().getResourceName().equals(resPath.getResourceHierarchy().getResourceName())) { + bExists = true; // node already has resPath as its child. + break; + } + } + if (!bExists) { + parent = node; + break; + } + } + if (parent != null) break; + } + } + if (parent == null) { + parent = addResourceNodes(dataFlowGraph, resPath.getParent(), dfChannel, resourceMap); + } resNode = dataFlowGraph.addResourceNode(parent, dfChannel, resPath); } - Set resSet = resourceMap.get(resPath.getResourceHierarchy()); - if (resSet == null) { - resSet = new HashSet<>(); - resourceMap.put(resPath.getResourceHierarchy(), resSet); + Map> chToNodes = resourceMap.get(resPath.getResourceHierarchy()); + if (chToNodes == null) { + chToNodes = new HashMap<>(); + resourceMap.put(resPath.getResourceHierarchy(), chToNodes); } - resSet.add(resNode); + Set nodes = chToNodes.get(dfChannel); + if (nodes == null) { + nodes = new HashSet<>(); + chToNodes.put(dfChannel, nodes); + } + nodes.add(resNode); return resNode; } + +// private ResourceNode addResourceNodes(DataFlowGraph dataFlowGraph, ResourcePath resPath, DataTransferChannel dfChannel, +// Map>> resourceMap) { +// if (resPath.getNumberOfParameters() == 0) { +// // ResourcePath without parameter corresponds to a global ResourceNode. +// dfChannel = null; +// } +// if (resourceMap.get(resPath.getResourceHierarchy()) != null && resourceMap.get(resPath.getResourceHierarchy()).get(dfChannel) != null) { +// Set nodes = resourceMap.get(resPath.getResourceHierarchy()).get(dfChannel); +// for (ResourceNode node: nodes) { +// if (node.getOutSideResource().toString().equals(resPath.toString())) { +// return node; +// } +// for (ResourcePath res: node.getInSideResources()) { +// if (res.toString().toString().equals(resPath.toString())) { +// return node; +// } +// } +// } +// } +// ResourceNode resNode = null; +// if (resPath.getParent() == null) { +// resNode = dataFlowGraph.addResourceNode(null, dfChannel, resPath); +// } else { +// ResourceNode parent = addResourceNodes(dataFlowGraph, resPath.getParent(), dfChannel, resourceMap); +// resNode = dataFlowGraph.addResourceNode(parent, dfChannel, resPath); +// } +// Map> chToNodes = resourceMap.get(resPath.getResourceHierarchy()); +// if (chToNodes == null) { +// chToNodes = new HashMap<>(); +// resourceMap.put(resPath.getResourceHierarchy(), chToNodes); +// } +// Set nodes = chToNodes.get(dfChannel); +// if (nodes == null) { +// nodes = new HashSet<>(); +// chToNodes.put(dfChannel, nodes); +// } +// nodes.add(resNode); +// return resNode; +// } }