diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/InsertStatelessObjectAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/InsertStatelessObjectAction.java index c9d423b..42160a2 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/actions/InsertStatelessObjectAction.java +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/InsertStatelessObjectAction.java @@ -15,11 +15,7 @@ * */ public class InsertStatelessObjectAction extends AbstractPopupAction{ - - /************************************************************* - * [ *constructor ] - /************************************************************* - */ + private ControlFlowDelegationStage stage = null; /************************************************************* @@ -31,13 +27,20 @@ this.stage = stage; } + /************************************************************* + * [ *public ] + /************************************************************* + * + */ @Override public void actionPerformed(ActionEvent e) { insertObjectNode(targetCell); - stage.setState( ControlFlowDelegationStageStatus.SELECTING_AN_EDGE); + this.stage.setState( ControlFlowDelegationStageStatus.SELECTING_AN_EDGE); } - /*************************************************************/ + /************************************************************ + * + */ private void insertObjectNode(final Object cellObj) { if(cellObj == null) return; diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/ShowDependentableMediatorAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowDependentableMediatorAction.java new file mode 100644 index 0000000..cd3cf8b --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowDependentableMediatorAction.java @@ -0,0 +1,48 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import com.mxgraph.model.mxCell; +import com.mxgraph.swing.mxGraphComponent; + +import application.editor.stages.ControlFlowDelegationStage; +import application.editor.stages.ControlFlowDelegationStageStatus; +import models.controlFlowModel.CallEdgeAttribute; + +public class ShowDependentableMediatorAction extends AbstractPopupAction { + private ControlFlowDelegationStage stage = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + */ + public ShowDependentableMediatorAction(final ControlFlowDelegationStage stage, final mxGraphComponent graphComponent, final mxCell targetCell) { + super("Dependent on Mediator", targetCell, graphComponent); + this.stage = stage; + } + + /************************************************************ + * [ *public ] + /************************************************************* + * + */ + @Override + public void actionPerformed(ActionEvent e) { + showDependentableNodesBySelectedEdge(targetCell); + stage.setState(ControlFlowDelegationStageStatus.SHOWING_DEPENDENTABLE_NODES); + // -> dependent manipulation is ControlFlowStageEditor + } + + /************************************************************* + * [ *private ] + /************************************************************* + * + */ + private void showDependentableNodesBySelectedEdge(Object cellObj) { + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)graphComponent.getGraph().getModel().getValue(cellObj); + if(callEdgeAttr == null) return; + + ControlFlowDelegationStage cfdStage = (ControlFlowDelegationStage)stage; + cfdStage.showDependentableNodes(this.graphComponent.getGraph(), callEdgeAttr);; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java index 077d713..92103b7 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java @@ -9,8 +9,10 @@ import application.editor.FlowCellEditor; import models.controlFlowModel.CallEdgeAttribute; +import models.controlFlowModel.EntryPointObjectNode; import models.controlFlowModel.ObjectNode; import models.controlFlowModel.ObjectNodeAttribute; +import models.controlFlowModel.StatefulObjectNode; /************************************************************* * @@ -19,84 +21,138 @@ private mxCell targetEdgeCell = null; /************************************************************* - * [ *constructor ] - /************************************************************* + * [ *constructor ] + /************************************************************* * * @param graph */ public ControlFlowDelegationCellEditor(ControlFlowDelegationStage stage, mxGraphComponent graphComponent) { super(stage, graphComponent); } - + /************************************************************* - * [ *public ] - /************************************************************* + * [ *public ] + /************************************************************* * */ @Override public void startEditing(Object cellObj, EventObject eventObj) { - if( editingCell != null) stopEditing(true); - ControlFlowDelegationStage cfdStage = (ControlFlowDelegationStage)stage; - - switch(cfdStage.getCurState()) { - case SELECTING_AN_EDGE: - // Branching based on the edge click event. - // | double clicked > Showing delegatable nodes. - if( graphComponent.getGraph().getModel().isEdge(cellObj)) { - // cache a target edge of cell; - targetEdgeCell = (mxCell)cellObj; - - showDelegatableNodesBySelectedEdge(cellObj); - cfdStage.setState(ControlFlowDelegationStageStatus.SHOWING_DELEGATABLE_NODES); + if (editingCell != null) + stopEditing(true); + ControlFlowDelegationStage cfdStage = (ControlFlowDelegationStage) stage; + + switch (cfdStage.getCurState()) { + case SELECTING_AN_EDGE: + // Branching based on the edge click event. + // | double clicked > Showing delegatable nodes. + if (graphComponent.getGraph().getModel().isEdge(cellObj)) { + // cache a target edge of cell; + targetEdgeCell = (mxCell) cellObj; + + showDelegatableNodesBySelectedEdge(cellObj); + cfdStage.setState(ControlFlowDelegationStageStatus.SHOWING_DELEGATABLE_NODES); + } + break; + + case SHOWING_DELEGATABLE_NODES: + if (graphComponent.getGraph().getModel().isVertex(cellObj)) { + mxCell dstCell = null; + if (cellObj instanceof mxCell) dstCell = (mxCell) cellObj; + else throw new ClassCastException(); + + // invocating delegation method + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute) graphComponent.getGraph().getModel().getValue(targetEdgeCell); + if (callEdgeAttr == null) return; + + ObjectNode dstObjNode = ((ObjectNodeAttribute) dstCell.getValue()).getObjectNode(); + if (dstObjNode == null) throw new ClassCastException(); + + if (!cfdStage.isExecutableDelegation(callEdgeAttr, dstObjNode)) { + JOptionPane.showMessageDialog(graphComponent, "It's impossible for the chose object to delegate."); + return; } - break; - - case SHOWING_DELEGATABLE_NODES: - if( graphComponent.getGraph().getModel().isVertex(cellObj) ) { - mxCell dstCell = null; - if(cellObj instanceof mxCell) dstCell = (mxCell)cellObj; + cfdStage.showDelegatedGraph(graphComponent.getGraph(), targetEdgeCell, (mxCell) cellObj); + cfdStage.setState(ControlFlowDelegationStageStatus.SELECTING_AN_EDGE); + } else { + cfdStage.resetAllStyleOfCells(); + cfdStage.setState(ControlFlowDelegationStageStatus.SELECTING_AN_EDGE); + } + break; + + case SHOWING_DEPENDENTABLE_NODES: + if (cfdStage.getCachedCell() == null) return; + this.targetEdgeCell = cfdStage.getCachedCell(); + + if (graphComponent.getGraph().getModel().isVertex(cellObj)) { + mxCell targetObjCell = null; + if (cellObj instanceof mxCell) targetObjCell = (mxCell) cellObj; else throw new ClassCastException(); - - // invocating delegation method - CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)graphComponent.getGraph().getModel().getValue(targetEdgeCell); - if(callEdgeAttr == null) return; + + // invocation + ObjectNodeAttribute targetObjNodeAttr = (targetObjCell.getValue() instanceof ObjectNodeAttribute) + ?(ObjectNodeAttribute)targetObjCell.getValue() + :null; + if(targetObjNodeAttr == null) return; - ObjectNode dstObjNode = ((ObjectNodeAttribute)dstCell.getValue()).getObjectNode(); - if(dstObjNode == null) throw new ClassCastException(); - - if(!cfdStage.isExecutableDelegation(callEdgeAttr, dstObjNode)){ - JOptionPane.showMessageDialog(graphComponent, "It's impossible for the chose object to delegate."); + ObjectNode targetObjNode = targetObjNodeAttr.getObjectNode(); + if (isNotStatelessObject(targetObjNode)) { + JOptionPane.showMessageDialog(graphComponent, "It's impossible for the chose object to dependent."); return; } - cfdStage.showDelegatedGraph(graphComponent.getGraph(), targetEdgeCell, (mxCell)cellObj); + + dependentObjectNode(targetObjCell); + + cfdStage.resetAllStyleOfCells(); cfdStage.setState(ControlFlowDelegationStageStatus.SELECTING_AN_EDGE); - } - else { + } else { cfdStage.resetAllStyleOfCells(); cfdStage.setState(ControlFlowDelegationStageStatus.SELECTING_AN_EDGE); } - break; - } + break; + } } /************************************************************* * */ @Override - public void stopEditing(boolean cancel) { } + public void stopEditing(boolean cancel) { + } /************************************************************* - * [ *private ] - /************************************************************* + * [ *private ] + /************************************************************* * view - /************************************************************* + ************************************************************** * */ private void showDelegatableNodesBySelectedEdge(Object cellObj) { - CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)graphComponent.getGraph().getModel().getValue(cellObj); - if(callEdgeAttr == null) return; - - ControlFlowDelegationStage cfdStage = (ControlFlowDelegationStage)stage; - cfdStage.showDelegatableNodes(graphComponent.getGraph(), callEdgeAttr); + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute) graphComponent.getGraph().getModel().getValue(cellObj); + if (callEdgeAttr == null) + return; + + ControlFlowDelegationStage cfdStage = (ControlFlowDelegationStage) stage; + cfdStage.showDelegatableNodes(graphComponent.getGraph(), callEdgeAttr); } + + /************************************************************ + * + */ + private void dependentObjectNode(final mxCell targetMediatorCell) { + if(targetMediatorCell == null) return; + + ControlFlowDelegationStage cfdStage = (ControlFlowDelegationStage) stage; + cfdStage.dependentObjectNode(graphComponent.getGraph(), targetEdgeCell, targetMediatorCell); + } + + /************************************************************ + * + */ + private boolean isNotStatelessObject(final ObjectNode targetObjNode) { + if(targetObjNode instanceof StatefulObjectNode) return true; + if(targetObjNode instanceof EntryPointObjectNode) return true; + + return false; + } + } diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java index bf0b201..3cbcfea 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java @@ -26,6 +26,7 @@ import models.controlFlowModel.CallEdge; import models.controlFlowModel.CallEdgeAttribute; import models.controlFlowModel.CallGraph; +import models.controlFlowModel.CompositeCallEdgeAttribute; import models.controlFlowModel.ControlFlowDelegator; import models.controlFlowModel.ControlFlowGraph; import models.controlFlowModel.EntryPointObjectNode; @@ -48,6 +49,8 @@ private ControlFlowGraph controlFlowGraph = null; private PopupMenuBase popupMenu = null; + + private mxCell selectedCellOnAnyEvent = null; /************************************************************* * [ *constructor ] @@ -81,6 +84,21 @@ curState = nextState; } + + /************************************************************* + * + */ + public void setCellOnAnyEvent(final mxCell selectedCell) { + this.selectedCellOnAnyEvent = selectedCell; + } + + /************************************************************* + * + */ + public mxCell getCachedCell() { + return this.selectedCellOnAnyEvent; + } + /************************************************************* * */ @@ -136,12 +154,12 @@ if(graphComponent.getCellAt(e.getX(), e.getY()) != null) return; if(curState.equals(ControlFlowDelegationStageStatus.SELECTING_AN_EDGE)) return; - System.out.println("cancel showing state."); resetAllStyleOfCells(); curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; + return; } - else if(SwingUtilities.isRightMouseButton(e)) { + else if(SwingUtilities.isRightMouseButton(e)) { popupMenu.show(e.getX(), e.getY()); } } @@ -149,11 +167,10 @@ return listener; } - /************************************************************* * manipulating the control-graph /************************************************************* - * + * control-flow-delegation */ public void showDelegatableNodes(mxGraph graph, final CallEdgeAttribute callEdgeAttr){ mxCell root = (mxCell)graph.getDefaultParent(); @@ -191,6 +208,44 @@ graph.refresh(); } } + + /************************************************************* + * dependent-on-mediator + */ + public void showDependentableNodes(mxGraph graph, final CallEdgeAttribute callEdgeAttr) { + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell layerCell = (mxCell)root.getChildAt(PULL_FLOW_LAYER); + graph.getModel().beginUpdate(); + try { + ObjectNode delegatingNode = callEdgeAttr.getDestinationObjectNode(); + + for(Object node : graph.getChildVertices(layerCell)) { + 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.searchDependentableMediatorNodes(callEdgeAttr.getCallEdge()); + + if(delegatableNodes.contains(objNode)) { + graph.getModel().setStyle(cell, objNodeAttr.getEnableStyle()); + } + else { + graph.getModel().setStyle(cell, objNodeAttr.getDisableStyle()); + } + + if(delegatingNode.equals(objNodeAttr.getObjectNode())) + /* base-Node*/graph.getModel().setStyle(cell, objNodeAttr.getDelegatingStyle()); + } + } + finally { + graph.getModel().endUpdate(); + graph.refresh(); + } + } /************************************************************* * Showing the graph that was executed CFD. @@ -238,6 +293,101 @@ /************************************************************* * */ + public void dependentObjectNode(mxGraph graph, mxCell targetEdgeCell ,mxCell targetObjNodeCell) { + CallEdgeAttribute targetCallEdgeAttr = (CallEdgeAttribute)targetEdgeCell.getValue(); + if(targetCallEdgeAttr == null) return; + + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell pullFlowLayerCell = (mxCell)root.getChildAt(Stage.PULL_FLOW_LAYER); + + graph.getModel().beginUpdate(); + + try { + // Reconnecting each edges of the node. + // Get each of the transformed object + ObjectNode srcObjNode = targetCallEdgeAttr.getSourceObjectNode(); + ObjectNode dstObjNode = targetCallEdgeAttr.getDestinationObjectNode(); + if(srcObjNode == null || dstObjNode == null) throw new NullPointerException(); + if(!(srcObjNode instanceof ObjectNode && dstObjNode instanceof ObjectNode)) throw new ClassCastException(); + + // Get target "Mediator Object" + ObjectNodeAttribute targetObjNodeAttr = (ObjectNodeAttribute)targetObjNodeCell.getValue(); + if(targetObjNodeAttr == null) throw new NullPointerException(); + + ObjectNode targetMediatorObjNode = targetObjNodeAttr.getObjectNode(); + if(targetMediatorObjNode == null) throw new NullPointerException(); + if(targetMediatorObjNode instanceof StatefulObjectNode || targetMediatorObjNode instanceof EntryPointObjectNode) return; + + + // Connecting I/O Edges to the insert object. + CallEdge srcToMediatorEdge = new CallEdge(targetCallEdgeAttr.getSourceObjectNode(), targetMediatorObjNode, targetCallEdgeAttr.getSelectedOption()); + CallEdge mediatorToDstEdge = new CallEdge(targetMediatorObjNode, dstObjNode, targetCallEdgeAttr.getSelectedOption()); + if(srcToMediatorEdge == null || mediatorToDstEdge == null) throw new NullPointerException(); + + // Manipulate an edge of the source object node. + srcObjNode.addOutEdge(srcToMediatorEdge); + srcObjNode.removeOutEdge(targetCallEdgeAttr.getCallEdge()); + + // Manipulate an edge of the destination object node. + dstObjNode.removeInEdge(targetCallEdgeAttr.getCallEdge()); + + // Connect an edge of the mediation object node. + targetMediatorObjNode.addInEdge(srcToMediatorEdge); + + // Create composition Attribute of the Call-Edge . + // Get already connected call-edge. + CompositeCallEdgeAttribute compositeEdgeAttr = null; + + for(int i = 0; i < pullFlowLayerCell.getChildCount(); i++) { + mxCell edgeCell = (mxCell)pullFlowLayerCell.getChildAt(i); + if (!edgeCell.isEdge() ) continue; + if (!(edgeCell.getValue() instanceof CallEdgeAttribute)) continue; + + CallEdgeAttribute edgeAttr = (CallEdgeAttribute)edgeCell.getValue(); + + if (!(edgeAttr.getSourceObjectNode().equals(targetMediatorObjNode)))continue; + if (!(edgeAttr.getDestinationObjectNode().equals(dstObjNode)))continue; + + compositeEdgeAttr = new CompositeCallEdgeAttribute(edgeAttr); + + break; + } + + if(compositeEdgeAttr != null) + compositeEdgeAttr.mergeCallEdgeAttribute(targetCallEdgeAttr); + + // Manipulate the cell of the graph. + for(int i = 0; i < pullFlowLayerCell.getChildCount(); i++) { + mxCell nodeCell = (mxCell)pullFlowLayerCell.getChildAt(i); + if( !nodeCell.isVertex() ) continue; + + // Check "nodeCell" has an instance of + ObjectNodeAttribute cellObjNodeAttr = (ObjectNodeAttribute)nodeCell.getValue(); + if(cellObjNodeAttr == null) throw new ClassCastException("dosen't have the value of "); + + // Is "nodeCell" the same as the source cell of the call edge? + if(nodeCell.equals(targetCallEdgeAttr.getSourceCell())){ + mxCell srcNodeCell = targetCallEdgeAttr.getSourceCell(); + + // If the target call edge hasn't removed yet. + // then it removes from mxGraphModel. + if(graph.getModel().getValue(targetEdgeCell) != null) + graph.getModel().remove(targetEdgeCell); + + graph.insertEdge(pullFlowLayerCell, null, compositeEdgeAttr, srcNodeCell, targetObjNodeCell, "movable=false;"); + continue; + } + + } + } + finally { + graph.getModel().endUpdate(); + } + } + + /************************************************************* + * + */ public void resetAllStyleOfCells() { mxCell root = (mxCell)graph.getDefaultParent(); @@ -274,13 +424,14 @@ mxCell root = (mxCell)graph.getDefaultParent(); mxCell layerCell = null; switch(callEdgeAttr.getSelectedOption()) { - case PUSH: - layerCell = (mxCell)root.getChildAt(Stage.PUSH_FLOW_LAYER); - break; - - case PULL: - case PUSHorPULL: - layerCell = (mxCell)root.getChildAt(Stage.PULL_FLOW_LAYER); + case PUSH: + layerCell = (mxCell)root.getChildAt(Stage.PUSH_FLOW_LAYER); + break; + + case PULL: + case PUSHorPULL: + layerCell = (mxCell)root.getChildAt(Stage.PULL_FLOW_LAYER); + break; } graph.getModel().beginUpdate(); @@ -303,7 +454,7 @@ objNodeAttr.getDefaultStyle()); insertObjNodeCell.setValue(objNodeAttr); - addObjectNodeToCallGraphl(insertObjNode, callEdgeAttr.getSelectedOption()); + addObjectNodeToCallGraph(insertObjNode, callEdgeAttr.getSelectedOption()); // Reconnecting each edges of the node. ObjectNode srcObjNode = callEdgeAttr.getSourceObjectNode(); @@ -374,7 +525,6 @@ } } - /************************************************************* * */ @@ -384,8 +534,8 @@ return delegatableNodes.contains(dstObjNode); } - - + + /************************************************************* /************************************************************* * [ *private ] /************************************************************* @@ -492,7 +642,7 @@ /************************************************************* - * Createing an input channel object + * Create 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; @@ -551,7 +701,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, final Map entryNodeCells) { mxCell root = (mxCell)graph.getDefaultParent(); @@ -603,7 +753,7 @@ /************************************************************* * */ - private void addObjectNodeToCallGraphl(final ObjectNode insertObjNode, final PushPullValue selectedOption) { + private void addObjectNodeToCallGraph(final ObjectNode insertObjNode, final PushPullValue selectedOption) { switch(selectedOption) { case PUSH: if(controlFlowGraph.getPushCallGraph().getNodes().contains(insertObjNode))return; @@ -620,5 +770,4 @@ } } - } diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStageStatus.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStageStatus.java index f2b7e7a..93a88a4 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStageStatus.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStageStatus.java @@ -6,4 +6,5 @@ public enum ControlFlowDelegationStageStatus { SELECTING_AN_EDGE, SHOWING_DELEGATABLE_NODES, + SHOWING_DEPENDENTABLE_NODES } diff --git a/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/ControlFlowDelegationStagePopupMenu.java b/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/ControlFlowDelegationStagePopupMenu.java index 1bd8d7c..dc088bc 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/ControlFlowDelegationStagePopupMenu.java +++ b/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/ControlFlowDelegationStagePopupMenu.java @@ -9,9 +9,12 @@ import application.actions.AbstractPopupAction; import application.actions.ChangeCallOrderAction; +import application.actions.ShowDependentableMediatorAction; import application.actions.InsertStatelessObjectAction; import application.editor.stages.ControlFlowDelegationStage; import application.views.PopupMenuBase; +import models.controlFlowModel.CallEdgeAttribute; +import models.dataFlowModel.PushPullValue; /************************************************************* * @@ -27,9 +30,10 @@ public ControlFlowDelegationStagePopupMenu(final ControlFlowDelegationStage stage, mxGraphComponent graphComponent) { super(graphComponent); this.stage = stage; - + addMenuItem(new JMenuItem(new InsertStatelessObjectAction(stage, graphComponent, selectedCell))); addMenuItem(new JMenuItem(new ChangeCallOrderAction(graphComponent, selectedCell))); + addMenuItem(new JMenuItem(new ShowDependentableMediatorAction(stage, graphComponent, selectedCell))); } /************************************************************* @@ -39,23 +43,25 @@ */ @Override public void show(int x, int y) { - - boolean isEnable = (graphComponent.getCellAt(x, y) != null) - ? true - : false; - - setEnableMenuItems(isEnable); - super.show(x, y); - - if( graphComponent.getCellAt(x, y) instanceof mxCell ) { selectedCell =(mxCell) graphComponent.getCellAt(x, y); } else { selectedCell = null; } + + if(this.selectedCell == null) return; notifyCellCached(selectedCell); + stage.setCellOnAnyEvent(selectedCell); + + boolean isEnable = (graphComponent.getCellAt(x, y) != null) + ? true + : false; + + setEnableMenuItems(isEnable); + + super.show(x, y); } /************************************************************* @@ -84,8 +90,31 @@ * */ private void setEnableMenuItems(final boolean isEnable) { + if(this.selectedCell == null) return; + for(Component component : popupMenu.getComponents()) { component.setEnabled(isEnable); + + // pull only + if(!isSelectedPullCallEdge(selectedCell)) { + JMenuItem menuItem = null; + if(component instanceof JMenuItem) menuItem = (JMenuItem)component; + + if(menuItem.getAction() instanceof ShowDependentableMediatorAction) { + component.setEnabled(false); + continue; + } + } + } } + + /************************************************************* + * + */ + private boolean isSelectedPullCallEdge(final mxCell selectedCell) { + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)selectedCell.getValue(); + return callEdgeAttr.getSelectedOption().equals(PushPullValue.PULL); + } + } diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CompositeCallEdgeAttribute.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CompositeCallEdgeAttribute.java new file mode 100644 index 0000000..389be85 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CompositeCallEdgeAttribute.java @@ -0,0 +1,36 @@ +package models.controlFlowModel; + +import java.util.ArrayList; +import java.util.List; + +public class CompositeCallEdgeAttribute extends CallEdgeAttribute { + private CallEdgeAttribute currentEdgeAttr = null; + private List mergedCallEdgeAttrs = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public CompositeCallEdgeAttribute(final CallEdgeAttribute callEdgeAttr) { + super(callEdgeAttr.getCallEdge(), + callEdgeAttr.getOriginalSourceObjectNode(), + callEdgeAttr.getSourceCell(), callEdgeAttr.getDestinationCell() + ); + + this.currentEdgeAttr = (this.currentEdgeAttr == null) + ? callEdgeAttr : null; + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + public void mergeCallEdgeAttribute(final CallEdgeAttribute mergedCallEdgeAttr) { + if(this.currentEdgeAttr == null) return; + if(this.mergedCallEdgeAttrs == null) this.mergedCallEdgeAttrs = new ArrayList(); + this.mergedCallEdgeAttrs.add(mergedCallEdgeAttr); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java index 2d0b5de..01fca86 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java @@ -4,6 +4,7 @@ import java.util.List; import models.Edge; +import models.dataFlowModel.PushPullValue; /************************************************************* * it has Delegation of Control-Flow algorithm. @@ -47,12 +48,28 @@ collectCommonTransferNodes(nodes, parentNode, delegatingNode); // 3. if the transfer method is PUSH-style, - // then serach delegatable area. - collectParentNodesInPushTransfer(nodes, delegatingNode, parentNode); + // then search delegatable area. + collectParentNodesOnPushTransfer(nodes, delegatingNode, parentNode); + // switch objects by transfer type return nodes; } + + + /************************************************************* + * + *@param callEdge + */ + public List searchDependentableMediatorNodes(final CallEdge callEdge){ + List nodes = new ArrayList<>(); + + // If the transfer method is PULL-style, + // then search dependable mediator object. + collectDependableObjectNodeOnPullTransfer(nodes, callEdge); + + return nodes; + } /************************************************************* * @@ -101,7 +118,7 @@ * @param result in "nodes" parameter. * @param curObjNode */ - private void collectParentNodesInPushTransfer(List nodes, ObjectNode curObjNode, final ObjectNode parentDelegatingNode) { + private void collectParentNodesOnPushTransfer(List nodes, ObjectNode curObjNode, final ObjectNode parentDelegatingNode) { if( isRootNode(curObjNode) ) return; if( isInEdgesConversingToNode(curObjNode) ) return; @@ -116,17 +133,17 @@ if( !(edge instanceof CallEdge)) continue; int callOrder = parentObjNode.getOutEdgeCallOrder((CallEdge)edge); - if(inEdgeCallOrder < callOrder) collectChildNodesInPushTransfer(nodes, (CallEdge)edge); + if(inEdgeCallOrder < callOrder) collectChildNodesOnPushTransfer(nodes, (CallEdge)edge); } - collectParentNodesInPushTransfer(nodes, parentObjNode, parentDelegatingNode); + collectParentNodesOnPushTransfer(nodes, parentObjNode, parentDelegatingNode); } /************************************************************* * * @param node */ - private void collectChildNodesInPushTransfer(List nodes, CallEdge callEdge) { + private void collectChildNodesOnPushTransfer(List nodes, CallEdge callEdge) { ObjectNode dstObjNode = (ObjectNode)callEdge.getDestination(); if(dstObjNode == null) return; @@ -142,12 +159,49 @@ if(foundNode == null) continue; if(nodes.contains(foundNode))continue; - collectChildNodesInPushTransfer(nodes, edge); + collectChildNodesOnPushTransfer(nodes, edge); } } /************************************************************* * + * + */ + private void collectDependableObjectNodeOnPullTransfer(List nodes, CallEdge callEdge) { + if(callEdge.getSelectedOption() != PushPullValue.PULL) return; + + // Are Both Source and Destination Stateful-Object? + StatefulObjectNode srcObjNode = (callEdge.getSource() instanceof StatefulObjectNode) + ? (StatefulObjectNode)callEdge.getSource() + : null; + + StatefulObjectNode dstObjNode = (callEdge.getDestination() instanceof StatefulObjectNode) + ? (StatefulObjectNode)callEdge.getDestination() + : null; + + if(srcObjNode == null || dstObjNode == null) return; + + // Has a destination connected with an object of a mediator? + for(Edge inEdge : dstObjNode.getInEdges()) { + CallEdge inCallEdge = (CallEdge)inEdge; + if(inCallEdge == null) continue; + + // It is a stateless object? (It is a mediator object?) + ObjectNode inSrcObjNode = (inCallEdge.getSource() instanceof ObjectNode) + ? (ObjectNode)inCallEdge.getSource() + : null; + if(inSrcObjNode == null) continue; + + if(inSrcObjNode instanceof StatefulObjectNode) continue; + if(inSrcObjNode instanceof EntryPointObjectNode) continue; + + nodes.add(inSrcObjNode); + } + } + + + /************************************************************* + * * @param node */ private boolean isRootNode(final ObjectNode node) {