diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java index 69047fa..3f29dc0 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java @@ -1,145 +1,80 @@ package application.editor; -import java.awt.event.MouseListener; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.AbstractMap; -import java.util.AbstractMap.SimpleEntry; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - import application.editor.stages.DataFlowModelingStage; import application.editor.stages.PushPullSelectionStage; +import application.layouts.DAGLayout; +import code.ast.CompilationUnit; import com.mxgraph.layout.mxCircleLayout; import com.mxgraph.layout.mxCompactTreeLayout; import com.mxgraph.model.mxCell; -import com.mxgraph.model.mxGeometry; -import com.mxgraph.model.mxGraphModel; -import com.mxgraph.model.mxICell; -import com.mxgraph.model.mxIGraphModel; import com.mxgraph.swing.mxGraphComponent; -import com.mxgraph.util.*; +import com.mxgraph.util.mxEvent; +import com.mxgraph.util.mxEventSource.mxIEventListener; import com.mxgraph.view.mxCellState; import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxGraphView; - -import algorithms.DataTransferModelAnalyzer; -import algorithms.Validation; -import application.layouts.*; -import code.ast.CompilationUnit; -import generators.JavaCodeGenerator; -import models.Edge; import models.EdgeAttribute; -import models.Node; -import models.algebra.Expression; -import models.algebra.InvalidMessage; -import models.algebra.ParameterizedIdentifierIsFutureWork; -import models.algebra.UnificationFailed; -import models.algebra.ValueUndefined; import models.dataConstraintModel.Channel; -import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.DataConstraintModel; -import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; -import models.dataConstraintModel.Selector; -import models.dataFlowModel.DataTransferModel; -import models.dataFlowModel.DataTransferChannel; -import models.dataFlowModel.PushPullAttribute; -import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; -import models.dataFlowModel.ChannelNode; -import models.dataFlowModel.DataFlowEdge; import models.dataFlowModel.DataFlowGraph; -import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.DataTransferModel; import models.visualModel.FormulaChannel; import parser.Parser; -import parser.Parser.TokenStream; -import parser.exceptions.ExpectedAssignment; -import parser.exceptions.ExpectedChannel; -import parser.exceptions.ExpectedChannelName; -import parser.exceptions.ExpectedColon; -import parser.exceptions.ExpectedEquals; -import parser.exceptions.ExpectedFormulaChannel; -import parser.exceptions.ExpectedGeometry; -import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; -import parser.exceptions.ExpectedIoChannel; -import parser.exceptions.ExpectedLeftCurlyBracket; -import parser.exceptions.ExpectedModel; -import parser.exceptions.ExpectedNode; -import parser.exceptions.ExpectedRHSExpression; -import parser.exceptions.ExpectedResource; -import parser.exceptions.ExpectedRightBracket; -import parser.exceptions.ExpectedStateTransition; -import parser.exceptions.WrongJsonExpression; -import parser.exceptions.WrongLHSExpression; -import parser.exceptions.WrongRHSExpression; -import parser.exceptions.ExpectedRightCurlyBracket; -import parser.exceptions.WrongPathExpression; import parser.ParserDTRAM; +import parser.exceptions.*; + +import java.awt.event.MouseListener; +import java.io.*; +import java.util.ArrayList; +import java.util.List; public class Editor { - final int PORT_DIAMETER = 8; - final int PORT_RADIUS = PORT_DIAMETER / 2; - protected DataTransferModel model = null; - protected mxGraph graph = null; - private mxGraphComponent graphComponent = null; + protected DataTransferModel model = null; + protected mxGraph graph; + private final mxGraphComponent graphComponent; - protected DataFlowGraph dataFlowGraph = null; + protected Stage curStage; + private final List stageChangeListeners; - protected Stage curStage = null; - private List stageChangeListeners = null; - - private mxEventSource.mxIEventListener curChangeEventListener = null; + private mxIEventListener curChangeEventListener = null; private MouseListener curMouseEventListener = null; - protected String curFileName = null; - protected String curFilePath = null; - protected ArrayList codes = null; + protected String curFileName = null; + protected String curFilePath = null; + protected ArrayList codes = null; - public static DataFlowModelingStage STAGE_DATA_FLOW_MODELING = null; - public static PushPullSelectionStage STAGE_PUSH_PULL_SELECTION = null; + // FIXME These variables should be named by camel-case because they are not constant. + public static DataFlowModelingStage STAGE_DATA_FLOW_MODELING = null; + public static PushPullSelectionStage STAGE_PUSH_PULL_SELECTION = null; - private boolean bReflectingArchitectureModel = false; + public Editor(mxGraphComponent graphComponent) { + this.graphComponent = graphComponent; + this.graph = graphComponent.getGraph(); - public Editor(mxGraphComponent graphComponent) { - this.graphComponent = graphComponent; - this.graph = graphComponent.getGraph(); + STAGE_DATA_FLOW_MODELING = new DataFlowModelingStage(graphComponent); + STAGE_PUSH_PULL_SELECTION = new PushPullSelectionStage(graphComponent); - STAGE_DATA_FLOW_MODELING = new DataFlowModelingStage(graphComponent); - STAGE_PUSH_PULL_SELECTION = new PushPullSelectionStage(graphComponent); + graphComponent.setCellEditor(STAGE_DATA_FLOW_MODELING.createCellEditor(graphComponent)); - graphComponent.setCellEditor(STAGE_DATA_FLOW_MODELING.createCellEditor(graphComponent)); + curStage = STAGE_DATA_FLOW_MODELING; - curStage = STAGE_DATA_FLOW_MODELING; + stageChangeListeners = new ArrayList<>(); + } - stageChangeListeners = new ArrayList<>(); - } + public mxGraph getGraph() { + return graph; + } - public mxGraph getGraph() { - return graph; - } + public mxGraphComponent getGraphComponent() { + return this.graphComponent; + } - public mxGraphComponent getGraphComponent() { - return this.graphComponent; - } - - public DataTransferModel getModel() { - if (model == null) { - model = new DataTransferModel(); - } - return model; - } + public DataTransferModel getModel() { + model = curStage.getModel(); + return model; + } public Stage getCurStage() { return curStage; @@ -165,15 +100,17 @@ } // A handler of a mouse event. - if(curMouseEventListener != null) { + if (curMouseEventListener != null) { graphComponent.getGraphControl().removeMouseListener(curMouseEventListener); } curMouseEventListener = nextStage.createMouseEventListener(this); - if(curMouseEventListener != null) { + if (curMouseEventListener != null) { graphComponent.getGraphControl().addMouseListener(curMouseEventListener); } curStage = nextStage; notifyStageChangeListeners(); + + setDAGLayout(); // FIXME Not correct workaround return true; } @@ -182,715 +119,343 @@ } private void notifyStageChangeListeners() { - for (IStageChangeListener l: stageChangeListeners) { + for (IStageChangeListener l : stageChangeListeners) { l.stageChanged(curStage); } } - public DataFlowGraph getDataFlowGraph() { - if (dataFlowGraph == null) { - analyzeDataTransferModel(getModel()); - updateEdgeAttiributes(dataFlowGraph); - } - return dataFlowGraph; - } + public DataFlowGraph getDataFlowGraph() { + if (curStage instanceof PushPullSelectionStage) { + return ((PushPullSelectionStage) curStage).getDataFlowGraph(); + } + return null; + } - public DataFlowGraph analyzeDataTransferModel(DataTransferModel model) { - DataFlowGraph flowGraph = DataTransferModelAnalyzer.createDataFlowGraphWithStateStoringAttribute(model); - dataFlowGraph = DataTransferModelAnalyzer.annotateWithSelectableDataTransferAttiribute(flowGraph); - return dataFlowGraph; - } + public ArrayList getCodes() { + return codes; + } - public void resetDataFlowGraph() { - dataFlowGraph = null; - } + public void setCodes(ArrayList codes) { + this.codes = codes; + } - public void setDataFlowGraph(DataFlowGraph dataFlowGraph) { - this.dataFlowGraph = dataFlowGraph; - } + public String getCurFileName() { + return curFileName; + } - public ArrayList getCodes() { - return codes; - } + public String getCurFilePath() { + return curFilePath; + } - public void setCodes(ArrayList codes) { - this.codes = codes; - } + public void setCurFilePath(String curFilePath) { + this.curFilePath = curFilePath; + this.curFileName = new File(curFilePath).getName(); + } - public String getCurFileName() { - return curFileName; - } + public void clear() { + // Force to change to the data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).clear(); - public String getCurFilePath() { - return curFilePath; - } + model = null; + curFilePath = null; + curFileName = null; + codes = null; + // resetDataFlowGraph + } - public void setCurFilePath(String curFilePath) { - this.curFilePath = curFilePath; - this.curFileName = new File(curFilePath).getName(); - } + /** + * Open a given file, parse the file, construct a DataFlowModel and a mxGraph + * + * @param file given file + */ + public void open(File file) { + // Force to change to data-modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) { + return; + } + if (file == null || !file.exists()) { + return; + } + // get a file's extension + String extension = file.getName().substring(file.getName().lastIndexOf(".")); + if (extension.contains(".model")) { + openModel(file); + } + if (extension.contains(".dtram")) { + openDTRAM(file); + } + } - public void clear() { - model = null; - ((mxGraphModel) graph.getModel()).clear(); - dataFlowGraph = null; - curFilePath = null; - curFileName = null; - codes = null; - } + private void openModel(File file) { + try { + Parser parser = new Parser(new BufferedReader(new FileReader(file))); + try { + // Parse the .model file. + model = parser.doParse(); - /** - * Open a given file, parse the file, construct a DataFlowModel and a mxGraph - * @param file given file - * @return a constructed DataFlowModel - */ - public DataTransferModel open(File file) { - try { + // Update stage's model to new parsed one + if (curStage instanceof DataFlowModelingStage) { + DataFlowModelingStage stage = (DataFlowModelingStage) curStage; + stage.setModel(model); + } - String extension =""; - if(file != null && file.exists()) { - // get a file's name - String name = file.getName(); + // Force to change PushPullSelectionStage to construct mxGraph + changeStage(STAGE_PUSH_PULL_SELECTION); - // get a file's extension - extension = name.substring(name.lastIndexOf(".")); - } - if(extension.contains(".model")) { - openModel(file); - } else { - ParserDTRAM parserDTRAM = new ParserDTRAM(new BufferedReader(new FileReader(file))); - try { - // Parse the .dtram file. - model = parserDTRAM.doParseModel(); + // Update current file info + curFilePath = file.getAbsolutePath(); + curFileName = file.getName(); + } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | + ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | + ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | + ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | + ExpectedColon e) { + e.printStackTrace(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } - // Analyze the model. - if (!Validation.checkUpdateConflict(model)) return null; - DataFlowGraph dataFlowGraph = analyzeDataTransferModel(model); + private void openDTRAM(File file) { + try { + ParserDTRAM parser = new ParserDTRAM(new BufferedReader(new FileReader(file))); + try { + // Parse the .dtram file. + model = parser.doParseModel(); - // Visualize the model. - graph = constructGraph(model, dataFlowGraph); - parserDTRAM.doParseGeometry(graph); - updateEdgeAttiributes(dataFlowGraph); + // Update stage's model to new parsed one + if (curStage instanceof DataFlowModelingStage) { + DataFlowModelingStage stage = (DataFlowModelingStage) curStage; + stage.setModel(model); + } - curFilePath = file.getAbsolutePath(); - curFileName = file.getName(); - return model; - } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword - | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedModel - | ExpectedGeometry | ExpectedNode | ExpectedResource | ExpectedFormulaChannel | ExpectedIoChannel - | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } + // Parse Geometry + parser.doParseGeometry(graph); - return null; - } + // Force to change PushPullSelectionStage to construct mxGraph + changeStage(STAGE_PUSH_PULL_SELECTION); - public DataTransferModel openModel(File file) { - try { + // Update current file info + curFilePath = file.getAbsolutePath(); + curFileName = file.getName(); + } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | + ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | + ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | + ExpectedAssignment | ExpectedModel | ExpectedGeometry | ExpectedNode | ExpectedResource | + ExpectedFormulaChannel | ExpectedIoChannel | ExpectedRightCurlyBracket | WrongPathExpression | + WrongJsonExpression | ExpectedColon e) { + e.printStackTrace(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } - Parser parser = new Parser(new BufferedReader(new FileReader(file))); + public void save() { + if (curFilePath == null) { + return; + } + File file = new File(curFilePath); + if (!file.exists()) { + return; + } + // get a file's extension + String extension = file.getName().substring(file.getName().lastIndexOf(".")); + if (extension.contains(".model")) { + saveModel(file); + } + if (extension.contains(".dtram")) { + saveDTRAM(file); + } + } - try { - // Parse the .model file. - model = parser.doParse(); + private void saveModel(File file) { + try { + FileWriter filewriter = new FileWriter(file); + filewriter.write(model.getSourceText()); + filewriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } - // Analyze the model. - if (!Validation.checkUpdateConflict(model)) return null; - DataFlowGraph dataFlowGraph = analyzeDataTransferModel(model); + private void saveDTRAM(File file) { + try { + FileWriter filewriter = new FileWriter(file); + filewriter.write(toOutputString()); + filewriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } - // Visualize the model. - graph = constructGraph(model, dataFlowGraph); - updateEdgeAttiributes(dataFlowGraph); + /** + * get writing texts "dtram" file information is written. + * + * @return formatted "dtram" info texts. + */ + private String toOutputString() { + StringBuilder fileString = new StringBuilder(); - // Set DAG layout. -// setDAGLayout(); + fileString.append("model {\n"); + fileString.append(this.model.getSourceText()); + fileString.append("}\n"); - curFilePath = file.getAbsolutePath(); - curFileName = file.getName(); - return model; - } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword - | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return null; - } + fileString.append("geometry {\n"); - /**-------------------------------------------------------------------------------- - * save - /**-------------------------------------------------------------------------------- - * - */ - public void save() { - if (curFilePath != null) { - try { - File file = new File(curFilePath); - String extension = ""; - if(file != null && file.exists()) { - // get a file's name - String name = file.getName(); + Object root = graph.getDefaultParent(); + for (int i = 0; i < graph.getModel().getChildCount(root); i++) { + Object cell = graph.getModel().getChildAt(root, i); + if (graph.getModel().isVertex(cell)) { + mxGraphView view = graph.getView(); + mxCellState state = view.getState(cell); + int x = (int) state.getX(); + int y = (int) state.getY(); + int w = (int) state.getWidth(); + int h = (int) state.getHeight(); - // get a file's extension - extension = name.substring(name.lastIndexOf(".")); - } - if(extension.contains(".model")) { - saveModel(file); - } else { - FileWriter filewriter = new FileWriter(file); - filewriter.write(toOutputString()); - filewriter.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - } + for (Channel ch : model.getChannels()) { + if (ch instanceof FormulaChannel && state.getLabel().equals(ch.getChannelName())) { + fileString.append("\tnode fc ").append(state.getLabel()).append(":").append(x).append(",").append(y).append(",").append(w).append(",").append(h).append("\n"); + } else if (ch != null && state.getLabel().equals(ch.getChannelName())) { + fileString.append("\tnode c ").append(state.getLabel()).append(":").append(x).append(",").append(y).append(",").append(w).append(",").append(h).append("\n"); + } + } - public void saveModel(File file) { - if (curFilePath != null) { - try { - FileWriter filewriter = new FileWriter(file); - filewriter.write(model.getSourceText()); - filewriter.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } + for (ResourcePath res : model.getResourcePaths()) { + if (res != null && state.getLabel().equals(res.getLeafResourceName())) + fileString.append("\tnode r ").append(state.getLabel()).append(":").append(x).append(",").append(y).append(",").append(w).append(",").append(h).append("\n"); + } - /**-------------------------------------------------------------------------------- - * get writing texts "dtram" file information is written. - * - * @return formatted "dtram" info texts. - */ - protected String toOutputString() { - String fileString = ""; + for (Channel ioC : model.getInputChannels()) { + if (ioC != null && state.getLabel().equals(ioC.getChannelName())) { + fileString.append("\tnode ioc ").append(state.getLabel()).append(":").append(x).append(",").append(y).append(",").append(w).append(",").append(h).append("\n"); + } + } + } + } + fileString.append("}\n"); - fileString += "model {\n"; - fileString += this.model.getSourceText(); - fileString += "}\n"; + return fileString.toString(); + } - fileString += "geometry {\n"; + public void delete() { + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).delete(); + } - Object root = graph.getDefaultParent(); - for (int i = 0; i < graph.getModel().getChildCount(root); i++) { - Object cell = graph.getModel().getChildAt(root, i); - if (graph.getModel().isVertex(cell)) { - mxGraphView view = graph.getView(); - mxCellState state = view.getState(cell); - int x = (int) state.getX(); - int y = (int) state.getY(); - int w = (int) state.getWidth(); - int h = (int) state.getHeight(); + public void setDAGLayout() { + Object parent = graph.getDefaultParent(); + graph.getModel().beginUpdate(); + try { + DAGLayout ctl = new DAGLayout(graph); + ctl.execute(parent); + } finally { + graph.getModel().endUpdate(); + } + } - for(Channel ch: model.getChannels()) { - if(ch instanceof FormulaChannel && state.getLabel().equals(ch.getChannelName())) { - fileString += "\tnode fc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; - } else if(ch instanceof Channel && state.getLabel().equals(ch.getChannelName())) { - fileString +="\tnode c " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; - } - } + 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(); + } + } - for (ResourcePath res: model.getResourcePaths()){ - if(res instanceof ResourcePath && state.getLabel().equals(res.getLeafResourceName())) - fileString += "\tnode r " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"; - } + public void setCircleLayout() { + Object parent = graph.getDefaultParent(); + graph.getModel().beginUpdate(); + try { + mxCircleLayout ctl = new mxCircleLayout(graph); + ctl.execute(parent); + } finally { + graph.getModel().endUpdate(); + } + } - for (Channel ioC: model.getInputChannels()) { - if(ioC instanceof Channel && state.getLabel().equals(ioC.getChannelName())) { - fileString += "\tnode ioc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"; - } - } - } - } - fileString += "}\n"; + public void addResourcePath(ResourcePath parentPath, String resName) { + // Force to change to data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).addResourcePath(parentPath, resName); + model = curStage.getModel(); + } - return fileString; - } + public void addChannel(DataTransferChannel channelGen) { + // Force to change to data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).addChannel(channelGen); + model = curStage.getModel(); + } - /** - * Construct a mxGraph from DataFlowModel and DataFlowModel - * @param model - * @param dataFlowGraph - * @return constructed mxGraph - */ - public mxGraph constructGraph(DataTransferModel model, DataFlowGraph dataFlowGraph) { - bReflectingArchitectureModel = true; - ((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); + public void addIOChannel(DataTransferChannel ioChannelGen) { + // Force to change to data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).addIOChannel(ioChannelGen); + model = curStage.getModel(); + } - mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo2.setRelative(true); - - Map channelsIn = new HashMap<>(); - Map channelsOut = new HashMap<>(); - Map resources = new HashMap<>(); - - // create resource vertices - for (ResourceNode resNode: dataFlowGraph.getRootResourceNodes()) { - int w = 80; - int h = 30; - ResourcePath res = resNode.getPrimaryResourcePath(); - Object resource = graph.insertVertex(parent, null, - res.getLeafResourceName(), 20, 20, w, h, - "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - resources.put(resNode, resource); - createChildResourceVerticies(resource, resNode, resources, w, h); - } - - // create channel vertices - for (ChannelNode c: dataFlowGraph.getRootChannelNodes()) { - DataTransferChannel channel = (DataTransferChannel) c.getChannel(); - if (channel.getInputResources().size() > 0) { - // Normal channel - if (channelsIn.get(channel) == null || channelsOut.get(channel) == null) { - if (channel.getSelectors().toString() == "[]") { - Object chCell = graph.insertVertex(parent, null, channel.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, chCell); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, chCell); // insert the output port of a channel - channelsIn.put(channel, port_in); - channelsOut.put(channel, port_out); - } else { - for (Selector s: channel.getSelectors()) { - Expression exp = s.getExpression(); - String selName = exp.toString(); - String cName = channel.getChannelName(); - String channelName = cName + " (" + selName + ")"; - Object chCell = graph.insertVertex(parent, null, channelName, 150, 20, 60, 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, chCell); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, chCell); // insert the output port of a channel - channelsIn.put(channel, port_in); - channelsOut.put(channel, port_out); - } - } - } - } else { - // I/O channel - if (channelsOut.get(channel) == null) { - if (channel.getSelectors().toString() == "[]") { - Object chCell = graph.insertVertex(parent, null, channel.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, chCell); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, chCell); // insert the output port of a channel - channelsIn.put(channel, port_in); - channelsOut.put(channel, port_out); - } else { - for (Selector s: channel.getSelectors()) { - Expression exp = s.getExpression(); - String selName = exp.toString(); - String cName = channel.getChannelName(); - String channelName = cName + " (" + selName + ")"; - Object chCell = graph.insertVertex(parent, null, channelName, 150, 20, 60, 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, chCell); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, chCell); // insert the output port of a channel - channelsIn.put(channel, port_in); - channelsOut.put(channel, port_out); - } - } - } - } - } - - // add input, output and reference edges - for (Edge edge: dataFlowGraph.getEdges()) { - DataFlowEdge dfEdge = (DataFlowEdge) edge; - if (dfEdge.isChannelToResource()) { - // output edge - DataTransferChannel channel = ((ChannelNode) dfEdge.getSource()).getChannel(); - ResourcePath dstRes = ((ResourceNode) dfEdge.getDestination()).getInSideResource(channel); - graph.insertEdge(parent, null, new SrcDstAttribute(channel, dstRes), channelsOut.get(channel), resources.get((ResourceNode) dfEdge.getDestination()), "movable=false"); - } else { - // input edge - DataTransferChannel channel = ((ChannelNode) dfEdge.getDestination()).getChannel(); - ResourcePath srcRes = ((ResourceNode) dfEdge.getSource()).getOutSideResource(channel); - Set> toRes = getResourceDependencyForChannel(channel, model, dataFlowGraph); - for(Map.Entry RtoR: toRes) { - graph.insertEdge(parent, null, null, - resources.get(RtoR.getValue()), - resources.get(RtoR.getKey()), "dashed=true;movable=false"); - } - - graph.insertEdge(parent, null, new SrcDstAttribute(srcRes, channel), resources.get((ResourceNode) dfEdge.getSource()), channelsIn.get(channel), "movable=false"); - } - } - - for (Channel ch: model.getChannels()) { - // reference edges - DataTransferChannel channel = (DataTransferChannel) ch; - for (ResourcePath refRes: channel.getReferenceResources()) { - graph.insertEdge(parent, null, null, resources.get(dataFlowGraph.getResourceNode(refRes)), channelsIn.get(channel), "dashed=true;movable=false"); - } - } - } finally { - graph.getModel().endUpdate(); - } - setDAGLayout(); - - bReflectingArchitectureModel = false; - return graph; - } - - public void createChildResourceVerticies(Object resource, ResourceNode resNode, Map resources, int w, int h) { - - for (ResourceNode childNode: resNode.getChildren()) { - ResourcePath childRes = childNode.getPrimaryResourcePath(); - Object childResource = graph.insertVertex(resource, null, - childRes.getName(), 0, 0, w, h, - "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - resources.put(childNode, childResource); - createChildResourceVerticies(childResource, childNode, resources, w, h); - } - } - - public void setDAGLayout() { - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - DAGLayout ctl = new DAGLayout(graph); - ctl.execute(parent); - } finally { - graph.getModel().endUpdate(); - } - } - - public void updateEdgeAttiributes(DataFlowGraph dataFlowGraph) { - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - // add input, output and reference edges - for (Edge e : dataFlowGraph.getEdges()) { - if (e instanceof DataFlowEdge) { - DataFlowEdge dataFlow = (DataFlowEdge) e; - if (!dataFlow.isChannelToResource()) { - ResourceNode srcRes = (ResourceNode) dataFlow.getSource(); - DataTransferChannel channel = ((ChannelNode) dataFlow.getDestination()).getChannel(); - // input edge - for (Object edge: graph.getChildEdges(parent)) { - mxCell edgeCell = (mxCell) edge; - if (edgeCell.getValue() instanceof SrcDstAttribute) { - SrcDstAttribute edgeAttr = (SrcDstAttribute) edgeCell.getValue(); - if (srcRes.getPrimaryResourcePath().equals(edgeAttr.getSource()) && channel.equals(edgeAttr.getDestination())) { - edgeCell.setValue(dataFlow.getAttribute()); - break; - } - } - } - } - } - } - } finally { - graph.getModel().endUpdate(); - } - graph.refresh(); - } - - 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(); - } - } - - public ResourcePath addResourcePath(ResourcePath parentPath, String resName) { - ResourcePath resourcePath = null; - if (parentPath == null) { - resourcePath = new ResourcePath(resName); - getModel().addResourcePath(resourcePath); - } else { - if (resName.startsWith(Parser.LEFT_CURLY_BRACKET) && resName.endsWith(Parser.RIGHT_CURLY_BRACKET)) { - TokenStream stream = new Parser.TokenStream(); - Parser parser = new Parser(stream); - stream.addLine(resName.substring(1, resName.length() - 1)); - try { - Expression exp = parser.parseTerm(stream, getModel()); - resourcePath = new ResourcePath(parentPath, exp); - getModel().addResourcePath(resourcePath); - } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - return null; - } - } else { - resourcePath = new ResourcePath(parentPath, resName); - getModel().addResourcePath(resourcePath); - } - } - resetDataFlowGraph(); - graph.getModel().beginUpdate(); - Object parent = graph.getDefaultParent(); - try { - graph.insertVertex(parent, null, resName, 20, 20, 80, 30, - "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - } finally { - graph.getModel().endUpdate(); - } - return resourcePath; - } - - public void addChannel(DataTransferChannel channelGen) { - getModel().addChannel(channelGen); - resetDataFlowGraph(); - graph.getModel().beginUpdate(); - Object parent = graph.getDefaultParent(); - 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); - - 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 - 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 - } finally { - graph.getModel().endUpdate(); - } - } - - public void addIOChannel(DataTransferChannel ioChannelGen) { - getModel().addInputChannel(ioChannelGen); - resetDataFlowGraph(); - graph.getModel().beginUpdate(); - Object parent = graph.getDefaultParent(); - try { - mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo2.setRelative(true); - - 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 - } finally { - graph.getModel().endUpdate(); - } - } - - public void addFormulaChannel(FormulaChannel formulaChannelGen) { - getModel().addChannel(formulaChannelGen); - resetDataFlowGraph(); - graph.getModel().beginUpdate(); - Object parent = graph.getDefaultParent(); - 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); - - Object channel = graph.insertVertex(parent, null, formulaChannelGen.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 - 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 - } finally { - graph.getModel().endUpdate(); - } - } - - public boolean connectEdge(mxCell edge, mxCell src, mxCell dst) { - if (bReflectingArchitectureModel) return false; - DataTransferModel model = getModel(); - Channel srcCh = model.getChannel((String) src.getValue()); - if (srcCh == null) { - srcCh = model.getInputChannel((String) src.getValue()); - if (srcCh == null) { - ResourcePath srcRes = model.getResourcePath((String) src.getValue()); - Channel dstCh = model.getChannel((String) dst.getValue()); - if (srcRes == null || dstCh == null) return false; - // resource to channel edge - ChannelMember srcCm = new ChannelMember(srcRes); - ((DataTransferChannel ) dstCh).addChannelMemberAsInput(srcCm); - edge.setValue(new SrcDstAttribute(srcRes, dstCh)); - resetDataFlowGraph(); - return true; - } - } - ResourcePath dstRes = model.getResourcePath((String) dst.getValue()); - if (dstRes == null) return false; - // channel to resource edge - ChannelMember dstCm = new ChannelMember(dstRes); - ((DataTransferChannel) srcCh).addChannelMemberAsOutput(dstCm); - edge.setValue(new SrcDstAttribute(srcCh, dstRes)); - resetDataFlowGraph(); - return true; - } - - public void delete() { - for (Object obj: graph.getSelectionCells()) { - mxCell cell = (mxCell) obj; - if (cell.isEdge()) { - String srcName = (String) cell.getSource().getValue(); - String dstName = (String) cell.getTarget().getValue(); - if (model.getResourcePath(srcName) != null) { - // resource to channel edge - Channel ch = model.getChannel(dstName); - ch.removeChannelMember(model.getResourcePath(srcName)); - } else if (model.getResourcePath(dstName) != null) { - // channel to resource edge - Channel ch = model.getChannel(srcName); - if (ch == null) { - ch = model.getInputChannel(srcName); - } - ch.removeChannelMember(model.getResourcePath(dstName)); - } - } else if (cell.isVertex()) { - String name = (String) cell.getValue(); - if (model.getChannel(name) != null) { - model.removeChannel(name); - } else if (model.getInputChannel(name) != null) { - model.removeInputChannel(name); - } else if (model.getResourcePath(name) != null) { - model.removeResourcePath(name); - } - } - } - graph.removeCells(graph.getSelectionCells()); - resetDataFlowGraph(); - } - - public void setChannelCode(DataTransferChannel ch, String code) { - ch.setSourceText(code); - TokenStream stream = new Parser.TokenStream(); - Parser parser = new Parser(stream); - - for (String line: code.split("\n")) { - stream.addLine(line); - } - try { - DataTransferChannel ch2 = parser.parseChannel(getModel()); - for (ChannelMember chm2: ch2.getInputChannelMembers()) { - for (ChannelMember chm: ch.getInputChannelMembers()) { - if (chm2.getResource() == chm.getResource()) { - chm.setStateTransition(chm2.getStateTransition()); - break; - } - } - } - for (ChannelMember chm2: ch2.getOutputChannelMembers()) { - for (ChannelMember chm: ch.getOutputChannelMembers()) { - if (chm2.getResource() == chm.getResource()) { - chm.setStateTransition(chm2.getStateTransition()); - break; - } - } - } - for (ChannelMember chm2: ch2.getReferenceChannelMembers()) { - for (ChannelMember chm: ch.getReferenceChannelMembers()) { - if (chm2.getResource() == chm.getResource()) { - chm.setStateTransition(chm2.getStateTransition()); - break; - } - } - } - resetDataFlowGraph(); - } catch (ExpectedRightBracket | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket - | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression - | WrongLHSExpression | WrongRHSExpression | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - } - } + public void addFormulaChannel(FormulaChannel formulaChannelGen) { + // Force to change to data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).addFormulaChannel(formulaChannelGen); + model = curStage.getModel(); + } - public Set> getResourceDependencyForChannel(DataTransferChannel ch, DataTransferModel model, DataFlowGraph dataFlowGraph) { - Set> resourceDpendency = new HashSet<>(); - if (ch.getOutputChannelMembers().size() > 0) { - try { - Map>> dependency = ch.fillOutsideResourcePaths(ch.getOutputChannelMembers().iterator().next(), JavaCodeGenerator.pullAccessor); - for (ChannelMember srcMem: dependency.keySet()) { - ResourceNode srcNode = dataFlowGraph.getResourceNode(srcMem.getResource()); - if (srcNode != null) { - for (ChannelMember dstMem: dependency.get(srcMem).getValue()) { - ResourceNode dstNode = dataFlowGraph.getResourceNode(dstMem.getResource()); - while (srcNode.getResourceHierarchy().getNumParameters() == 0 && srcNode.getParent() != null) { - srcNode = srcNode.getParent(); - } - resourceDpendency.add(new AbstractMap.SimpleEntry<>(srcNode, dstNode)); - } - } - } - } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage - | UnificationFailed | ValueUndefined e) { - e.printStackTrace(); - } - } - return resourceDpendency; - } + public boolean connectEdge(mxCell edge, mxCell src, mxCell dst) { + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) { + return false; + } + return ((DataFlowModelingStage) curStage).connectEdge(edge, src, dst); + } - private class SrcDstAttribute extends EdgeAttribute { - private Object src; - private Object dst; + public static class SrcDstAttribute extends EdgeAttribute { + private final Object src; + private final Object dst; - public SrcDstAttribute(Object src, Object dst) { - this.src = src; - this.dst = dst; - } + public SrcDstAttribute(Object src, Object dst) { + this.src = src; + this.dst = dst; + } - public Object getSource() { - return src; - } + public Object getSource() { + return src; + } - public Object getDestination() { - return dst; - } + public Object getDestination() { + return dst; + } - public String toString() { - return ""; - } - } + public String toString() { + return ""; + } + } }