diff --git a/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java index e6d16e2..8d20abc 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java @@ -53,25 +53,6 @@ this.editor = new Editor(graphComponent); - graph.getModel().addListener(mxEvent.CHANGE, new mxIEventListener() { - public void invoke(Object sender, mxEventObject evt) { -// List terminals = new ArrayList<>(); -// mxCell cell = null; -// for (Object change: ((List) evt.getProperties().get("changes"))) { -// if (change instanceof mxGraphModel.mxTerminalChange) { -// mxGraphModel.mxTerminalChange terminalChange = (mxGraphModel.mxTerminalChange) change; -// cell = (mxCell) terminalChange.getCell(); -// mxCell terminal = (mxCell) terminalChange.getTerminal(); -// terminals.add(terminal); -// } -// } -// if (terminals.size() == 2) { -// if (!editor.connectEdge(cell, terminals.get(0), terminals.get(1))) { -// graph.removeCells(new mxCell[] {cell}); -// } -// } - } - }); getContentPane().add(graphComponent); new mxRubberband(graphComponent); graph.setAllowDanglingEdges(false); diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java index 9320731..d0475ca 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java @@ -13,6 +13,8 @@ import com.mxgraph.layout.mxCompactTreeLayout; import com.mxgraph.model.mxCell; import com.mxgraph.swing.mxGraphComponent; +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; @@ -53,6 +55,7 @@ public DataTransferModel model = null; public mxGraph graph = null; private mxGraphComponent graphComponent = null; + private mxIEventListener curChangeEventListener = null; protected Stage curStage = null; protected List stageQueue = null; @@ -116,6 +119,13 @@ if (!nextStage.canChangeFrom(curStage)) return false; nextStage.init(curStage); graphComponent.setCellEditor(nextStage.createCellEditor(graphComponent)); + if (curChangeEventListener != null) { + graph.getModel().removeListener(curChangeEventListener); + } + curChangeEventListener = nextStage.createChangeEventListener(this); + if (curChangeEventListener != null) { + graph.getModel().addListener(mxEvent.CHANGE, curChangeEventListener); + } curStage = nextStage; return true; } diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java index a154445..9f5e616 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java @@ -3,6 +3,7 @@ import com.mxgraph.model.mxCell; import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.swing.view.mxICellEditor; +import com.mxgraph.util.mxEventSource.mxIEventListener; import com.mxgraph.view.mxGraph; import models.dataFlowModel.DataTransferModel; @@ -37,7 +38,7 @@ abstract public boolean canChangeFrom(Stage prevStage); abstract public void init(Stage prevStage); abstract public mxICellEditor createCellEditor(mxGraphComponent graphComponent); - + abstract public mxIEventListener createChangeEventListener(Editor editor); /************************************************************* * [ *public ] diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java index 64360b3..a35a852 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java @@ -8,8 +8,10 @@ import com.mxgraph.model.mxGeometry; import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.util.mxPoint; +import com.mxgraph.util.mxEventSource.mxIEventListener; import com.mxgraph.view.mxGraph; +import application.editor.Editor; import application.editor.FlowCellEditor; import application.editor.Stage; import models.Edge; @@ -69,7 +71,7 @@ DataFlowGraph dataFlowGraph = ((PushPullSelectionStage) prevStage).getDataFlowGraph(); - controlFlowGraph = new ControlFlowGraph(dataFlowGraph); + controlFlowGraph = new ControlFlowGraph(dataFlowGraph, model); graph = clearControlFlowGraphCells(graph); graph = constructGraph(graph, controlFlowGraph); @@ -83,6 +85,11 @@ public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { return new ControlFlowDelegationCellEditor(this, graphComponent); } + + @Override + public mxIEventListener createChangeEventListener(Editor editor) { + return null; + } /************************************************************* * @@ -298,15 +305,18 @@ Map pullResNodeCells = createCellsOfResourceMap(graph, PULL_FLOW_LAYER, controlFlowGraph); // Creating Entry-Point Object - // Map channelsIn = createCellsOfInputChannel(graph, CONTROL_FLOW_LAYER, controlFlowGraph, controlFlowNodeCells); + Map controlFlowEntryNodeCells = createCellsOfInputChannel(graph, CONTROL_FLOW_LAYER, controlFlowGraph, controlFlowNodeCells); + Map pushFlowEntryNodeCells = createCellsOfInputChannel(graph, CONTROL_FLOW_LAYER, controlFlowGraph, controlFlowNodeCells); // Inserting edges of each transfer - graph = insertControlFlowEdges(graph, PUSH_FLOW_LAYER, controlFlowGraph.getPushCallGraph(), pushResNodeCells); - graph = insertControlFlowEdges(graph, PULL_FLOW_LAYER, controlFlowGraph.getPullCallGraph(), pullResNodeCells); + graph = insertControlFlowEdges(graph, PUSH_FLOW_LAYER, controlFlowGraph.getPushCallGraph(), pushResNodeCells, pushFlowEntryNodeCells); + graph = insertControlFlowEdges(graph, PULL_FLOW_LAYER, controlFlowGraph.getPullCallGraph(), pullResNodeCells, null); // Inserting edges of both Push and Pull transfer - graph = insertControlFlowEdges(graph, CONTROL_FLOW_LAYER, controlFlowGraph.getPushCallGraph(),controlFlowNodeCells); - graph = insertControlFlowEdges(graph, CONTROL_FLOW_LAYER, controlFlowGraph.getPullCallGraph(),controlFlowNodeCells); + graph = insertControlFlowEdges(graph, CONTROL_FLOW_LAYER, controlFlowGraph.getPushCallGraph(),controlFlowNodeCells, controlFlowEntryNodeCells); + graph = insertControlFlowEdges(graph, CONTROL_FLOW_LAYER, controlFlowGraph.getPullCallGraph(),controlFlowNodeCells, controlFlowEntryNodeCells); + + } finally { graph.getModel().endUpdate(); @@ -407,8 +417,9 @@ * Createing an input channel object */ private Map createCellsOfInputChannel(mxGraph graph, final int layerNumber, final ControlFlowGraph controlGraph, final Map resNodeCell){ + if(layerNumber == PULL_FLOW_LAYER) return null; + mxCell root = (mxCell)graph.getDefaultParent(); -// mxCell nodeLayerCell = (mxCell)root.getChildAt(NODE_LAYER); mxCell layerCell = (mxCell)root.getChildAt(layerNumber); Map ioChannelCells = new HashMap<>(); @@ -418,30 +429,22 @@ mxGeometry outPortGeometry = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); outPortGeometry.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); outPortGeometry.setRelative(true); + + CallGraph callGraph = controlFlowGraph.getPushCallGraph(); // insert an I/O channel as a vertex - for (ChannelGenerator ioChannelGen: model.getIOChannelGenerators()) { - Object channel = graph.insertVertex(layerCell, null, ioChannelGen.getChannelName(), 150, 20, 30, 30); + for (Node node : callGraph.getNodes()) { + EntryPointObjectNode entryPointObjNode = null; + if(node instanceof EntryPointObjectNode) + entryPointObjNode = (EntryPointObjectNode)node; + else continue; + + ObjectNodeAttribute entryObjAttr = new ObjectNodeAttribute(entryPointObjNode); + + mxCell channel = (mxCell)graph.insertVertex(layerCell, null, entryObjAttr, 150, 20, 30, 30); mxCell port_out = new mxCell(null, outPortGeometry, "shape=ellipse;perimter=ellipsePerimeter"); port_out.setVertex(true); graph.addCell(port_out, channel); // insert the output port of a channel - - EntryPointObjectNode entryPointObjNode = new EntryPointObjectNode(ioChannelGen.getChannelName()); - CallGraph callGraph = null; - if(layerNumber == PUSH_FLOW_LAYER) { - callGraph = controlFlowGraph.getPushCallGraph(); - for (Node node : callGraph.getNodes()) { - StatefulObjectNode statefulObjNode = (StatefulObjectNode)node; - if( !ioChannelGen.getIdentifierTemplates().contains(statefulObjNode.getResource().getIdentifierTemplate())) - continue; -// controlFlowGraph.getPushCallGraph().addNode(entryPointObjNode); -// controlFlowGraph.getPushCallGraph().addEdge(entryPointObjNode, statefulObjectNode, PushPullValue.PUSH); - - - graph.insertEdge(layerCell, null, null, port_out, resNodeCell.get(statefulObjNode), "movable=false;strokeColor=#FF0000"); - } - - } ioChannelCells.put(entryPointObjNode, port_out); } } @@ -455,7 +458,7 @@ /************************************************************* * When changed from previous stage, it will be called in initializing. */ - private mxGraph insertControlFlowEdges(mxGraph graph, final int layerNumber, final CallGraph callGraph ,final Map resNodeCells) { + private mxGraph insertControlFlowEdges(mxGraph graph, final int layerNumber, final CallGraph callGraph ,final Map resNodeCells, final Map entryNodeCells) { mxCell root = (mxCell)graph.getDefaultParent(); mxCell layerCell = (mxCell)root.getChildAt(layerNumber); @@ -466,11 +469,21 @@ // Is checking node connecting a resource? if(callEdge.getSource() == null || callEdge.getDestination() == null) continue; - ResourceNode srcResNode = ((StatefulObjectNode)callEdge.getSource()).getResource(); + Node srcResNode = null; ResourceNode dstResNode = ((StatefulObjectNode)callEdge.getDestination()).getResource(); - mxCell srcNodeCell =resNodeCells.get(srcResNode); + mxCell srcNodeCell =null; mxCell dstNodeCell = resNodeCells.get(dstResNode); + + if(callEdge.getSource() instanceof StatefulObjectNode) { + srcResNode = ((StatefulObjectNode)callEdge.getSource()).getResource(); + srcNodeCell =resNodeCells.get(srcResNode); + } + else if (callEdge.getSource() instanceof EntryPointObjectNode) { + srcResNode = (EntryPointObjectNode)callEdge.getSource(); + srcNodeCell = entryNodeCells.get(srcResNode); + } + else continue; if(srcNodeCell == null || dstNodeCell == null) continue; diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java index d9628a8..100de3d 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java @@ -1,16 +1,21 @@ package application.editor.stages; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGeometry; import com.mxgraph.model.mxGraphModel; import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxEventSource.mxIEventListener; +import com.mxgraph.util.mxEventObject; import com.mxgraph.util.mxPoint; import com.mxgraph.view.mxGraph; import algorithms.Validation; +import application.editor.Editor; import application.editor.Editor.SrcDstAttribute; import application.editor.FlowCellEditor; import application.editor.Stage; @@ -77,6 +82,29 @@ public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { return new DataFlowCellEditor(this, graphComponent); } + + @Override + public mxIEventListener createChangeEventListener(Editor editor) { + return new mxIEventListener() { + public void invoke(Object sender, mxEventObject evt) { + List terminals = new ArrayList<>(); + mxCell cell = null; + for (Object change: ((List) evt.getProperties().get("changes"))) { + if (change instanceof mxGraphModel.mxTerminalChange) { + mxGraphModel.mxTerminalChange terminalChange = (mxGraphModel.mxTerminalChange) change; + cell = (mxCell) terminalChange.getCell(); + mxCell terminal = (mxCell) terminalChange.getTerminal(); + terminals.add(terminal); + } + } + if (terminals.size() == 2) { + if (!editor.connectEdge(cell, terminals.get(0), terminals.get(1))) { + graph.removeCells(new mxCell[] {cell}); + } + } + } + }; + } /************************************************************* * diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java index 6224fd9..dedf31d 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java @@ -1,11 +1,18 @@ package application.editor.stages; +import java.util.ArrayList; +import java.util.List; + import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGraphModel; import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxEventObject; +import com.mxgraph.util.mxEventSource.mxIEventListener; import com.mxgraph.view.mxGraph; import algorithms.DataTransferModelAnalyzer; import application.editor.Editor.SrcDstAttribute; +import application.editor.Editor; import application.editor.FlowCellEditor; import application.editor.InEdgeAttribute; import application.editor.OutEdgeAttribute; @@ -53,6 +60,28 @@ return new PushPullSelectionCellEditor(this, graphComponent); } + @Override + public mxIEventListener createChangeEventListener(Editor editor) { + return new mxIEventListener() { + public void invoke(Object sender, mxEventObject evt) { + List terminals = new ArrayList<>(); + mxCell cell = null; + for (Object change: ((List) evt.getProperties().get("changes"))) { + if (change instanceof mxGraphModel.mxTerminalChange) { + mxGraphModel.mxTerminalChange terminalChange = (mxGraphModel.mxTerminalChange) change; + cell = (mxCell) terminalChange.getCell(); + mxCell terminal = (mxCell) terminalChange.getTerminal(); + terminals.add(terminal); + } + } + if (terminals.size() == 2) { + // cancel connect + graph.removeCells(new mxCell[] {cell}); + } + } + }; + } + public DataFlowGraph getDataFlowGraph() { return dataFlowGraph; } diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java index 0830a1e..0ebaaa2 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java @@ -1,8 +1,15 @@ package models.controlFlowModel; import models.Edge; +import models.algebra.Expression; +import models.algebra.Term; +import models.algebra.Variable; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; import models.dataFlowModel.DataFlowEdge; import models.dataFlowModel.DataFlowGraph; +import models.dataFlowModel.DataTransferChannelGenerator; +import models.dataFlowModel.DataTransferModel; import models.dataFlowModel.PushPullAttribute; import models.dataFlowModel.PushPullValue; import models.dataFlowModel.ResourceNode; @@ -12,7 +19,7 @@ private CallGraph pushCallGraph; private CallGraph pullCallGraph; - public ControlFlowGraph(DataFlowGraph dataFlowGraph) { + public ControlFlowGraph(DataFlowGraph dataFlowGraph, DataTransferModel model) { this.dataFlowGraph = dataFlowGraph; this.pushCallGraph = new CallGraph(); this.pullCallGraph = new CallGraph(); @@ -28,6 +35,28 @@ pullCallGraph.addEdge(dstNode, srcNode, PushPullValue.PULL); } } + for (ChannelGenerator ch: model.getIOChannelGenerators()) { + DataTransferChannelGenerator cio = (DataTransferChannelGenerator) ch; + EntryPointObjectNode srcNode = new EntryPointObjectNode(cio); + for (ChannelMember cm: cio.getChannelMembers()) { + if (srcNode.getName() == null) { + Expression exp = cm.getStateTransition().getMessageExpression(); + if (exp instanceof Term) { + srcNode.setName(((Term) exp).getSymbol().getName()); + } else if (exp instanceof Variable) { + srcNode.setName(((Variable) exp).getName()); + } + } + ResourceNode dstResNode = dataFlowGraph.getResouceNode(cm.getIdentifierTemplate()); + StatefulObjectNode dstNode = pushCallGraph.getStatefulObjectNode(dstResNode); + if (dstNode == null) { + pushCallGraph.addNode(dstResNode); + dstNode = pushCallGraph.getStatefulObjectNode(dstResNode); + } + // from an I/O channel to a resource + pushCallGraph.insertEdge(srcNode, dstNode, PushPullValue.PUSH, 0); + } + } } public ControlFlowGraph(DataFlowGraph dataFlowGraph, PushPullValue priority) { diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java index 498d064..f200312 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java @@ -1,18 +1,27 @@ package models.controlFlowModel; +import models.dataFlowModel.DataTransferChannelGenerator; + /************************************************************* * An object is mapped to I/O channel. * ToDo: Fecthing name from in Data-Flow-Graph */ public class EntryPointObjectNode extends ObjectNode { + DataTransferChannelGenerator ioChannelGenerator = null; /************************************************************* * [ *constructor ] /************************************************************* * */ - public EntryPointObjectNode(String name) { + public EntryPointObjectNode(DataTransferChannelGenerator ioChannelGenerator) { + super(null); + this.ioChannelGenerator = ioChannelGenerator; + } + + public EntryPointObjectNode(String name, DataTransferChannelGenerator ioChannelGenerator) { super(name); + this.ioChannelGenerator = ioChannelGenerator; } /************************************************************* @@ -20,6 +29,12 @@ /************************************************************* * */ - + public DataTransferChannelGenerator getIoChannelGenerator() { + return ioChannelGenerator; + } + public void setIoChannelGenerator(DataTransferChannelGenerator ioChannelGenerator) { + this.ioChannelGenerator = ioChannelGenerator; + } + }