diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java index 9473eb6..4d51c71 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java @@ -15,6 +15,7 @@ import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGeometry; import com.mxgraph.model.mxGraphModel; +import com.mxgraph.util.mxConstants; import com.mxgraph.util.mxPoint; import com.mxgraph.view.mxGraph; @@ -24,6 +25,9 @@ import code.ast.CompilationUnit; import models.Edge; import models.Node; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.IdentifierTemplate; import models.dataFlowModel.DataFlowModel; import models.dataFlowModel.DataflowChannelGenerator; import models.dataFlowModel.PushPullAttribute; @@ -93,6 +97,11 @@ return curFileName; } + /** + * Open a given file, parse the file, construct a DataFlowModel and a mxGraph + * @param file given file + * @return a constructed DataFlowModel + */ public DataFlowModel open(File file) { try { Parser parser = new Parser(new BufferedReader(new FileReader(file))); @@ -115,6 +124,12 @@ return null; } + /** + * Construct a mxGraph from DataFlowModel and DataFlowModel + * @param model + * @param resourceDependencyGraph + * @return constructed mxGraph + */ public mxGraph constructGraph(DataFlowModel model, ResourceDependencyGraph resourceDependencyGraph) { ((mxGraphModel) graph.getModel()).clear(); Object parent = graph.getDefaultParent(); @@ -130,16 +145,18 @@ Map channelsIn = new HashMap<>(); Map channelsOut = new HashMap<>(); - Map resources = new HashMap<>(); + Map resources = new HashMap<>(); Map> resourceToChannels = new HashMap<>(); Map> channelToResources = new HashMap<>(); + Set refEdgeCreated = new HashSet<>(); + // create channel vertices for (Edge e : resourceDependencyGraph.getEdges()) { if (e instanceof ResourceDependency) { ResourceDependency dependency = (ResourceDependency) e; DataflowChannelGenerator channelGen = dependency.getChannelGenerator(); if (channelsIn.get(channelGen) == null || channelsOut.get(channelGen) == null) { - Object channel = graph.insertVertex(parent, null, channelGen.getChannelName(), 150, 20, 30, 30); // insert�@a�@channel�@as�@a�@vertex + Object channel = graph.insertVertex(parent, null, channelGen.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); port_in.setVertex(true); graph.addCell(port_in, channel); // insert the input port of a channel @@ -152,46 +169,72 @@ } } + // create resource vertices for (Node n : resourceDependencyGraph.getNodes()) { if (n instanceof ResourceNode) { ResourceNode resourceNode = (ResourceNode) n; Object resource = graph.insertVertex(parent, null, resourceNode.getIdentifierTemplate().getResourceName(), 20, 20, 80, 30, - "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a node - resources.put(resourceNode, resource); + "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex + resources.put(resourceNode.getIdentifierTemplate(), resource); } } - + + // add input, output and reference edges for (Edge e : resourceDependencyGraph.getEdges()) { if (e instanceof ResourceDependency) { ResourceDependency dependency = (ResourceDependency) e; DataflowChannelGenerator channelGen = dependency.getChannelGenerator(); ResourceNode srcResource = (ResourceNode) dependency.getSource(); ResourceNode dstResource = (ResourceNode) dependency.getDestination(); + // input edge Map resToChannelEdges = resourceToChannels.get(srcResource); if (resToChannelEdges == null) { resToChannelEdges = new HashMap<>(); resourceToChannels.put(srcResource, resToChannelEdges); } if (resToChannelEdges.get(channelGen) == null) { - mxCell edge = (mxCell) graph.insertEdge(parent, null, dependency.getAttribute(), resources.get(srcResource), channelsIn.get(channelGen)); + mxCell edge = (mxCell) graph.insertEdge(parent, null, dependency.getAttribute(), resources.get(srcResource.getIdentifierTemplate()), channelsIn.get(channelGen), "movable=false"); resToChannelEdges.put(channelGen, edge); } else { mxCell edge = resToChannelEdges.get(channelGen); ((PushPullAttribute) edge.getValue()).intersectOptions(((PushPullAttribute) dependency.getAttribute()).getOptions()); } + // output edge Set resSet = channelToResources.get(channelGen); if (resSet == null) { resSet = new HashSet<>(); channelToResources.put(channelGen, resSet); } if (!resSet.contains(dstResource)) { - graph.insertEdge(parent, null, null, channelsOut.get(channelGen), resources.get(dstResource)); + graph.insertEdge(parent, null, null, channelsOut.get(channelGen), resources.get(dstResource.getIdentifierTemplate()), "movable=false"); resSet.add(dstResource); } + // reference edges + if (!refEdgeCreated.contains(channelGen)) { + refEdgeCreated.add(channelGen); + for (IdentifierTemplate refRes: channelGen.getReferenceIdentifierTemplates()) { + mxCell edge = (mxCell) graph.insertEdge(parent, null, null, resources.get(refRes), channelsIn.get(channelGen), "dashed=true;movable=false"); + } + } + } + } + + for (ChannelGenerator ioChannelGen: model.getIOChannelGenerators()) { + if (channelsOut.get(ioChannelGen) == null) { + Object channel = graph.insertVertex(parent, null, ioChannelGen.getChannelName(), 150, 20, 30, 30); // insert an I/O channel as a vertex + mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); + port_out.setVertex(true); + graph.addCell(port_out, channel); // insert the output port of a channel + channelsOut.put((DataflowChannelGenerator) ioChannelGen, port_out); + for (IdentifierTemplate outRes: ((DataflowChannelGenerator) ioChannelGen).getOutputIdentifierTemplates()) { + graph.insertEdge(parent, null, null, port_out, resources.get(outRes), "movable=false"); + } } } + graph.setAllowDanglingEdges(false); + graph.setCellsDisconnectable(false); } finally { graph.getModel().endUpdate(); }