diff --git a/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java b/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java index 0385b05..039c4bd 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java @@ -18,6 +18,7 @@ import application.actions.SaveAction; import application.actions.SaveAsAction; import application.actions.ShowNavigationAction; +import application.actions.ShowSwitchLayerWindowAction; import application.actions.TreeLayoutAction; import application.actions.ZoomInAction; import application.actions.ZoomOutAction; @@ -78,6 +79,7 @@ menu = add(new JMenu("Window")); menu.add(new ShowNavigationAction(applicationWindow)); + menu.add(new ShowSwitchLayerWindowAction(applicationWindow)); } public Editor getEditor() { diff --git a/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java index 2651c23..bd82ef3 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java @@ -19,17 +19,19 @@ import application.editor.Editor; import application.editor.stages.DataFlowCellEditor; import application.views.NavigationWindow; +import application.views.SwitchDisplayFlowWindow; public class ApplicationWindow extends JFrame { private static final long serialVersionUID = -8690140317781055614L; public static final String title = "Visual Modeling Tool"; - private Editor editor; - private mxGraph graph; - private mxGraphComponent graphComponent; + private Editor editor = null; + private mxGraph graph = null; + private mxGraphComponent graphComponent = null; - private ApplicationMenuBar menuBar; - private NavigationWindow navigationWindow; + private ApplicationMenuBar menuBar = null; + private NavigationWindow navigationWindow = null; + private SwitchDisplayFlowWindow switchDisplayFlowWindow = null; public ApplicationWindow() { setTitle(title); @@ -81,6 +83,10 @@ navigationWindow = new NavigationWindow(this, editor); navigationWindow.setVisible(true); + + switchDisplayFlowWindow = new SwitchDisplayFlowWindow(this, editor); + switchDisplayFlowWindow.setVisible(false); + editor.addStageChangeListener(navigationWindow); } @@ -103,5 +109,9 @@ public void showNavigationWindow() { navigationWindow.setVisible(true); } + + public void showSwitchLayerWindow() { + switchDisplayFlowWindow.setVisible(true); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/ShowSwitchLayerWindowAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowSwitchLayerWindowAction.java new file mode 100644 index 0000000..58019dd --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowSwitchLayerWindowAction.java @@ -0,0 +1,16 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.ApplicationWindow; + +public class ShowSwitchLayerWindowAction extends AbstractSystemAction { + public ShowSwitchLayerWindowAction(ApplicationWindow frame) { + super("Switch Layer", frame); + } + + @Override + public void actionPerformed(ActionEvent e) { + frame.showSwitchLayerWindow(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java index a9bd803..dd56bda 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java @@ -1,21 +1,26 @@ package application.editor.stages; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.util.EventObject; -import java.util.List; + +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; import com.mxgraph.model.mxCell; import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.swing.mxGraphComponent.mxGraphControl; import application.editor.FlowCellEditor; import models.controlFlowModel.CallEdgeAttribute; -import models.controlFlowModel.ControlFlowDelegator; -import models.controlFlowModel.ObjectNode; -import models.controlFlowModel.ObjectNodeAttribute; -import models.dataFlowModel.PushPullValue; +/************************************************************* + * + */ public class ControlFlowDelegationCellEditor extends FlowCellEditor { - private ControlFlowDelegationStageStatus curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; + private ControlFlowDelegationStageStatus curState = null; /************************************************************* * [ *constructor ] @@ -25,6 +30,18 @@ */ public ControlFlowDelegationCellEditor(ControlFlowDelegationStage stage, mxGraphComponent graphComponent) { super(stage, graphComponent); + curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; + + // If required handlers have already resistered, + // then remove them before each add. + mxGraphControl graphControl = graphComponent.getGraphControl(); + for(MouseListener listener : graphControl.getMouseListeners()) { + if(listener instanceof InsertObjectNodeAction) + graphControl.removeMouseListener(listener); + } + + // Adding handlers + graphControl.addMouseListener(new InsertObjectNodeAction()); } /************************************************************* @@ -35,19 +52,21 @@ @Override public void startEditing(Object cellObj, EventObject eventObj) { if( editingCell != null) stopEditing(true); - + switch(curState) { case SELECTING_AN_EDGE: if( graphComponent.getGraph().getModel().isEdge(cellObj) ) { System.out.println("Selecting"); - CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)graphComponent.getGraph().getModel().getValue(cellObj); - + + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)graphComponent.getGraph().getModel().getValue(cellObj); if(callEdgeAttr == null) return; + System.out.println("Edge: " + callEdgeAttr.getSelectedOption().name()); - showDelegatableArea(callEdgeAttr); - + ((ControlFlowDelegationStage)stage).showDelegatableNodes(callEdgeAttr); + + // Advance to the next stage; curState = ControlFlowDelegationStageStatus.SHOWING_DELEGATABLE_NODES; } break; @@ -59,7 +78,7 @@ } else { System.out.println("cancel showing state."); - resetGraph(); + ((ControlFlowDelegationStage)stage). resetGraph(); curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; } break; @@ -73,70 +92,33 @@ public void stopEditing(boolean cancel) { } - - /************************************************************* - * [ *private ] - /************************************************************* - * - */ - private void showDelegatableArea(final CallEdgeAttribute callEdgeAttr) { - mxCell root = (mxCell)graphComponent.getGraph().getDefaultParent(); - mxCell controlGraphLayer = (mxCell)root.getChildAt(stage.CONTROL_FLOW_LAYER); - - List delegatableNodes = ((ControlFlowDelegationStage)stage).getDelegatableNodes(callEdgeAttr.getCallEdge()); - - graphComponent.getGraph().getModel().beginUpdate(); - try { - ObjectNode delegatingNode = callEdgeAttr.getSelectedOption().equals(PushPullValue.PUSH) - ? callEdgeAttr.getSourceObjectNode() - : callEdgeAttr.getDestinationObjectNode(); + /************************************************************* + * Inserting an intermediation object type of . + */ + private class InsertObjectNodeAction extends MouseAdapter { + @Override + public void mouseReleased(MouseEvent e) { + // if the right mouse button was clicked, + // then pop up the dialog name to insert a mediator-object. + if( !curState.equals(ControlFlowDelegationStageStatus.SELECTING_AN_EDGE)) return; + if( !SwingUtilities.isRightMouseButton(e) )return; - for(Object node : graphComponent.getGraph().getChildVertices(controlGraphLayer)) { - if( !(node instanceof mxCell) ) continue; - mxCell cell = (mxCell)node; + Object cellObj = graphComponent.getCellAt(e.getX(), e.getY()); + if(cellObj == null) return; - ObjectNodeAttribute objNodeAttr = (ObjectNodeAttribute)cell.getValue(); - if(objNodeAttr == null) throw new NullPointerException(""); - - ObjectNode objNode = objNodeAttr.getObjectNode(); - if(delegatableNodes.contains(objNode)) // enable - graphComponent.getGraph().getModel().setStyle(cell, objNodeAttr.getEnableStyle()); - else // disable - graphComponent.getGraph().getModel().setStyle(cell, objNodeAttr.getDisableStyle()); - - // base-Node - if(delegatingNode.equals(objNodeAttr.getObjectNode())) - graphComponent.getGraph().getModel().setStyle(cell, objNodeAttr.getDefaultStyle()); - } - } - finally { - graphComponent.getGraph().getModel().endUpdate(); + mxCell edgeCell = null; + if(cellObj instanceof mxCell) edgeCell = (mxCell)cellObj; + else return; + + curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; + + // Inputing name to the dialog. + String objName = JOptionPane.showInputDialog("Object Name:"); + if(objName == null) return; + + ((ControlFlowDelegationStage)stage) + .insertObjectNodeCellInControlFlowLayer(graphComponent.getGraph(), edgeCell, objName); } } - - /************************************************************* - * - */ - private void resetGraph() { - mxCell root = (mxCell)graphComponent.getGraph().getDefaultParent(); - mxCell controlGraphLayer = (mxCell)root.getChildAt(stage.CONTROL_FLOW_LAYER); - - graphComponent.getGraph().getModel().beginUpdate(); - - try { - for(Object node : graphComponent.getGraph().getChildVertices(controlGraphLayer)) { - if( !(node instanceof mxCell) ) continue; - mxCell cell = (mxCell)node; - ObjectNodeAttribute objNodeAttr = (ObjectNodeAttribute)cell.getValue(); - if(objNodeAttr == null) throw new NullPointerException(""); - - graphComponent.getGraph().getModel().setStyle(cell, objNodeAttr.getDefaultStyle()); - } - } - finally { - graphComponent.getGraph().getModel().endUpdate(); - } - } - } diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java index aec3621..78243fc 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java @@ -19,17 +19,21 @@ import models.controlFlowModel.ObjectNode; import models.controlFlowModel.ObjectNodeAttribute; import models.controlFlowModel.StatefulObjectNode; -import models.dataConstraintModel.IdentifierTemplate; import models.dataFlowModel.DataFlowGraph; +import models.dataFlowModel.PushPullValue; import models.dataFlowModel.ResourceNode; import models.dataFlowModel.ResourceNodeAttribute; +/************************************************************* + * + * @author k-fujii + */ public class ControlFlowDelegationStage extends Stage { public final int PORT_DIAMETER = 8; public final int PORT_RADIUS = PORT_DIAMETER / 2; private ControlFlowGraph controlFlowGraph = null; - + /************************************************************* * [ *constructor ] /************************************************************* @@ -63,18 +67,16 @@ model = ((PushPullSelectionStage) prevStage).getModel(); DataFlowGraph dataFlowGraph = ((PushPullSelectionStage) prevStage).getDataFlowGraph(); - controlFlowGraph = new ControlFlowGraph(dataFlowGraph); - + + controlFlowGraph = new ControlFlowGraph(dataFlowGraph); + graph = clearControlFlowGraphCells(graph); graph = constructGraph(graph, controlFlowGraph); - - // First, a mouse-event is "Showing delegatable Objects". } } /************************************************************* * - * @return */ @Override public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { @@ -83,39 +85,178 @@ /************************************************************* * + * Todo: PUSH/PULLレイヤーへの対応 */ - public List getDelegatableNodes(final CallEdge callEdge){ - ControlFlowDelegator delegator = new ControlFlowDelegator(controlFlowGraph); - return delegator.searchDelegatableNodes(callEdge); + public void showDelegatableNodes(final CallEdgeAttribute callEdgeAttribute){ + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell controlGraphLayer = (mxCell)root.getChildAt(CONTROL_FLOW_LAYER); + + graph.getModel().beginUpdate(); + try { + ObjectNode delegatingNode = callEdgeAttribute.getDestinationObjectNode(); + + for(Object node : graph.getChildVertices(controlGraphLayer)) { + if( !(node instanceof mxCell) ) continue; + mxCell cell = (mxCell)node; + + ObjectNodeAttribute objNodeAttr = (ObjectNodeAttribute)cell.getValue(); + if(objNodeAttr == null) return; + + ObjectNode objNode = objNodeAttr.getObjectNode(); + ControlFlowDelegator delegator = new ControlFlowDelegator(controlFlowGraph); + List delegatableNodes = delegator.searchDelegatableNodes(callEdgeAttribute.getCallEdge()); + + if(delegatableNodes.contains(objNode)) // enable + graph.getModel().setStyle(cell, objNodeAttr.getEnableStyle()); + else // disable + graph.getModel().setStyle(cell, objNodeAttr.getDisableStyle()); + + + // base-Node + if(delegatingNode.equals(objNodeAttr.getObjectNode())) + graph.getModel().setStyle(cell, objNodeAttr.getDelegatingStyle()); + } + } + finally { + graph.getModel().endUpdate(); + } } + /************************************************************* + * + */ + public void resetGraph() { + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell controlGraphLayer = (mxCell)root.getChildAt(CONTROL_FLOW_LAYER); + + graph.getModel().beginUpdate(); + + try { + for(Object node : graph.getChildVertices(controlGraphLayer)) { + + mxCell cell = null; + if(node instanceof mxCell) cell = (mxCell)node; + else continue; + + ObjectNodeAttribute objNodeAttr = null; + if(cell.getValue() instanceof ObjectNodeAttribute) + objNodeAttr = (ObjectNodeAttribute) cell.getValue(); + else throw new NullPointerException(""); + + graph.getModel().setStyle(cell, objNodeAttr.getDefaultStyle()); + } + } + finally { + graph.getModel().endUpdate(); + } + } /************************************************************* + * Inserting an intermediation object type of . + */ + public void insertObjectNodeCellInControlFlowLayer(mxGraph graph, mxCell targetEdge, final String insertObjName) { + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell contorlLayerCell = (mxCell)root.getChildAt(CONTROL_FLOW_LAYER); + + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)targetEdge.getValue(); + if(callEdgeAttr == null) throw new NullPointerException(); + + graph.getModel().beginUpdate(); + + try { + // Inserting the node type of to the graph. + ObjectNode insertObjNode = new ObjectNode(insertObjName); + ObjectNodeAttribute objNodeAttr = new ObjectNodeAttribute(insertObjNode); + mxCell insertObjNodeCell = (mxCell)graph.insertVertex(contorlLayerCell, null, objNodeAttr, 20, 20, 40, 40, objNodeAttr.getDefaultStyle()); + + insertObjNodeCell.setValue(objNodeAttr); + + addObjectNodeToCallGraphl(insertObjNode, callEdgeAttr.getSelectedOption()); + + // Reconnecting each edges of the node. + ObjectNode srcObjNode = callEdgeAttr.getSourceObjectNode(); + ObjectNode dstObjNode = callEdgeAttr.getDestinationObjectNode(); + if(srcObjNode == null || dstObjNode == null) throw new NullPointerException(); + if(!(srcObjNode instanceof ObjectNode && dstObjNode instanceof ObjectNode)) throw new ClassCastException(); + + // Connecting I/O Edges to the insert object. + CallEdge srcToInsertEdge = callEdgeAttr.getCallEdge(); + CallEdge insertToDstEdge = new CallEdge(insertObjNode, dstObjNode, callEdgeAttr.getSelectedOption()); + + srcToInsertEdge.setDestination(insertObjNode); // changing the out of edge of the sourceObjectNode + + if(srcToInsertEdge == null || insertToDstEdge == null) throw new NullPointerException(); + + insertObjNode.addInEdge(srcToInsertEdge); + insertObjNode.addOutEdge(insertToDstEdge); + + for(int i =0; i < contorlLayerCell.getChildCount(); i++) { + mxCell nodeCell = (mxCell)contorlLayerCell.getChildAt(i); + if( !nodeCell.isVertex()) continue; + + // Checking "nodeCell" has an instance of + ObjectNodeAttribute cellObjNodeAttr = (ObjectNodeAttribute)nodeCell.getValue(); + if(cellObjNodeAttr == null) throw new ClassCastException("dosen't have the value of "); + + // Getting the cell + + // Is "nodeCell" the same as the source cell of the call edge? + if(nodeCell.equals(callEdgeAttr.getSourceCell())){ + mxCell srcNodeCell = callEdgeAttr.getSourceCell(); + CallEdgeAttribute newInEdgeAttr = new CallEdgeAttribute(srcToInsertEdge, srcNodeCell, insertObjNodeCell); + + // If the target call edge hasn't removed yet. + // then it removes from mxGraphModel. + if(graph.getModel().getValue(targetEdge) == null) return; + graph.getModel().remove(targetEdge); + + graph.insertEdge(contorlLayerCell, null, newInEdgeAttr, srcNodeCell, insertObjNodeCell, "movable=false;"); + + continue; + } + // Is "nodeCell" the same as the destination cell of the call edge? + else if(nodeCell.equals(callEdgeAttr.getDestinationCell())) { + mxCell dstNodeCell = callEdgeAttr.getDestinationCell(); + CallEdgeAttribute newOutEdgeAttr = new CallEdgeAttribute(insertToDstEdge, insertObjNodeCell, dstNodeCell); + + // If the target + if(graph.getModel().getValue(targetEdge) == null) return; + graph.getModel().remove(targetEdge); + + graph.insertEdge(contorlLayerCell, null, newOutEdgeAttr, insertObjNodeCell, dstNodeCell, "movable=false;"); + + continue; + } + } + } + finally { + graph.getModel().endUpdate(); + } + } + + /************************************************************* * [ *private ] /************************************************************* - * [ views ] - /************************************************************* * - * @param graph - * @param dataFlowGraph */ private mxGraph constructGraph(mxGraph graph, ControlFlowGraph controlFlowGraph) { showOnlyLayer(graph, CONTROL_FLOW_LAYER); - - // Creating Control-Flow and separeted Push/Pull which types of - Map controlFlowNodeCells = createCellsOfResourceMap(graph, CONTROL_FLOW_LAYER, controlFlowGraph); - Map pushResNodeCells = createCellsOfResourceMap(graph, PUSH_FLOW_LAYER, controlFlowGraph); - Map pullResNodeCells = createCellsOfResourceMap(graph, PULL_FLOW_LAYER, controlFlowGraph); - + graph.getModel().beginUpdate(); try { - // 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); + // Creating Control-Flow and separeted Push/Pull which types of + Map controlFlowNodeCells = createCellsOfResourceMap(graph, CONTROL_FLOW_LAYER, controlFlowGraph); + Map pushResNodeCells = createCellsOfResourceMap(graph, PUSH_FLOW_LAYER, controlFlowGraph); + Map pullResNodeCells = createCellsOfResourceMap(graph, PULL_FLOW_LAYER, controlFlowGraph); // Inserting edges of each transfer graph = insertControlFlowEdges(graph, PUSH_FLOW_LAYER, controlFlowGraph.getPushCallGraph(), pushResNodeCells); graph = insertControlFlowEdges(graph, PULL_FLOW_LAYER, controlFlowGraph.getPullCallGraph(), pullResNodeCells); + + // 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); + } finally { graph.getModel().endUpdate(); } @@ -124,7 +265,6 @@ /************************************************************* * When changed from previous stage, it will be called in initializing. - * @return */ private mxGraph clearControlFlowGraphCells(mxGraph graph) { mxCell root = (mxCell)graph.getDefaultParent(); @@ -151,12 +291,10 @@ /************************************************************* * Creating a map of to and Creating 's vertices - * @param model - * @param dataFlowGraph - * @return constructed mxGraph + * @return constructed the view of the graph */ - private Map createCellsOfResourceMap(mxGraph graph, final int layerNumber, final ControlFlowGraph controlFlowGraph) { - Map resNodeCells = new HashMap<>(); + private Map createCellsOfResourceMap(mxGraph graph, final int layerNumber, final ControlFlowGraph controlFlowGraph) { + Map resNodeCells = new HashMap<>(); mxCell root = (mxCell)graph.getDefaultParent(); mxCell nodeLayerCell = (mxCell)root.getChildAt(NODE_LAYER); @@ -164,41 +302,61 @@ // create resource vertices for (ResourceNode resNode : controlFlowGraph.getDataFlowGraph().getResouceNodes()) { - ObjectNode objNode = controlFlowGraph.getPushCallGraph().getStatefulObjectNode(resNode) != null - ? controlFlowGraph.getPushCallGraph().getStatefulObjectNode(resNode) - : controlFlowGraph.getPullCallGraph().getStatefulObjectNode(resNode); + + ObjectNode objNode = null; + switch(layerNumber) { + case CONTROL_FLOW_LAYER: + if(controlFlowGraph.getPushCallGraph().getStatefulObjectNode(resNode) != null) + objNode = controlFlowGraph.getPushCallGraph().getStatefulObjectNode(resNode); + + else if(controlFlowGraph.getPullCallGraph().getStatefulObjectNode(resNode) != null) + objNode = controlFlowGraph.getPullCallGraph().getStatefulObjectNode(resNode); + break; + + case PUSH_FLOW_LAYER: + if(controlFlowGraph.getPushCallGraph().getStatefulObjectNode(resNode) != null) + objNode = controlFlowGraph.getPushCallGraph().getStatefulObjectNode(resNode); + break; + + case PULL_FLOW_LAYER: + if(controlFlowGraph.getPullCallGraph().getStatefulObjectNode(resNode) != null) + objNode = controlFlowGraph.getPullCallGraph().getStatefulObjectNode(resNode); + break; + } + + if(objNode == null) continue; for(int i =0; i < nodeLayerCell.getChildCount(); i++) { mxCell nodeCell = (mxCell)nodeLayerCell.getChildAt(i); - if( !(nodeCell.getValue() instanceof ResourceNodeAttribute) ) continue; + if( nodeCell.getValue() instanceof ResourceNodeAttribute ) { + nodeCell = (mxCell)nodeLayerCell.getChildAt(i); + } + else continue; // Checking if the "node" has a cell of the data-flow-layer is the same as "resNode". ResourceNodeAttribute resNodeAttr = (ResourceNodeAttribute)nodeCell.getValue(); - if( !resNodeAttr.getResourceNode().equals(resNode) ) continue; + if( !resNodeAttr.getResourceNode().equals(resNode) )continue; // Getting information from the cell in the data-flow-layer, // After that, insert a resource as a vertex ObjectNodeAttribute objNodeAttr = new ObjectNodeAttribute(objNode); - Object resNodeObj = graph.insertVertex(layerCell, null, objNodeAttr, + mxCell resNodeObjCell = (mxCell)graph.insertVertex(layerCell, null, objNodeAttr, /* scale */nodeCell.getGeometry().getX(), nodeCell.getGeometry().getY(), /*coordinate*/nodeCell.getGeometry().getWidth(), nodeCell.getGeometry().getHeight(), - objNodeAttr.getDefaultStyle()); - resNodeCells.put(resNode, resNodeObj); + objNodeAttr.getDefaultStyle()); + + resNodeCells.put(resNode, resNodeObjCell); } } return resNodeCells; } + /************************************************************* - * - * @param graph - * @param layerNumber - * @param callGraph - * @param resNodeCells - * @return + * 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) { mxCell root = (mxCell)graph.getDefaultParent(); mxCell layerCell = (mxCell)root.getChildAt(layerNumber); @@ -207,20 +365,39 @@ CallEdge callEdge = (CallEdge) callGraphEdge; // Is checking node connecting a resource? - if(callEdge.getSource() == null) continue; - if(callEdge.getDestination() == null) continue; + if(callEdge.getSource() == null || callEdge.getDestination() == null) continue; ResourceNode srcResNode = ((StatefulObjectNode)callEdge.getSource()).getResource(); ResourceNode dstResNode = ((StatefulObjectNode)callEdge.getDestination()).getResource(); - Object srcNodeCell =resNodeCells.get(srcResNode); - Object dstNodeCell = resNodeCells.get(dstResNode); + mxCell srcNodeCell =resNodeCells.get(srcResNode); + mxCell dstNodeCell = resNodeCells.get(dstResNode); - CallEdgeAttribute callEdgeAttr = new CallEdgeAttribute(callEdge); - callEdge.setAttribute(callEdgeAttr); + if(srcNodeCell == null || dstNodeCell == null) continue; + CallEdgeAttribute callEdgeAttr = new CallEdgeAttribute(callEdge, srcNodeCell, dstNodeCell); graph.insertEdge(layerCell, null, callEdgeAttr, srcNodeCell, dstNodeCell, "movable=false;"); } return graph; } + + /************************************************************* + * + */ + private void addObjectNodeToCallGraphl(final ObjectNode insertObjNode, final PushPullValue selectedOption) { + switch(selectedOption) { + case PUSH: + if(controlFlowGraph.getPushCallGraph().getNodes().contains(insertObjNode))return; + controlFlowGraph.getPushCallGraph().addNode(insertObjNode); + + break; + + case PULL: + case PUSHorPULL: + if(controlFlowGraph.getPullCallGraph().getNodes().contains(insertObjNode))return; + controlFlowGraph.getPullCallGraph().addNode(insertObjNode); + + break; + } + } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java index 7c2c599..0fd74f4 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java @@ -35,29 +35,52 @@ import parser.exceptions.WrongLHSExpression; import parser.exceptions.WrongRHSExpression; +/************************************************************* + * + * @author n-nitta, k-fujii + */ public class DataFlowModelingStage extends Stage { public int PORT_DIAMETER = 8; public int PORT_RADIUS = PORT_DIAMETER / 2; + /************************************************************* + * [ *constructor] + /************************************************************* + * + */ public DataFlowModelingStage(mxGraph graph) { super(graph); } + /************************************************************* + * [ *public ] + /************************************************************* + * + */ @Override public boolean canChangeFrom(Stage prevStage) { return true; } + /************************************************************* + * + */ @Override public void init(Stage prevStage) { showOnlyLayer(graph, NODE_LAYER, DATA_FLOW_LAYER); } + /************************************************************* + * + */ @Override public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { return new DataFlowCellEditor(this, graphComponent); } + /************************************************************* + * + */ public void clear() { model = null; ((mxGraphModel) graph.getModel()).clear(); @@ -70,20 +93,18 @@ root.insert(new mxCell()); // CONTROL_FLOW_LAYER root.insert(new mxCell()); // PUSH_FLOW_LAYER root.insert(new mxCell()); // PULL_FLOW_LAYER - -// mxCell nodeLayerCell = new mxCell(); -// root.insert(nodeLayerCell); // NODE_LAYER, DATA_FLOW_LAYER -// nodeLayerCell.insert(new mxCell()); // CONTROL_FLOW_LAYER -// nodeLayerCell.insert(new mxCell()); // PUSH_FLOW_LAYER -// nodeLayerCell.insert(new mxCell()); // PULL_FLOW_LAYER - + showOnlyLayer(graph, NODE_LAYER, DATA_FLOW_LAYER); - } finally { + } + finally { graph.getModel().endUpdate(); } graph.refresh(); } + /************************************************************* + * + */ public DataTransferModel getModel() { if (model == null) { setModel(new DataTransferModel()); @@ -91,6 +112,9 @@ return model; } + /************************************************************* + * + */ public void setModel(DataTransferModel model) { clear(); // Set the model. @@ -99,14 +123,17 @@ // Update the mxGraph. graph = constructGraph(graph, model); } - + + /************************************************************* + * + */ public boolean isValid() { if (model == null) return false; if (!Validation.checkUpdateConflict(model)) return false; return true; } - /** + /************************************************************* * Construct a mxGraph from DataFlowModel * @param model * @param dataFlowGraph @@ -195,6 +222,9 @@ return graph; } + /************************************************************* + * + */ public void addIdentifierTemplate(IdentifierTemplate res) { getModel().addIdentifierTemplate(res); graph.getModel().beginUpdate(); @@ -208,6 +238,9 @@ } } + /************************************************************* + * + */ public void addChannelGenerator(DataTransferChannelGenerator channelGen) { getModel().addChannelGenerator(channelGen); graph.getModel().beginUpdate(); @@ -233,7 +266,10 @@ graph.getModel().endUpdate(); } } - + + /************************************************************* + * + */ public void addIOChannelGenerator(DataTransferChannelGenerator ioChannelGen) { getModel().addIOChannelGenerator(ioChannelGen); graph.getModel().beginUpdate(); @@ -304,6 +340,9 @@ return true; } + /************************************************************* + * + */ public void delete() { for (Object obj: graph.getSelectionCells()) { mxCell cell = (mxCell) obj; @@ -336,6 +375,9 @@ graph.removeCells(graph.getSelectionCells()); } + /************************************************************* + * + */ public void setChannelCode(DataTransferChannelGenerator ch, String code) { ch.setSourceText(code); TokenStream stream = new TokenStream(); diff --git a/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java b/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java index fcb0426..0389845 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java +++ b/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java @@ -22,8 +22,6 @@ /************************************************************* * DAG-Layout sorting algorithm. - * @author k-okada, k-fujii - * */ public class DAGLayout extends mxGraphLayout { diff --git a/AlgebraicDataflowArchitectureModel/src/application/views/SwitchDisplayFlowWindow.java b/AlgebraicDataflowArchitectureModel/src/application/views/SwitchDisplayFlowWindow.java new file mode 100644 index 0000000..5bfd503 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/views/SwitchDisplayFlowWindow.java @@ -0,0 +1,59 @@ +package application.views; + +import java.awt.Container; +import java.awt.GridLayout; + +import javax.swing.ButtonGroup; +import javax.swing.JDialog; +import javax.swing.JToggleButton; + +import application.ApplicationWindow; +import application.editor.Editor; + +/************************************************************* + * the window has a button group for swichting layers in the control-flow-modeling. + */ +public class SwitchDisplayFlowWindow extends JDialog { + private String title = "ShowLayer"; + private Editor editor = null; + private JToggleButton enableControlFlowLayerButton = null; + private JToggleButton enablePushFlowLayerButton = null; + private JToggleButton enablePullFlowLayerButton = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public SwitchDisplayFlowWindow(final ApplicationWindow owner, final Editor editor) { + super(owner); + this.editor = editor; + + setTitle(title); + setDefaultCloseOperation(HIDE_ON_CLOSE); + + // initialize buttons + enableControlFlowLayerButton = new JToggleButton("PUSH/PULL-Flow"); + enablePushFlowLayerButton = new JToggleButton("PUSH-Flow"); + enablePullFlowLayerButton = new JToggleButton("PULL-Flow"); + + enableControlFlowLayerButton.setEnabled(true); + enableControlFlowLayerButton.setEnabled(false); + enableControlFlowLayerButton.setEnabled(false); + + ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(enableControlFlowLayerButton); + buttonGroup.add(enablePushFlowLayerButton); + buttonGroup.add(enablePullFlowLayerButton); + + // initialize panel + Container panel = getContentPane(); + panel.setLayout(new GridLayout(/*low*/3, /*col*/1)); + panel.add(enableControlFlowLayerButton); + panel.add(enablePushFlowLayerButton); + panel.add(enablePullFlowLayerButton); + pack(); + setResizable(false); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdgeAttribute.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdgeAttribute.java index 5d0ee42..450f732 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdgeAttribute.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdgeAttribute.java @@ -1,18 +1,29 @@ package models.controlFlowModel; +import com.mxgraph.model.mxCell; + import models.EdgeAttribute; import models.dataFlowModel.PushPullValue; +/************************************************************* + * Information of connection status of the call edge among nodes type of "Object-Node". + */ public class CallEdgeAttribute extends EdgeAttribute { private CallEdge callEdge = null; + private mxCell srcCell = null; + private mxCell dstCell = null; /************************************************************* * [ *constructor ] /************************************************************* * */ - public CallEdgeAttribute(CallEdge callEdge) { + public CallEdgeAttribute(CallEdge callEdge, final mxCell srcCell, final mxCell dstCell) { this.callEdge = callEdge; + this.callEdge.setAttribute(this); + + this.srcCell = srcCell; + this.dstCell = dstCell; } /************************************************************* @@ -27,7 +38,7 @@ public PushPullValue getSelectedOption() { return callEdge.getSelectedOption(); } - + public ObjectNode getSourceObjectNode() { if( !(callEdge.getSource() instanceof ObjectNode) ) throw new ClassCastException("sourceNode isn't type of "); return (ObjectNode)callEdge.getSource(); @@ -38,12 +49,28 @@ return (ObjectNode)callEdge.getDestination(); } + public mxCell getSourceCell() { + return srcCell; + } + + public mxCell getDestinationCell() { + return dstCell; + } + /************************************************************* * */ @Override public String toString() { - return callEdge.getSelectedOption().name(); + String value = ""; + value += callEdge.getSelectedOption().name(); + + if(2 <= callEdge.getSource().getOutEdges( ).size()) { + int order = (((ObjectNode)callEdge.getSource()).getOutEdgeCallOrder(callEdge)+ 1); + value += ":[" + order + "]"; + } + + return value; } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java index 2b5458e..fbd3356 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java @@ -47,8 +47,6 @@ dstObjNode.addInEdge(edge); } - - public StatefulObjectNode getStatefulObjectNode(ResourceNode resNode) { return statefulObjMap.get(resNode); } diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java index 86517ec..3c972b2 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java @@ -37,27 +37,24 @@ List nodes = new ArrayList<>(); // 1. adding parentNode - ObjectNode delegatingNode = callEdge.getSelectedOption().equals(PushPullValue.PUSH) - ? (ObjectNode) callEdge.getSource() - : (ObjectNode) callEdge.getDestination(); - - ObjectNode parentNode = callEdge.getSelectedOption().equals(PushPullValue.PUSH) - ? (ObjectNode) callEdge.getDestination() - : (ObjectNode) callEdge.getSource(); + ObjectNode delegatingNode = (ObjectNode) callEdge.getDestination(); + ObjectNode parentNode = (ObjectNode) callEdge.getSource(); if(parentNode == null || delegatingNode == null) throw new NullPointerException("parentNode is null."); if( !(parentNode instanceof ObjectNode && delegatingNode instanceof ObjectNode)) throw new ClassCastException("callEdge.getSource() is not ObjectNode"); - - nodes.add(parentNode); + + // if the relation of "delegatingNode" to "parentNode" is 1 : 1 ? + // then return an empty list. + if( isRootNode(parentNode) && ! hasChildrenNode(parentNode) ) return nodes; + // 2. collecting for each transfer method has nodes in the common area. + collectCommonTransferNodes(nodes, parentNode, delegatingNode); - // 2. searchinge and adding children node of parentNode - // same area of each transfer methods - searchOutOfNodes(nodes, parentNode, delegatingNode, callEdge.getSelectedOption()); - - // add to nodes in PUSH + // 3. if the transfer method is PUSH-style, + // then serach delegatable area. + collectParentNodesInPushTransfer(nodes, parentNode); // switch objects by transfer type return nodes; @@ -66,37 +63,88 @@ /************************************************************* * [* private ] /************************************************************* - * + * Collecting nodes in the "nodes" parameter for each transfer method has nodes in the common area. + * @param nodes + * @param curObjNode + * @param delegatingObjNode + * @param selectedOption */ - private void searchOutOfNodes(List nodes, ObjectNode currentNode, final ObjectNode delegatingNode, final PushPullValue selectedOption){ - - switch(selectedOption) { - case PUSH: - if(currentNode.getInEdges().size() == 0) return; - - for(Edge e : currentNode.getInEdges()) { - ObjectNode foundNode = (ObjectNode)e.getSource(); + private void collectCommonTransferNodes(List nodes, ObjectNode curObjNode, final ObjectNode delegatingObjNode){ + if( !hasChildrenNode(curObjNode)) return; - if(foundNode.equals(delegatingNode)) continue; - - nodes.add(foundNode); - searchOutOfNodes(nodes, foundNode, delegatingNode, selectedOption); - } - break; + for(Edge e : curObjNode.getOutEdges()) { + ObjectNode foundNode = (ObjectNode)e.getDestination(); - case PULL: - case PUSHorPULL: - if(currentNode.getOutEdges().size() == 0) return; + if( foundNode.equals(delegatingObjNode)) continue; + + nodes.add(foundNode); + collectCommonTransferNodes(nodes, foundNode, delegatingObjNode); + } + } - for(Edge e : currentNode.getOutEdges()) { - ObjectNode foundNode = (ObjectNode)e.getDestination(); - - if(foundNode.equals(delegatingNode)) continue; - - nodes.add(foundNode); - searchOutOfNodes(nodes, foundNode, delegatingNode, selectedOption); - } - break; + /************************************************************* + * Collecting nodes in the "nodes" parameter for node of the area of PUSH-style transfer method. + * @param result in "nodes" parameter. + * @param curObjNode + */ + private void collectParentNodesInPushTransfer(List nodes, ObjectNode curObjNode) { + if( isRootNode(curObjNode) ) return; + if( isInEdgesConversingToNode(curObjNode) ) return; + + if( !(curObjNode.getInEdge(0).getSource() instanceof ObjectNode)) + throw new ClassCastException(); + + ObjectNode parentObjNode = (ObjectNode)curObjNode.getInEdge(0).getSource(); + nodes.add(parentObjNode); + + int inEdgeCallOrder = parentObjNode.getOutEdgeCallOrder(curObjNode.getInEdge(0)); + for(Edge edge : parentObjNode.getOutEdges()) { + if( !(edge instanceof CallEdge)) continue; + + int callOrder = curObjNode.getOutEdgeCallOrder((CallEdge)edge); + if(inEdgeCallOrder < callOrder) collectChildNodesInPushTransfer(nodes, parentObjNode); } + + collectParentNodesInPushTransfer(nodes, parentObjNode); + } + + /************************************************************* + * + * @param node + */ + private void collectChildNodesInPushTransfer(List nodes, ObjectNode curObjNode) { + if( !hasChildrenNode(curObjNode)) return; + + for(Edge e : curObjNode.getOutEdges()) { + ObjectNode foundNode = (ObjectNode)e.getDestination(); + nodes.add(foundNode); + + collectChildNodesInPushTransfer(nodes, curObjNode); + } + } + + /************************************************************* + * + * @param node + */ + private boolean isRootNode(final ObjectNode node) { + return node.getInEdges().isEmpty(); + } + + /************************************************************* + * + * @param node + */ + private boolean hasChildrenNode(final ObjectNode node) { + if(node.getOutEdges().size() < 1) return false; + return true; + } + + /************************************************************* + * + * @param node + */ + private boolean isInEdgesConversingToNode(final ObjectNode node) { + return ( 1 < node.getInEdges().size() ); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java new file mode 100644 index 0000000..498d064 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java @@ -0,0 +1,25 @@ +package models.controlFlowModel; + +/************************************************************* + * An object is mapped to I/O channel. + * ToDo: Fecthing name from in Data-Flow-Graph + */ +public class EntryPointObjectNode extends ObjectNode { + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public EntryPointObjectNode(String name) { + super(name); + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + + +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java index 7907683..8bbcc31 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java @@ -7,11 +7,13 @@ import models.Node; public class ObjectNode extends Node{ - private String name; + protected String name = ""; public ObjectNode(String name) { inEdges = new ArrayList<>(); outEdges = new ArrayList<>(); + + this.name = name; } public String getName() { @@ -21,6 +23,24 @@ public void setName(String name) { this.name = name; } + + public CallEdge findEdgeInOutEdges(final CallEdge edge) { + for(Edge e : outEdges) { + if( e instanceof CallEdge) return (CallEdge)e; + } + return null; + } + + public CallEdge findEdgeInInEdges(final CallEdge edge) { + for(Edge e : inEdges) { + if( e instanceof CallEdge) return (CallEdge)e; + } + return null; +} + + public CallEdge getInEdge(int i) { + return (CallEdge) ((List) inEdges).get(i); + } public CallEdge getOutEdge(int i) { return (CallEdge) ((List) outEdges).get(i); @@ -33,6 +53,13 @@ public int getChildrenNum() { return outEdges.size(); } + + public int getOutEdgeCallOrder(final CallEdge callEdge) { + for(int i = 0; i < outEdges.size(); i++) { + if(callEdge.equals(getOutEdge(i))) return i; + } + return -1; + } public ObjectNode getChildren(int i) { return (ObjectNode) ((List) outEdges).get(i).getDestination(); diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNodeAttribute.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNodeAttribute.java index 8b3f18d..9462f7a 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNodeAttribute.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNodeAttribute.java @@ -1,5 +1,7 @@ package models.controlFlowModel; +import com.mxgraph.model.mxCell; + import models.NodeAttribute; /************************************************************* @@ -9,21 +11,37 @@ */ public class ObjectNodeAttribute extends NodeAttribute{ private ObjectNode objectNode = null; + private String shapeStyle = ""; /************************************************************* * [ *constructor ] /************************************************************* * */ - public ObjectNodeAttribute(ObjectNode objectNode) { + public ObjectNodeAttribute(final ObjectNode objectNode) { this.objectNode = objectNode; this.objectNode.setAttribute(this); - - if( objectNode instanceof StatefulObjectNode ) { - this.objectNode.setName(objectNode.getName()); + + // Setting a shape style of cell + if(objectNode instanceof StatefulObjectNode) { + shapeStyle = "shape=ellipse;perimeter=ellipsePerimeter;"; + } + else if(objectNode instanceof EntryPointObjectNode) { + shapeStyle = "shape=rectangle;perimeter=rectanglePerimeter;"; } else { - this.objectNode.setName("objectNode"); + shapeStyle = "shape=hexagon;perimeter=hexagonPerimeter;"; + } + + // Setting a name of cell + if(objectNode.name != null) return; + if(objectNode.name.isEmpty()) return; + + if( objectNode instanceof StatefulObjectNode ) { + objectNode.name = objectNode.getName(); + } + else if(objectNode instanceof EntryPointObjectNode){ + objectNode.name = "entryPoint"; } } @@ -38,35 +56,53 @@ public ObjectNode getObjectNode() { return objectNode; } - + /************************************************************* * */ public String getDefaultStyle() { + String style = ";"; + return objectNode instanceof StatefulObjectNode - ? "shape=ellipse;perimeter=ellipsePerimeter;" - : "shape=hexagon;perimeter=hexagonPerimeter"; + ? shapeStyle + style + : shapeStyle + style; } /************************************************************* * */ public String getEnableStyle() { + String style = "fillColor=#7fffd4;"; + style += "strokeColor=#66cdaa;"; + style += "strokeWidth=2;"; + return objectNode instanceof StatefulObjectNode - ? "shape=ellipse;perimeter=ellipsePerimeter;fillColor=#ffcc33" - : "shape=hexagon;perimeter=hexagonPerimeter;fillColor=#ffcc33"; + ? shapeStyle + style + : shapeStyle + style; } /************************************************************* * */ public String getDisableStyle() { + String style = "fillColor=#999999"; + return objectNode instanceof StatefulObjectNode - ? "shape=ellipse;perimeter=ellipsePerimeter;fillColor=#999999" - : "shape=hexagon;perimeter=hexagonPerimeter;fillColor=#999999"; + ? shapeStyle + style + : shapeStyle + style; } /************************************************************* + * + */ + public String getDelegatingStyle() { + String style = "strokeWidth=4;"; + style += "strokeColor=#4169e;"; + + return shapeStyle + style; + } + + /************************************************************* * showing label of mxCell */ @Override