package graphicalrefactor.editor; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import java.util.HashMap; import com.mxgraph.layout.mxCircleLayout; import com.mxgraph.layout.mxCompactTreeLayout; import com.mxgraph.layout.mxParallelEdgeLayout; import com.mxgraph.layout.mxPartitionLayout; import com.mxgraph.layout.mxStackLayout; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGeometry; import com.mxgraph.model.mxGraphModel; import com.mxgraph.util.mxPoint; import com.mxgraph.view.mxGraph; import algorithms.DataStorageNecessity; import algorithms.EdgeTransitionSelectable; import algorithms.UpdateConflictCheck; import code.ast.TypeDeclaration; import models.Edge; import models.Node; import models.dataFlowModel.DataFlowModel; import models.dataFlowModel.DataflowChannelGenerator; import models.dataFlowModel.PushPullAttribute; import models.dataFlowModel.PushPullValue; import models.dataFlowModel.ResourceDependency; import models.dataFlowModel.ResourceDependencyGraph; import models.dataFlowModel.ResourceNode; import parser.ExpectedChannel; import parser.ExpectedChannelName; import parser.ExpectedEquals; import parser.ExpectedInOrOutKeyword; import parser.ExpectedLeftCurlyBracket; import parser.ExpectedRHSExpression; import parser.ExpectedRightBracket; import parser.ExpectedStateTransition; import parser.Parser; import parser.WrongLHSExpression; import parser.WrongRHSExpression; public class Editor { final int PORT_DIAMETER = 8; final int PORT_RADIUS = PORT_DIAMETER / 2; private mxGraph graph = null; private DataFlowModel model = null; private ResourceDependencyGraph resourceGraph = null; private ArrayList<TypeDeclaration> codes = null; public Editor(mxGraph graph) { this.graph = graph; } public mxGraph getGraph() { return graph; } public void setGraph(mxGraph graph) { this.graph = graph; } public DataFlowModel getModel() { return model; } public void setModel(DataFlowModel model) { this.model = model; } public ResourceDependencyGraph getResourceGraph() { return resourceGraph; } public void setResourceGraph(ResourceDependencyGraph resourceGraph) { this.resourceGraph = resourceGraph; } public ArrayList<TypeDeclaration> getCodes() { return codes; } public void setCodes(ArrayList<TypeDeclaration> codes) { this.codes = codes; } public DataFlowModel open(File file) { try { Parser parser = new Parser(new BufferedReader(new FileReader(file))); try { model = parser.doParse(); if(!UpdateConflictCheck.run(model)) return null; graph = constructGraph(model); return model; } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } public mxGraph constructGraph(DataFlowModel model) { ResourceDependencyGraph resourceDependencyGraph = DataStorageNecessity.run(model); EdgeTransitionSelectable.run(resourceDependencyGraph); ((mxGraphModel) graph.getModel()).clear(); Object parent = graph.getDefaultParent(); graph.getModel().beginUpdate(); try { mxGeometry geo1 = new mxGeometry(0, 0.5, PORT_DIAMETER, PORT_DIAMETER); geo1.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); geo1.setRelative(true); mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); geo2.setRelative(true); HashMap<DataflowChannelGenerator, Object> channelsIn = new HashMap<>(); HashMap<DataflowChannelGenerator, Object> channelsOut = new HashMap<>(); HashMap<ResourceNode, Object> resources = new HashMap<>(); 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 mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); port_in.setVertex(true); graph.addCell(port_in, channel); mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); port_out.setVertex(true); graph.addCell(port_out, channel); channelsIn.put(channelGen, port_in); channelsOut.put(channelGen, port_out); } } } 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); } } for (Edge e : resourceDependencyGraph.getEdges()) { if (e instanceof ResourceDependency) { ResourceDependency dependency = (ResourceDependency) e; DataflowChannelGenerator channelGen = dependency.getChannelGenerator(); graph.insertEdge(parent, null, dependency.getAttribute(), resources.get(dependency.getSource()), channelsIn.get(channelGen)); graph.insertEdge(parent, null, null, channelsOut.get(channelGen), resources.get(dependency.getDestination())); } } } finally { graph.getModel().endUpdate(); } setTreeLayout(); setResourceGraph(resourceDependencyGraph); return graph; } public void setTreeLayout() { Object parent = graph.getDefaultParent(); graph.getModel().beginUpdate(); try { mxCompactTreeLayout ctl = new mxCompactTreeLayout(graph); ctl.setLevelDistance(100); // ctl.setHorizontal(false); ctl.setEdgeRouting(false); ctl.execute(parent); } finally { graph.getModel().endUpdate(); } } public void setCircleLayout() { Object parent = graph.getDefaultParent(); graph.getModel().beginUpdate(); try { mxCircleLayout ctl = new mxCircleLayout(graph); ctl.execute(parent); } finally { graph.getModel().endUpdate(); } } }