diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java index 6fe7965..69047fa 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java @@ -1,5 +1,6 @@ package application.editor; +import java.awt.event.MouseListener; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; @@ -18,6 +19,8 @@ import java.util.Map.Entry; import java.util.Set; +import application.editor.stages.DataFlowModelingStage; +import application.editor.stages.PushPullSelectionStage; import com.mxgraph.layout.mxCircleLayout; import com.mxgraph.layout.mxCompactTreeLayout; import com.mxgraph.model.mxCell; @@ -26,10 +29,8 @@ import com.mxgraph.model.mxICell; import com.mxgraph.model.mxIGraphModel; import com.mxgraph.swing.mxGraphComponent; -import com.mxgraph.util.mxConstants; -import com.mxgraph.util.mxPoint; +import com.mxgraph.util.*; import com.mxgraph.view.mxCellState; -import com.mxgraph.util.mxRectangle; import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxGraphView; @@ -96,17 +97,33 @@ protected DataFlowGraph dataFlowGraph = null; + protected Stage curStage = null; + private List stageChangeListeners = null; + + private mxEventSource.mxIEventListener curChangeEventListener = null; + private MouseListener curMouseEventListener = 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; + private boolean bReflectingArchitectureModel = false; public Editor(mxGraphComponent graphComponent) { this.graphComponent = graphComponent; this.graph = graphComponent.getGraph(); - - graphComponent.setCellEditor(new DataTransferModelingCellEditor(graphComponent, this)); + + STAGE_DATA_FLOW_MODELING = new DataFlowModelingStage(graphComponent); + STAGE_PUSH_PULL_SELECTION = new PushPullSelectionStage(graphComponent); + + graphComponent.setCellEditor(STAGE_DATA_FLOW_MODELING.createCellEditor(graphComponent)); + + curStage = STAGE_DATA_FLOW_MODELING; + + stageChangeListeners = new ArrayList<>(); } public mxGraph getGraph() { @@ -124,6 +141,52 @@ return model; } + public Stage getCurStage() { + return curStage; + } + + public boolean canChange(Stage nextStage) { + return nextStage.canChangeFrom(curStage); + } + + public boolean changeStage(Stage nextStage) { + if (!nextStage.canChangeFrom(curStage)) return false; + nextStage.init(curStage); + graphComponent.setCellEditor(nextStage.createCellEditor(graphComponent)); + + // add listeners + // "curChangeEventListener" will be called when updating the mxGraph. + if (curChangeEventListener != null) { + graph.getModel().removeListener(curChangeEventListener); + } + curChangeEventListener = nextStage.createChangeEventListener(this); + if (curChangeEventListener != null) { + graph.getModel().addListener(mxEvent.CHANGE, curChangeEventListener); + } + + // A handler of a mouse event. + if(curMouseEventListener != null) { + graphComponent.getGraphControl().removeMouseListener(curMouseEventListener); + } + curMouseEventListener = nextStage.createMouseEventListener(this); + if(curMouseEventListener != null) { + graphComponent.getGraphControl().addMouseListener(curMouseEventListener); + } + curStage = nextStage; + notifyStageChangeListeners(); + return true; + } + + public void addStageChangeListener(IStageChangeListener stageChangeListener) { + stageChangeListeners.add(stageChangeListener); + } + + private void notifyStageChangeListeners() { + for (IStageChangeListener l: stageChangeListeners) { + l.stageChanged(curStage); + } + } + public DataFlowGraph getDataFlowGraph() { if (dataFlowGraph == null) { analyzeDataTransferModel(getModel()); @@ -196,26 +259,26 @@ openModel(file); } else { ParserDTRAM parserDTRAM = new ParserDTRAM(new BufferedReader(new FileReader(file))); - try { + try { // Parse the .dtram file. model = parserDTRAM.doParseModel(); - + // Analyze the model. if (!Validation.checkUpdateConflict(model)) return null; DataFlowGraph dataFlowGraph = analyzeDataTransferModel(model); - + // Visualize the model. graph = constructGraph(model, dataFlowGraph); parserDTRAM.doParseGeometry(graph); updateEdgeAttiributes(dataFlowGraph); - + 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 + | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedModel + | ExpectedGeometry | ExpectedNode | ExpectedResource | ExpectedFormulaChannel | ExpectedIoChannel | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { e.printStackTrace(); } @@ -232,21 +295,21 @@ Parser parser = new Parser(new BufferedReader(new FileReader(file))); - try { + try { // Parse the .model file. model = parser.doParse(); - + // Analyze the model. if (!Validation.checkUpdateConflict(model)) return null; DataFlowGraph dataFlowGraph = analyzeDataTransferModel(model); - + // Visualize the model. graph = constructGraph(model, dataFlowGraph); updateEdgeAttiributes(dataFlowGraph); - + // Set DAG layout. // setDAGLayout(); - + curFilePath = file.getAbsolutePath(); curFileName = file.getName(); return model; @@ -264,7 +327,7 @@ /**-------------------------------------------------------------------------------- * save /**-------------------------------------------------------------------------------- - * + * */ public void save() { if (curFilePath != null) { @@ -281,7 +344,7 @@ if(extension.contains(".model")) { saveModel(file); } else { - FileWriter filewriter = new FileWriter(file); + FileWriter filewriter = new FileWriter(file); filewriter.write(toOutputString()); filewriter.close(); } @@ -294,7 +357,7 @@ public void saveModel(File file) { if (curFilePath != null) { try { - FileWriter filewriter = new FileWriter(file); + FileWriter filewriter = new FileWriter(file); filewriter.write(model.getSourceText()); filewriter.close(); } catch (IOException e) { @@ -305,12 +368,12 @@ /**-------------------------------------------------------------------------------- * get writing texts "dtram" file information is written. - * + * * @return formatted "dtram" info texts. */ protected String toOutputString() { String fileString = ""; - + fileString += "model {\n"; fileString += this.model.getSourceText(); fileString += "}\n"; @@ -330,7 +393,7 @@ for(Channel ch: model.getChannels()) { if(ch instanceof FormulaChannel && state.getLabel().equals(ch.getChannelName())) { - fileString += "\tnode fc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; + 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"; } @@ -347,16 +410,16 @@ } } } - } + } fileString += "}\n"; - + return fileString; } - + /** * Construct a mxGraph from DataFlowModel and DataFlowModel * @param model - * @param dataFlowGraph + * @param dataFlowGraph * @return constructed mxGraph */ public mxGraph constructGraph(DataTransferModel model, DataFlowGraph dataFlowGraph) { @@ -388,7 +451,7 @@ resources.put(resNode, resource); createChildResourceVerticies(resource, resNode, resources, w, h); } - + // create channel vertices for (ChannelNode c: dataFlowGraph.getRootChannelNodes()) { DataTransferChannel channel = (DataTransferChannel) c.getChannel(); @@ -408,7 +471,7 @@ } else { for (Selector s: channel.getSelectors()) { Expression exp = s.getExpression(); - String selName = exp.toString(); + 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 @@ -456,7 +519,7 @@ } } } - + // add input, output and reference edges for (Edge edge: dataFlowGraph.getEdges()) { DataFlowEdge dfEdge = (DataFlowEdge) edge; @@ -467,19 +530,19 @@ 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(); + 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.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; @@ -491,13 +554,13 @@ 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, @@ -507,7 +570,7 @@ createChildResourceVerticies(childResource, childNode, resources, w, h); } } - + public void setDAGLayout() { Object parent = graph.getDefaultParent(); graph.getModel().beginUpdate(); @@ -746,7 +809,7 @@ ch.setSourceText(code); TokenStream stream = new Parser.TokenStream(); Parser parser = new Parser(stream); - + for (String line: code.split("\n")) { stream.addLine(line); } @@ -783,7 +846,7 @@ e.printStackTrace(); } } - + public Set> getResourceDependencyForChannel(DataTransferChannel ch, DataTransferModel model, DataFlowGraph dataFlowGraph) { Set> resourceDpendency = new HashSet<>(); if (ch.getOutputChannelMembers().size() > 0) {