diff --git a/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java index 6374908..fb04068 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java @@ -1,49 +1,84 @@ package application.simulator; -import application.editor.Editor; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Rectangle; +import java.util.EventObject; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import javax.swing.BorderFactory; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JTextField; + import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGraphModel; import com.mxgraph.model.mxIGraphModel; import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.swing.view.mxICellEditor; import com.mxgraph.util.mxConstants; import com.mxgraph.util.mxUtils; import com.mxgraph.view.mxCellState; -import models.algebra.*; +import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; + +import application.editor.Editor; +import application.layouts.DAGLayout; +import models.algebra.Expression; +import models.algebra.InvalidMessage; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Position; +import models.algebra.Term; +import models.algebra.Type; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; +import models.algebra.Variable; import models.dataConstraintModel.Channel; import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.DataFlowGraph; import models.dataFlowModel.DataTransferChannel; import models.dataFlowModel.PushPullAttribute; import models.dataFlowModel.PushPullValue; import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.visualModel.FormulaChannel; import parser.Parser; import parser.Parser.TokenStream; import parser.exceptions.ExpectedColon; import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedRightBracket; import parser.exceptions.WrongJsonExpression; -import simulator.Event; +import simulator.ChannelState; import simulator.Resource; import simulator.ResourceIdentifier; import simulator.Simulator; +import simulator.Event; +import simulator.SystemState; -import javax.swing.*; -import java.awt.*; -import java.util.ArrayList; -import java.util.EventObject; -import java.util.List; - -public class InputEventCellEditor implements mxICellEditor { +public class InputEventCellEditor implements mxICellEditor { public int DEFAULT_MIN_WIDTH = 70; public int DEFAULT_MIN_HEIGHT = 30; public double DEFAULT_MINIMUM_EDITOR_SCALE = 1; private double x = 20; private double y = 20; - + protected double minimumEditorScale = DEFAULT_MINIMUM_EDITOR_SCALE; protected int minimumWidth = DEFAULT_MIN_WIDTH; protected int minimumHeight = DEFAULT_MIN_HEIGHT; - + private SimulatorWindow window; private Object editingCell; private EventObject trigger; @@ -60,73 +95,75 @@ this.simulator = simulator; this.editor = editor; } - + @Override public Object getEditingCell() { return editingCell; } - + @Override public void startEditing(Object cell, EventObject evt) { if (editingCell != null) { stopEditing(true); } if (!graphComponent.getGraph().getModel().isEdge(cell)) { - Resource res = simulator.getCurState().getResource((String) ((mxCell) cell).getValue()); - ResourceIdentifier resId = res.getResourceIdentifier(); // clicked resource - ArrayList eventChs = new ArrayList<>(); // eventchannelList - ArrayList messages = new ArrayList<>(); // ADLmessage - ArrayList eventMessages = new ArrayList<>(); // messageList + ResourceIdentifier resId = res.getResourceIdentifier(); // clicked resource + ArrayList eventChs = new ArrayList<>(); // event channel list + ArrayList messageTexts = new ArrayList<>(); // message text list + ArrayList messageExps = new ArrayList<>(); // message expression list + ArrayList> refParams = new ArrayList<>(); // message parameters for ref ports ResourcePath eventResPath = null; - - for (Channel ch : simulator.getModel().getInputChannels()) { // all channels - eventResPath = getSelectableMessages(ch, resId, eventChs, messages, eventMessages, eventResPath); + + for (Channel ch: simulator.getModel().getInputChannels()) { // all channels + eventResPath = getSelectableMessages(ch, resId, eventChs, messageTexts, messageExps, refParams, eventResPath); } - - if (messages.isEmpty()) { + if (messageTexts.isEmpty()) { return; } - String[] eventList = messages.toArray(new String[messages.size()]); - JComboBox event = new JComboBox(eventList); + String[] messageList = messageTexts.toArray(new String[messageTexts.size()]); + JComboBox messageMenu = new JComboBox(messageList); - JPanel eventChoice = new JPanel(); - eventChoice.add(event); // FirstEventChoice + JPanel eventSelectPanel = new JPanel(); + eventSelectPanel.add(messageMenu); - int ret = JOptionPane.showConfirmDialog(window, eventChoice, "Event Choice", JOptionPane.OK_CANCEL_OPTION); + int ret = JOptionPane.showConfirmDialog(window, eventSelectPanel, "Event Choice", JOptionPane.OK_CANCEL_OPTION); // Select an event. if (ret == JOptionPane.OK_OPTION) { - - JPanel inputEvent = new JPanel(); - int i, eventNum; - i = eventNum = 0; - - for (String eventString : eventList) { - if (eventString.equals(event.getSelectedItem().toString())) { - eventNum = i; + int i, messageIdx; + i = messageIdx = 0; + for (String messageText : messageList) { + if(messageText.equals(messageMenu.getSelectedItem().toString())) { + messageIdx = i; } i++; } - - JTextArea textArea = new JTextArea(eventMessages.get(eventNum).toString(), 10, 30); // EventInput - inputEvent.add(textArea); - - int approve = JOptionPane.showConfirmDialog(window, inputEvent, "Event Code", JOptionPane.OK_CANCEL_OPTION); + JPanel inputEventPanel = new JPanel(); + JTextArea textArea = new JTextArea(messageExps.get(messageIdx).toString(), 10, 30); + inputEventPanel.add(textArea); + + int approve = JOptionPane.showConfirmDialog(window, inputEventPanel, "Event Code", JOptionPane.OK_CANCEL_OPTION); // Input an message text for the event. if (approve == JOptionPane.OK_OPTION) { try { - - TokenStream stream = new Parser.TokenStream(); - Parser parser = new Parser(stream); - stream.addLine(textArea.getText()); - Expression eventMessage = parser.parseTerm(stream, simulator.getModel()); - - Event newEvent = new Event(eventChs.get(eventNum), eventMessage, eventResPath, simulator.getCurState().getResource(resId)); - simulator.transition(newEvent); - - graphComponent.setCellEditor(new InputEventCellEditor(window, graphComponent, simulator, this.editor)); - + + TokenStream stream = new Parser.TokenStream(); + Parser parser = new Parser(stream); + stream.addLine(textArea.getText()); + Expression eventMessage = parser.parseTerm(stream, simulator.getModel()); + if (eventMessage instanceof Term) { + TreeMap refMap = refParams.get(messageIdx); + for (Integer paramIdx: refMap.keySet()) { + ((Term) eventMessage).getSymbol().setArity(-1); + ((Term) eventMessage).addChild(paramIdx, refMap.get(paramIdx), true); + } + } + + Event newEvent = new Event(eventChs.get(messageIdx), eventMessage, eventResPath, simulator.getCurState().getResource(resId)); + simulator.transition(newEvent); + + graphComponent.setCellEditor(new InputEventCellEditor(window, graphComponent, simulator, this.editor)); + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedRightBracket | - WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { + | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } @@ -134,12 +171,12 @@ // resource return; } - + mxCellState state = graphComponent.getGraph().getView().getState(cell); if (state != null && state.getLabel() != null && !state.getLabel().equals("")) { editingCell = cell; trigger = evt; - + double scale = Math.max(minimumEditorScale, graphComponent.getGraph().getView().getScale()); Object value = graphComponent.getGraph().getModel().getValue(cell); if (value != null && value instanceof PushPullAttribute) { @@ -154,45 +191,68 @@ } } } - + private ResourcePath getSelectableMessages(Channel ch, ResourceIdentifier resId, - ArrayList eventChs, ArrayList messages, ArrayList eventMessages, - ResourcePath eventResPath) { - if (((DataTransferChannel) ch).getInputResources().size() == 0) { // event ch or normal ch - for (ChannelMember out : ((DataTransferChannel) ch).getOutputChannelMembers()) { + ArrayList eventChs, ArrayList messageTexts, ArrayList messageExps, ArrayList> refParams, + ResourcePath eventResPath) { + if (((DataTransferChannel) ch).getInputResources().size() == 0) { // event ch. or normal ch. + for (ChannelMember out: ((DataTransferChannel) ch).getOutputChannelMembers()) { ResourcePath resPath = out.getResource(); - if (!out.isOutside() && resId.isInstanceOf(resPath)) { // account.uid == acounts.123 + if (!out.isOutside() && resId.isInstanceOf(resPath)) { eventResPath = resPath; eventChs.add(((DataTransferChannel) ch)); - String message = null; + String messageText = null; Expression mesExp = out.getStateTransition().getMessageExpression(); + TreeMap refMap = new TreeMap<>(); if (mesExp instanceof Term) { + // Reconstruct an input message template List pathParams = resPath.getPathParams(); List children = ((Term) mesExp).getChildren(); mesExp = new Term(((Term) mesExp).getSymbol()); - for (Expression child : children) { - if (!pathParams.contains(child)) { - ((Term) mesExp).addChild(child); + for (int i = 0; i < children.size(); i++) { + Expression child = children.get(i); + boolean isRefVar = false; + for (ChannelMember refCm: ((DataTransferChannel) ch).getReferenceChannelMembers()) { + if (refCm.getStateTransition().getMessageExpression() instanceof Term) { + Expression varExp = ((Term) refCm.getStateTransition().getMessageExpression()).getChild(i); + if (varExp != null && varExp instanceof Variable) { + if (refCm.getStateTransition().getCurStateExpression().contains(varExp)) { + // child has come from a reference resource. + isRefVar = true; + break; + } + } + } + } + if (!isRefVar) { + // child has not come from a reference resource. + if (!pathParams.contains(child)) { + ((Term) mesExp).addChild(child); + } else { + int idx = pathParams.indexOf(child); + ((Term) mesExp).addChild(resId.getPathParams().get(idx)); + } } else { - int idx = pathParams.indexOf(child); - ((Term) mesExp).addChild(resId.getPathParams().get(idx)); + // child has come from a reference resource. + refMap.put(i, child); } } - message = ((Term) mesExp).getSymbol().toString(); - } else if (mesExp instanceof Variable) { - message = ((Variable) mesExp).getName(); + messageText = ((Term) mesExp).getSymbol().toString(); + } else if(mesExp instanceof Variable) { + messageText = ((Variable) mesExp).getName(); } - eventMessages.add(mesExp); - messages.add(message); // for the pull-down menu + messageExps.add(mesExp); + messageTexts.add(messageText); // for the pull-down menu + refParams.add(refMap); } } - for (Channel childCh : ch.getChildren()) { - eventResPath = getSelectableMessages(childCh, resId, eventChs, messages, eventMessages, eventResPath); + for (Channel childCh: ch.getChildren()) { + eventResPath = getSelectableMessages(childCh, resId, eventChs, messageTexts, messageExps, refParams, eventResPath); } } return eventResPath; } - + @Override public void stopEditing(boolean cancel) { if (editingCell != null) { @@ -207,14 +267,14 @@ PushPullAttribute attr = (PushPullAttribute) value; List options = attr.getOptions(); PushPullValue selected = null; - for (PushPullValue option : options) { + for (PushPullValue option: options) { if (option.toString().equals(getCurrentValue())) { selected = option; break; } } if (selected != null) { - attr.selectOption(selected); + attr.selectOption(selected); } graphComponent.labelChanged(cell, attr, trig); } @@ -222,58 +282,58 @@ mxCellState state = graphComponent.getGraph().getView().getState(cell); graphComponent.redraw(state); } - + if (comboBox.getParent() != null) { comboBox.setVisible(false); comboBox.getParent().remove(comboBox); } - + graphComponent.requestFocusInWindow(); } } - + public String getCurrentValue() { return (String) comboBox.getSelectedItem(); } - + /** * Returns the bounds to be used for the editor. */ public Rectangle getEditorBounds(mxCellState state, double scale) { mxIGraphModel model = state.getView().getGraph().getModel(); Rectangle bounds = null; - + bounds = state.getLabelBounds().getRectangle(); bounds.height += 10; - + // Applies the horizontal and vertical label positions if (model.isVertex(state.getCell())) { String horizontal = mxUtils.getString(state.getStyle(), mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER); - + if (horizontal.equals(mxConstants.ALIGN_LEFT)) { bounds.x -= state.getWidth(); } else if (horizontal.equals(mxConstants.ALIGN_RIGHT)) { bounds.x += state.getWidth(); } - + String vertical = mxUtils.getString(state.getStyle(), mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE); - + if (vertical.equals(mxConstants.ALIGN_TOP)) { bounds.y -= state.getHeight(); } else if (vertical.equals(mxConstants.ALIGN_BOTTOM)) { bounds.y += state.getHeight(); } } - + bounds.setSize( (int) Math.max(bounds.getWidth(), Math.round(minimumWidth * scale)), (int) Math.max(bounds.getHeight(), Math.round(minimumHeight * scale))); - + return bounds; } - + }