diff --git a/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java b/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java index 1835abf..dfbbe9f 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java @@ -1,100 +1,86 @@ package application; -import javax.swing.JMenu; -import javax.swing.JMenuBar; - -import application.actions.CircleLayoutAction; -import application.actions.DAGLayoutAction; -import application.actions.DeleteAction; -import application.actions.ExitAction; -import application.actions.JavaPrototypeGenerateAction; -import application.actions.JerseyPrototypeGenerateAction; -import application.actions.NewChannelAction; -import application.actions.NewFormulaChannelAction; -import application.actions.NewIOChannelAction; -import application.actions.NewModelAction; -import application.actions.NewResourceAction; -import application.actions.OpenAction; -import application.actions.SaveAction; -import application.actions.SaveAsAction; -import application.actions.SimulateAction; -import application.actions.TreeLayoutAction; -import application.actions.ZoomInAction; -import application.actions.ZoomOutAction; +import application.actions.*; import application.editor.Editor; +import javax.swing.*; + public class ApplicationMenuBar extends JMenuBar { - private static final long serialVersionUID = 4811536194182272888L; + private static final long serialVersionUID = 4811536194182272888L; - private ApplicationWindow applicationWindow = null; - - private NewResourceAction newResourceAction = null; - private NewChannelAction newChannelAction = null; - private NewIOChannelAction newIOChannelAction = null; - private NewFormulaChannelAction newFormulaChannelAction = null; - private DeleteAction deleteAction = null; - private JavaPrototypeGenerateAction javaPrototypeGenerateAction = null; - private JerseyPrototypeGenerateAction jerseyPrototypeGenerateAction = null; - private DAGLayoutAction dagLayoutAction = null; - private TreeLayoutAction treeLayoutAction = null; - private CircleLayoutAction circleLayoutAction = null; - //private SimulateAction simulateAction = null; - + private ApplicationWindow applicationWindow = null; - public ApplicationMenuBar(ApplicationWindow applicationWindow) { - this.applicationWindow = applicationWindow; - JMenu newMenu = new JMenu("New"); - - newMenu.add(new NewModelAction(applicationWindow)); - - newMenu.add(newResourceAction = new NewResourceAction(applicationWindow.getEditor())); - newMenu.add(newChannelAction = new NewChannelAction(applicationWindow.getEditor())); - newMenu.add(newIOChannelAction = new NewIOChannelAction(applicationWindow.getEditor())); - newMenu.add(newFormulaChannelAction = new NewFormulaChannelAction(applicationWindow.getEditor())); - - JMenu menu = null; - menu = add(new JMenu("File")); - menu.add(newMenu); - menu.add(new OpenAction(applicationWindow)); - menu.addSeparator(); - menu.add(new SaveAction(applicationWindow)); - menu.add(new SaveAsAction(applicationWindow)); - menu.addSeparator(); - menu.add(new ExitAction()); - - menu = add(new JMenu("Edit")); - menu.add(deleteAction = new DeleteAction(applicationWindow.getEditor())); + private NewResourceAction newResourceAction = null; + private NewChannelAction newChannelAction = null; + private NewIOChannelAction newIOChannelAction = null; + private NewFormulaChannelAction newFormulaChannelAction = null; + private DeleteAction deleteAction = null; + private JavaPrototypeGenerateAction javaPrototypeGenerateAction = null; + private JerseyPrototypeGenerateAction jerseyPrototypeGenerateAction = null; + private DAGLayoutAction dagLayoutAction = null; + private TreeLayoutAction treeLayoutAction = null; + private CircleLayoutAction circleLayoutAction = null; + private ShowNavigationAction showNavigationAction; + //private SimulateAction simulateAction = null; - menu = add(new JMenu("Layout")); - menu.add(dagLayoutAction = new DAGLayoutAction(applicationWindow.getEditor())); - menu.add(treeLayoutAction = new TreeLayoutAction(applicationWindow.getEditor())); - menu.add(circleLayoutAction = new CircleLayoutAction(applicationWindow.getEditor())); + public ApplicationMenuBar(ApplicationWindow applicationWindow) { + this.applicationWindow = applicationWindow; + JMenu newMenu = new JMenu("New"); - menu = add(new JMenu("View")); - menu.add(new ZoomInAction(applicationWindow.getGraphComponent())); - menu.add(new ZoomOutAction(applicationWindow.getGraphComponent())); + newMenu.add(new NewModelAction(applicationWindow)); - menu = add(new JMenu("Simulate")); - menu.add(new SimulateAction(applicationWindow)); - - menu = add(new JMenu("Generate")); - menu.add(javaPrototypeGenerateAction = new JavaPrototypeGenerateAction(applicationWindow.getEditor())); - menu.add(jerseyPrototypeGenerateAction = new JerseyPrototypeGenerateAction(applicationWindow.getEditor())); - } + newMenu.add(newResourceAction = new NewResourceAction(applicationWindow.getEditor())); + newMenu.add(newChannelAction = new NewChannelAction(applicationWindow.getEditor())); + newMenu.add(newIOChannelAction = new NewIOChannelAction(applicationWindow.getEditor())); + newMenu.add(newFormulaChannelAction = new NewFormulaChannelAction(applicationWindow.getEditor())); - public Editor getEditor() { - return applicationWindow.getEditor(); - } + JMenu menu = null; + menu = add(new JMenu("File")); + menu.add(newMenu); + menu.add(new OpenAction(applicationWindow)); + menu.addSeparator(); + menu.add(new SaveAction(applicationWindow)); + menu.add(new SaveAsAction(applicationWindow)); + menu.addSeparator(); + menu.add(new ExitAction()); - public void setEditor(Editor editor) { - newResourceAction.setEditor(editor); - newChannelAction.setEditor(editor); - newIOChannelAction.setEditor(editor); - deleteAction.setEditor(editor); - javaPrototypeGenerateAction.setEditor(editor); - jerseyPrototypeGenerateAction.setEditor(editor); - treeLayoutAction.setEditor(editor); - circleLayoutAction.setEditor(editor); - } + menu = add(new JMenu("Edit")); + menu.add(deleteAction = new DeleteAction(applicationWindow.getEditor())); + + + menu = add(new JMenu("Layout")); + menu.add(dagLayoutAction = new DAGLayoutAction(applicationWindow.getEditor())); + menu.add(treeLayoutAction = new TreeLayoutAction(applicationWindow.getEditor())); + menu.add(circleLayoutAction = new CircleLayoutAction(applicationWindow.getEditor())); + + menu = add(new JMenu("View")); + menu.add(new ZoomInAction(applicationWindow.getGraphComponent())); + menu.add(new ZoomOutAction(applicationWindow.getGraphComponent())); + + menu = add(new JMenu("Simulate")); + menu.add(new SimulateAction(applicationWindow)); + + menu = add(new JMenu("Generate")); + menu.add(javaPrototypeGenerateAction = new JavaPrototypeGenerateAction(applicationWindow.getEditor())); + menu.add(jerseyPrototypeGenerateAction = new JerseyPrototypeGenerateAction(applicationWindow.getEditor())); + + menu = add(new JMenu("Window")); + menu.add(showNavigationAction = new ShowNavigationAction(applicationWindow)); + } + + public Editor getEditor() { + return applicationWindow.getEditor(); + } + + public void setEditor(Editor editor) { + newResourceAction.setEditor(editor); + newChannelAction.setEditor(editor); + newIOChannelAction.setEditor(editor); + deleteAction.setEditor(editor); + javaPrototypeGenerateAction.setEditor(editor); + jerseyPrototypeGenerateAction.setEditor(editor); + treeLayoutAction.setEditor(editor); + circleLayoutAction.setEditor(editor); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java index 63324d0..57fea37 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java @@ -1,97 +1,102 @@ package application; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.JFrame; - +import application.editor.Editor; +import application.views.NavigationWindow; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGeometry; import com.mxgraph.model.mxGraphModel; -import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.swing.handler.mxRubberband; -import com.mxgraph.swing.view.mxICellEditor; +import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.util.mxEvent; import com.mxgraph.util.mxEventObject; import com.mxgraph.util.mxEventSource.mxIEventListener; import com.mxgraph.view.mxGraph; -import application.editor.Editor; -import application.editor.DataTransferModelingCellEditor; +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; public class ApplicationWindow extends JFrame { - private static final long serialVersionUID = -8690140317781055614L; - public static final String title = "Visual Modeling Tool"; - - private Editor editor = null; - private mxGraph graph = null; - private mxGraphComponent graphComponent = null; - - private ApplicationMenuBar menuBar = null; + private static final long serialVersionUID = -8690140317781055614L; + public static final String title = "Visual Modeling Tool"; - public ApplicationWindow() { - setTitle(title); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - this.graph = new mxGraph() { - public boolean isPort(Object cell) { - mxGeometry geo = getCellGeometry(cell); - - return (geo != null) ? geo.isRelative() : false; - } - - public boolean isCellFoldable(Object cell, boolean collapse) { - return false; - } - }; - - this.graphComponent = new mxGraphComponent(graph); - - 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); - graph.setCellsDisconnectable(true); - - menuBar = new ApplicationMenuBar(this); - setJMenuBar(menuBar); - setSize(870, 640); - } + private Editor editor = null; + private mxGraph graph = null; + private mxGraphComponent graphComponent = null; - public mxGraph getGraph() { - return graph; - } + private ApplicationMenuBar menuBar = null; + private NavigationWindow navigationWindow; - public mxGraphComponent getGraphComponent() { - return graphComponent; - } + public ApplicationWindow() { + setTitle(title); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - public Editor getEditor() { - return editor; - } + this.graph = new mxGraph() { + public boolean isPort(Object cell) { + mxGeometry geo = getCellGeometry(cell); + return (geo != null) ? geo.isRelative() : false; + } - public void setEditor(Editor editor) { - this.editor = editor; - } + public boolean isCellFoldable(Object cell, boolean collapse) { + return false; + } + }; + this.graphComponent = new mxGraphComponent(graph); + + 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); + graph.setCellsDisconnectable(true); + + menuBar = new ApplicationMenuBar(this); + setJMenuBar(menuBar); + setSize(870, 640); + setLocationRelativeTo(null); // Center on screen + + navigationWindow = new NavigationWindow(this, editor); + navigationWindow.setVisible(true); + editor.addStageChangeListener(navigationWindow); + } + + public mxGraph getGraph() { + return graph; + } + + public mxGraphComponent getGraphComponent() { + return graphComponent; + } + + public Editor getEditor() { + return editor; + } + + public void setEditor(Editor editor) { + this.editor = editor; + } + + public void showNavigationWindow() { + navigationWindow.setVisible(true); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/NewResourceAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/NewResourceAction.java index b01fc46..bd9aad2 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/actions/NewResourceAction.java +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/NewResourceAction.java @@ -1,28 +1,24 @@ package application.actions; -import java.awt.event.ActionEvent; - -import javax.swing.JOptionPane; - import application.editor.Editor; -import models.dataConstraintModel.ResourcePath; + +import javax.swing.*; +import java.awt.event.ActionEvent; public class NewResourceAction extends AbstractEditorAction { - /** - * - */ - private static final long serialVersionUID = -4439207504700741286L; + private static final long serialVersionUID = -4439207504700741286L; - public NewResourceAction(Editor editor) { - super("Resource...", editor); - } + public NewResourceAction(Editor editor) { + super("Resource...", editor); + } - @Override - public void actionPerformed(ActionEvent e) { - String resName = JOptionPane.showInputDialog("Resourece Name:"); - if (resName == null) return; - editor.addResourcePath(null, resName); - } - + @Override + public void actionPerformed(ActionEvent e) { + String resName = JOptionPane.showInputDialog("Resource Name:"); + if (resName == null) { + return; + } + editor.addResourcePath(null, resName); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/OpenAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/OpenAction.java index d01c518..90f3ca1 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/actions/OpenAction.java +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/OpenAction.java @@ -1,62 +1,63 @@ package application.actions; -import java.awt.event.ActionEvent; -import java.io.File; - -import javax.swing.JFileChooser; -import javax.swing.filechooser.FileFilter; -import javax.swing.filechooser.FileNameExtensionFilter; - import application.ApplicationWindow; import application.editor.Editor; +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.event.ActionEvent; +import java.io.File; + public class OpenAction extends AbstractSystemAction { - /** - * - */ - private static final long serialVersionUID = -8290761032629599683L; - - private String lastDir = null; - - public OpenAction(ApplicationWindow frame) { - super("Open...", frame); - } - @Override - public void actionPerformed(ActionEvent e) { - Editor editor = frame.getEditor(); - if (editor != null) { - String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); + private static final long serialVersionUID = -8290761032629599683L; - JFileChooser fc = new JFileChooser(wd); + private String lastDir = null; - FileFilter model = new FileNameExtensionFilter("model","model"); - FileFilter dtram = new FileNameExtensionFilter("dtram", "dtram"); - - // Adds file filter for supported file format - FileFilter defaultFilter = new FileFilter() { + public OpenAction(ApplicationWindow frame) { + super("Open...", frame); + } - public boolean accept(File file) { - String lcase = file.getName().toLowerCase(); - return lcase.endsWith(".model"); - } + @Override + public void actionPerformed(ActionEvent e) { + Editor editor = frame.getEditor(); + if (editor == null) { + return; + } + String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); - @Override - public String getDescription() { - return null; - } - }; - - fc.addChoosableFileFilter(defaultFilter); - fc.addChoosableFileFilter(model); - fc.addChoosableFileFilter(dtram); - int rc = fc.showDialog(null, "Open Model File"); - if (rc == JFileChooser.APPROVE_OPTION) { - lastDir = fc.getSelectedFile().getParent(); - editor.open(fc.getSelectedFile()); - frame.setTitle(frame.title + " - " + fc.getSelectedFile().getAbsolutePath()); - } - } - } + JFileChooser fc = buildFileChooser(wd); + int option = fc.showDialog(null, "Open Model File"); + if (option == JFileChooser.APPROVE_OPTION) { + lastDir = fc.getSelectedFile().getParent(); + editor.open(fc.getSelectedFile()); + frame.setTitle(ApplicationWindow.title + " - " + fc.getSelectedFile().getAbsolutePath()); + } + } + private static JFileChooser buildFileChooser(String wd) { + JFileChooser fc = new JFileChooser(wd); + + FileFilter model = new FileNameExtensionFilter("model", "model"); + FileFilter dtram = new FileNameExtensionFilter("dtram", "dtram"); + + // Adds file filter for supported file format + FileFilter defaultFilter = new FileFilter() { + public boolean accept(File file) { + String lowerCase = file.getName().toLowerCase(); + return lowerCase.endsWith(".model"); + } + + @Override + public String getDescription() { + return null; + } + }; + + fc.addChoosableFileFilter(defaultFilter); + fc.addChoosableFileFilter(model); + fc.addChoosableFileFilter(dtram); + return fc; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java new file mode 100644 index 0000000..0dc4b9e --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java @@ -0,0 +1,17 @@ +package application.actions; + +import application.ApplicationWindow; + +import java.awt.event.ActionEvent; + +public class ShowNavigationAction extends AbstractSystemAction { + + public ShowNavigationAction(ApplicationWindow frame) { + super("Show Navigation", frame); + } + + @Override + public void actionPerformed(ActionEvent e) { + frame.showNavigationWindow(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/DataTransferModelingCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/DataTransferModelingCellEditor.java deleted file mode 100644 index fa88e8d..0000000 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/DataTransferModelingCellEditor.java +++ /dev/null @@ -1,250 +0,0 @@ -package application.editor; - -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Rectangle; -import java.util.EventObject; -import java.util.List; - -import javax.swing.BorderFactory; -import javax.swing.JComboBox; -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.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.Expression; -import models.dataFlowModel.DataTransferModel; -import models.dataFlowModel.DataTransferChannel; -import models.dataFlowModel.PushPullAttribute; -import models.dataFlowModel.PushPullValue; -import models.visualModel.FormulaChannel; -import parser.Parser; -import parser.Parser.TokenStream; -import parser.exceptions.ExpectedColon; -import parser.exceptions.ExpectedRightBracket; -import parser.exceptions.WrongJsonExpression; - -public class DataTransferModelingCellEditor implements mxICellEditor { - public int DEFAULT_MIN_WIDTH = 70; - public int DEFAULT_MIN_HEIGHT = 30; - public double DEFAULT_MINIMUM_EDITOR_SCALE = 1; - - protected double minimumEditorScale = DEFAULT_MINIMUM_EDITOR_SCALE; - protected int minimumWidth = DEFAULT_MIN_WIDTH; - protected int minimumHeight = DEFAULT_MIN_HEIGHT; - - private Object editingCell; - private EventObject trigger; - private JComboBox comboBox; - private mxGraphComponent graphComponent; - private Editor editor; - - public DataTransferModelingCellEditor(mxGraphComponent graphComponent, Editor editor) { - this.graphComponent = graphComponent; - 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)) { - DataTransferModel model = editor.getModel(); - DataTransferChannel ch = (DataTransferChannel) model.getChannel((String) ((mxCell) cell).getValue()); - if (ch == null) { - ch = (DataTransferChannel) model.getInputChannel((String) ((mxCell) cell).getValue()); - if(ch == null) { - //resource - return; - } - } - - if(ch instanceof FormulaChannel) { - - JPanel panel = new JPanel(); - JLabel label1 = new JLabel("Formula: "); - JLabel label2 = new JLabel("Source: "); - GridBagLayout layout = new GridBagLayout(); - panel.setLayout(layout); - GridBagConstraints gbc = new GridBagConstraints(); - - gbc.gridx = 0; - gbc.gridy = 0; - layout.setConstraints(label1, gbc); - panel.add(label1); - - gbc.gridx = 1; - gbc.gridy = 0; - JTextField formulaText = new JTextField(((FormulaChannel) ch).getFormula(),15); - layout.setConstraints(formulaText, gbc); - panel.add(formulaText); - - gbc.gridx = 0; - gbc.gridy = 1; - layout.setConstraints(label2, gbc); - panel.add(label2); - - gbc.gridx = 1; - gbc.gridy = 1; - JTextArea textArea = new JTextArea(ch.getSourceText(),7,15); - textArea.setEditable(false); - layout.setConstraints(textArea, gbc); - panel.add(textArea); - - int r = JOptionPane.showConfirmDialog( - null, // owner window - panel, // message - "Edit Formula Channel", // window's title - JOptionPane.OK_CANCEL_OPTION, // option (button types) - JOptionPane.QUESTION_MESSAGE); // message type (icon types) - if(r == JOptionPane.OK_OPTION) { - TokenStream stream = new Parser.TokenStream(); - Parser parser = new Parser(stream); - - String formula = formulaText.getText(); - stream.addLine(formula.split(Parser.EQUALS)[1]); - - try { - Expression exp = parser.parseTerm(stream, editor.getModel()); - ((FormulaChannel) ch).setFormula(formula); - ((FormulaChannel) ch).setFormulaTerm(exp); - } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - } - } - }else { - JPanel panel = new JPanel(); - JTextArea textArea = new JTextArea(ch.getSourceText(), 10, 20); - panel.add(textArea); - // JEditorPane panel = new JEditorPane("text/plain", ch.toString()); - // panel.setEditable(true); - int ret = JOptionPane.showConfirmDialog(null, panel, "Channel Code", JOptionPane.OK_CANCEL_OPTION); - if (ret == JOptionPane.OK_OPTION) { - editor.setChannelCode(ch, textArea.getText()); - } - } - 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) { - PushPullAttribute attr = (PushPullAttribute) value; - comboBox = new JComboBox<>(attr.getOptionStrings()); - comboBox.setBorder(BorderFactory.createEmptyBorder()); - comboBox.setOpaque(false); - comboBox.setBounds(getEditorBounds(state, scale)); - comboBox.setVisible(true); - graphComponent.getGraphControl().add(comboBox, 0); - comboBox.updateUI(); - } - } - } - - @Override - public void stopEditing(boolean cancel) { - if (editingCell != null) { - comboBox.transferFocusUpCycle(); - Object cell = editingCell; - editingCell = null; - if (!cancel) { - EventObject trig = trigger; - trigger = null; - Object value = graphComponent.getGraph().getModel().getValue(cell); - if (value != null && value instanceof PushPullAttribute) { - PushPullAttribute attr = (PushPullAttribute) value; - List options = attr.getOptions(); - PushPullValue selected = null; - for (PushPullValue option: options) { - if (option.toString().equals(getCurrentValue())) { - selected = option; - break; - } - } - if (selected != null) { - options.remove(selected); - options.add(0, selected); - } - graphComponent.labelChanged(cell, attr, trig); - } - } else { - 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; - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java index 6fe7965..66107cf 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java @@ -1,833 +1,473 @@ package application.editor; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.AbstractMap; -import java.util.AbstractMap.SimpleEntry; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - +import application.editor.stages.DataFlowModelingStage; +import application.editor.stages.PushPullSelectionStage; +import application.layouts.DAGLayout; +import code.ast.CompilationUnit; import com.mxgraph.layout.mxCircleLayout; import com.mxgraph.layout.mxCompactTreeLayout; import com.mxgraph.model.mxCell; -import com.mxgraph.model.mxGeometry; -import com.mxgraph.model.mxGraphModel; -import com.mxgraph.model.mxICell; -import com.mxgraph.model.mxIGraphModel; import com.mxgraph.swing.mxGraphComponent; -import com.mxgraph.util.mxConstants; -import com.mxgraph.util.mxPoint; +import com.mxgraph.util.mxEvent; +import com.mxgraph.util.mxEventSource.mxIEventListener; import com.mxgraph.view.mxCellState; -import com.mxgraph.util.mxRectangle; import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxGraphView; - -import algorithms.DataTransferModelAnalyzer; -import algorithms.Validation; -import application.layouts.*; -import code.ast.CompilationUnit; -import generators.JavaCodeGenerator; -import models.Edge; import models.EdgeAttribute; -import models.Node; -import models.algebra.Expression; -import models.algebra.InvalidMessage; -import models.algebra.ParameterizedIdentifierIsFutureWork; -import models.algebra.UnificationFailed; -import models.algebra.ValueUndefined; import models.dataConstraintModel.Channel; -import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.DataConstraintModel; -import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; -import models.dataConstraintModel.Selector; -import models.dataFlowModel.DataTransferModel; -import models.dataFlowModel.DataTransferChannel; -import models.dataFlowModel.PushPullAttribute; -import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; -import models.dataFlowModel.ChannelNode; -import models.dataFlowModel.DataFlowEdge; import models.dataFlowModel.DataFlowGraph; -import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.DataTransferModel; import models.visualModel.FormulaChannel; import parser.Parser; -import parser.Parser.TokenStream; -import parser.exceptions.ExpectedAssignment; -import parser.exceptions.ExpectedChannel; -import parser.exceptions.ExpectedChannelName; -import parser.exceptions.ExpectedColon; -import parser.exceptions.ExpectedEquals; -import parser.exceptions.ExpectedFormulaChannel; -import parser.exceptions.ExpectedGeometry; -import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; -import parser.exceptions.ExpectedIoChannel; -import parser.exceptions.ExpectedLeftCurlyBracket; -import parser.exceptions.ExpectedModel; -import parser.exceptions.ExpectedNode; -import parser.exceptions.ExpectedRHSExpression; -import parser.exceptions.ExpectedResource; -import parser.exceptions.ExpectedRightBracket; -import parser.exceptions.ExpectedStateTransition; -import parser.exceptions.WrongJsonExpression; -import parser.exceptions.WrongLHSExpression; -import parser.exceptions.WrongRHSExpression; -import parser.exceptions.ExpectedRightCurlyBracket; -import parser.exceptions.WrongPathExpression; import parser.ParserDTRAM; +import parser.exceptions.*; + +import java.awt.event.MouseListener; +import java.io.*; +import java.util.ArrayList; +import java.util.List; public class Editor { - final int PORT_DIAMETER = 8; - final int PORT_RADIUS = PORT_DIAMETER / 2; - protected DataTransferModel model = null; - protected mxGraph graph = null; - private mxGraphComponent graphComponent = null; + protected DataTransferModel model = null; - protected DataFlowGraph dataFlowGraph = null; + protected mxGraph graph; + private final mxGraphComponent graphComponent; - protected String curFileName = null; - protected String curFilePath = null; - protected ArrayList codes = null; - - private boolean bReflectingArchitectureModel = false; + protected Stage curStage; + private final List stageChangeListeners; - public Editor(mxGraphComponent graphComponent) { - this.graphComponent = graphComponent; - this.graph = graphComponent.getGraph(); - - graphComponent.setCellEditor(new DataTransferModelingCellEditor(graphComponent, this)); - } + private mxIEventListener curChangeEventListener = null; + private MouseListener curMouseEventListener = null; - public mxGraph getGraph() { - return graph; - } + protected String curFileName = null; + protected String curFilePath = null; + protected ArrayList codes = null; - public mxGraphComponent getGraphComponent() { - return this.graphComponent; - } + public static DataFlowModelingStage STAGE_DATA_FLOW_MODELING = null; + public static PushPullSelectionStage STAGE_PUSH_PULL_SELECTION = null; - public DataTransferModel getModel() { - if (model == null) { - model = new DataTransferModel(); - } - return model; - } + public Editor(mxGraphComponent graphComponent) { + this.graphComponent = graphComponent; + this.graph = graphComponent.getGraph(); - public DataFlowGraph getDataFlowGraph() { - if (dataFlowGraph == null) { - analyzeDataTransferModel(getModel()); - updateEdgeAttiributes(dataFlowGraph); - } - return dataFlowGraph; - } + STAGE_DATA_FLOW_MODELING = new DataFlowModelingStage(graphComponent); + STAGE_PUSH_PULL_SELECTION = new PushPullSelectionStage(graphComponent); - public DataFlowGraph analyzeDataTransferModel(DataTransferModel model) { - DataFlowGraph flowGraph = DataTransferModelAnalyzer.createDataFlowGraphWithStateStoringAttribute(model); - dataFlowGraph = DataTransferModelAnalyzer.annotateWithSelectableDataTransferAttiribute(flowGraph); - return dataFlowGraph; - } + graphComponent.setCellEditor(STAGE_DATA_FLOW_MODELING.createCellEditor(graphComponent)); - public void resetDataFlowGraph() { - dataFlowGraph = null; - } + curStage = STAGE_DATA_FLOW_MODELING; - public void setDataFlowGraph(DataFlowGraph dataFlowGraph) { - this.dataFlowGraph = dataFlowGraph; - } + stageChangeListeners = new ArrayList<>(); + } - public ArrayList getCodes() { - return codes; - } + public boolean canChange(Stage nextStage) { + return nextStage.canChangeFrom(curStage); + } - public void setCodes(ArrayList codes) { - this.codes = codes; - } + public boolean changeStage(Stage nextStage) { + if (!nextStage.canChangeFrom(curStage)) { + return false; + } + nextStage.init(curStage); + graphComponent.setCellEditor(nextStage.createCellEditor(graphComponent)); - public String getCurFileName() { - return curFileName; - } + // add listeners + // "curChangeEventListener" will be called when updating the mxGraph. + if (curChangeEventListener != null) { + graph.getModel().removeListener(curChangeEventListener); + } + curChangeEventListener = nextStage.createChangeEventListener(this); + if (curChangeEventListener != null) { + graph.getModel().addListener(mxEvent.CHANGE, curChangeEventListener); + } - public String getCurFilePath() { - return curFilePath; - } + // A handler of a mouse event. + if (curMouseEventListener != null) { + graphComponent.getGraphControl().removeMouseListener(curMouseEventListener); + } + curMouseEventListener = nextStage.createMouseEventListener(this); + if (curMouseEventListener != null) { + graphComponent.getGraphControl().addMouseListener(curMouseEventListener); + } + curStage = nextStage; + notifyStageChangeListeners(); + return true; + } - public void setCurFilePath(String curFilePath) { - this.curFilePath = curFilePath; - this.curFileName = new File(curFilePath).getName(); - } + public void addStageChangeListener(IStageChangeListener stageChangeListener) { + stageChangeListeners.add(stageChangeListener); + } - public void clear() { - model = null; - ((mxGraphModel) graph.getModel()).clear(); - dataFlowGraph = null; - curFilePath = null; - curFileName = null; - codes = null; - } + private void notifyStageChangeListeners() { + for (IStageChangeListener l : stageChangeListeners) { + l.stageChanged(curStage); + } + } - /** - * Open a given file, parse the file, construct a DataFlowModel and a mxGraph - * @param file given file - * @return a constructed DataFlowModel - */ - public DataTransferModel open(File file) { - try { + public DataFlowGraph getDataFlowGraph() { + if (curStage instanceof PushPullSelectionStage) { + return ((PushPullSelectionStage) curStage).getDataFlowGraph(); + } + return null; + } - String extension =""; - if(file != null && file.exists()) { - // get a file's name - String name = file.getName(); + public void setCurFilePath(String curFilePath) { + this.curFilePath = curFilePath; + this.curFileName = new File(curFilePath).getName(); + } - // get a file's extension - extension = name.substring(name.lastIndexOf(".")); - } - if(extension.contains(".model")) { - openModel(file); - } else { - ParserDTRAM parserDTRAM = new ParserDTRAM(new BufferedReader(new FileReader(file))); - try { - // Parse the .dtram file. - model = parserDTRAM.doParseModel(); - - // Analyze the model. - if (!Validation.checkUpdateConflict(model)) return null; - DataFlowGraph dataFlowGraph = analyzeDataTransferModel(model); - - // Visualize the model. - graph = constructGraph(model, dataFlowGraph); - parserDTRAM.doParseGeometry(graph); - updateEdgeAttiributes(dataFlowGraph); - - curFilePath = file.getAbsolutePath(); - curFileName = file.getName(); - return model; - } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword - | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedModel - | ExpectedGeometry | ExpectedNode | ExpectedResource | ExpectedFormulaChannel | ExpectedIoChannel - | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } + public void clear() { + // Force to change to the data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).clear(); - return null; - } + model = null; + curFilePath = null; + curFileName = null; + codes = null; + } - public DataTransferModel openModel(File file) { - try { + /** + * Open a given file, parse the file, construct a DataFlowModel and a mxGraph + * + * @param file given file + */ + public void open(File file) { + // Force to change to data-modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) { + return; + } + if (file == null || !file.exists()) { + return; + } + // get a file's extension + String extension = file.getName().substring(file.getName().lastIndexOf(".")); + if (extension.contains(".model")) { + openModel(file); + } + if (extension.contains(".dtram")) { + openDTRAM(file); + } + } - Parser parser = new Parser(new BufferedReader(new FileReader(file))); + private void openModel(File file) { + try { + Parser parser = new Parser(new BufferedReader(new FileReader(file))); + try { + // Parse the .model file. + model = parser.doParse(); - try { - // Parse the .model file. - model = parser.doParse(); - - // Analyze the model. - if (!Validation.checkUpdateConflict(model)) return null; - DataFlowGraph dataFlowGraph = analyzeDataTransferModel(model); - - // Visualize the model. - graph = constructGraph(model, dataFlowGraph); - updateEdgeAttiributes(dataFlowGraph); - - // Set DAG layout. -// setDAGLayout(); - - curFilePath = file.getAbsolutePath(); - curFileName = file.getName(); - return model; - } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword - | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return null; - } + // Update stage's model to new parsed one + if (curStage instanceof DataFlowModelingStage) { + ((DataFlowModelingStage) curStage).setModel(model); + } - /**-------------------------------------------------------------------------------- - * save - /**-------------------------------------------------------------------------------- - * - */ - public void save() { - if (curFilePath != null) { - try { - File file = new File(curFilePath); - String extension = ""; - if(file != null && file.exists()) { - // get a file's name - String name = file.getName(); + // Force to change PushPullSelectionStage to construct mxGraph + boolean stageChanged = changeStage(STAGE_PUSH_PULL_SELECTION); + if (stageChanged && curStage instanceof PushPullSelectionStage) { + ((PushPullSelectionStage) curStage).constructGraph(); + } - // get a file's extension - extension = name.substring(name.lastIndexOf(".")); - } - if(extension.contains(".model")) { - saveModel(file); - } else { - FileWriter filewriter = new FileWriter(file); - filewriter.write(toOutputString()); - filewriter.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - } + // Set layout + setDAGLayout(); - public void saveModel(File file) { - if (curFilePath != null) { - try { - FileWriter filewriter = new FileWriter(file); - filewriter.write(model.getSourceText()); - filewriter.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } + // Update current file info + curFilePath = file.getAbsolutePath(); + curFileName = file.getName(); + } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | + ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | + ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | + ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | + ExpectedColon | ExpectedDoubleQuotation e) { + e.printStackTrace(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } - /**-------------------------------------------------------------------------------- - * get writing texts "dtram" file information is written. - * - * @return formatted "dtram" info texts. - */ - protected String toOutputString() { - String fileString = ""; - - fileString += "model {\n"; - fileString += this.model.getSourceText(); - fileString += "}\n"; + private void openDTRAM(File file) { + try { + ParserDTRAM parser = new ParserDTRAM(new BufferedReader(new FileReader(file))); + try { + // Parse the .dtram file. + model = parser.doParseModel(); - fileString += "geometry {\n"; + // Update stage's model to new parsed one + if (curStage instanceof DataFlowModelingStage) { + ((DataFlowModelingStage) curStage).setModel(model); + } - Object root = graph.getDefaultParent(); - for (int i = 0; i < graph.getModel().getChildCount(root); i++) { - Object cell = graph.getModel().getChildAt(root, i); - if (graph.getModel().isVertex(cell)) { - mxGraphView view = graph.getView(); - mxCellState state = view.getState(cell); - int x = (int) state.getX(); - int y = (int) state.getY(); - int w = (int) state.getWidth(); - int h = (int) state.getHeight(); + // Force to change PushPullSelectionStage to construct mxGraph + boolean stageChanged = changeStage(STAGE_PUSH_PULL_SELECTION); + if (stageChanged && curStage instanceof PushPullSelectionStage) { + ((PushPullSelectionStage) curStage).constructGraph(); + } - for(Channel ch: model.getChannels()) { - if(ch instanceof FormulaChannel && state.getLabel().equals(ch.getChannelName())) { - fileString += "\tnode fc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; - } else if(ch instanceof Channel && state.getLabel().equals(ch.getChannelName())) { - fileString +="\tnode c " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; - } - } + // Restore the geometry + parser.doParseGeometry(graph); - for (ResourcePath res: model.getResourcePaths()){ - if(res instanceof ResourcePath && state.getLabel().equals(res.getLeafResourceName())) - fileString += "\tnode r " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"; - } + // Update current file info + curFilePath = file.getAbsolutePath(); + curFileName = file.getName(); + } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | + ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | + ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | + ExpectedAssignment | ExpectedModel | ExpectedGeometry | ExpectedNode | ExpectedResource | + ExpectedFormulaChannel | ExpectedIoChannel | ExpectedRightCurlyBracket | WrongPathExpression | + WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { + e.printStackTrace(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } - for (Channel ioC: model.getInputChannels()) { - if(ioC instanceof Channel && state.getLabel().equals(ioC.getChannelName())) { - fileString += "\tnode ioc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"; - } - } - } - } - fileString += "}\n"; - - return fileString; - } - - /** - * Construct a mxGraph from DataFlowModel and DataFlowModel - * @param model - * @param dataFlowGraph - * @return constructed mxGraph - */ - public mxGraph constructGraph(DataTransferModel model, DataFlowGraph dataFlowGraph) { - bReflectingArchitectureModel = true; - ((mxGraphModel) graph.getModel()).clear(); - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - mxGeometry geo1 = new mxGeometry(0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo1.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo1.setRelative(true); + public void save() { + if (curFilePath == null) { + return; + } + File file = new File(curFilePath); + if (!file.exists()) { + return; + } + // get a file's extension + String extension = file.getName().substring(file.getName().lastIndexOf(".")); + if (extension.contains(".model")) { + saveModel(file); + } + if (extension.contains(".dtram")) { + saveDTRAM(file); + } + } - mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo2.setRelative(true); + private void saveModel(File file) { + try { + FileWriter filewriter = new FileWriter(file); + filewriter.write(model.getSourceText()); + filewriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } - Map channelsIn = new HashMap<>(); - Map channelsOut = new HashMap<>(); - Map resources = new HashMap<>(); + private void saveDTRAM(File file) { + try { + FileWriter filewriter = new FileWriter(file); + filewriter.write(toOutputString()); + filewriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } - // create resource vertices - for (ResourceNode resNode: dataFlowGraph.getRootResourceNodes()) { - int w = 80; - int h = 30; - ResourcePath res = resNode.getPrimaryResourcePath(); - Object resource = graph.insertVertex(parent, null, - res.getLeafResourceName(), 20, 20, w, h, - "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - resources.put(resNode, resource); - createChildResourceVerticies(resource, resNode, resources, w, h); - } - - // create channel vertices - for (ChannelNode c: dataFlowGraph.getRootChannelNodes()) { - DataTransferChannel channel = (DataTransferChannel) c.getChannel(); - if (channel.getInputResources().size() > 0) { - // Normal channel - if (channelsIn.get(channel) == null || channelsOut.get(channel) == null) { - if (channel.getSelectors().toString() == "[]") { - Object chCell = graph.insertVertex(parent, null, channel.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex - mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); - port_in.setVertex(true); - graph.addCell(port_in, chCell); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, chCell); // insert the output port of a channel - channelsIn.put(channel, port_in); - channelsOut.put(channel, port_out); - } else { - for (Selector s: channel.getSelectors()) { - Expression exp = s.getExpression(); - String selName = exp.toString(); - String cName = channel.getChannelName(); - String channelName = cName + " (" + selName + ")"; - Object chCell = graph.insertVertex(parent, null, channelName, 150, 20, 60, 30); // insert a channel as a vertex - mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); - port_in.setVertex(true); - graph.addCell(port_in, chCell); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, chCell); // insert the output port of a channel - channelsIn.put(channel, port_in); - channelsOut.put(channel, port_out); - } - } - } - } else { - // I/O channel - if (channelsOut.get(channel) == null) { - if (channel.getSelectors().toString() == "[]") { - Object chCell = graph.insertVertex(parent, null, channel.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex - mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); - port_in.setVertex(true); - graph.addCell(port_in, chCell); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, chCell); // insert the output port of a channel - channelsIn.put(channel, port_in); - channelsOut.put(channel, port_out); - } else { - for (Selector s: channel.getSelectors()) { - Expression exp = s.getExpression(); - String selName = exp.toString(); - String cName = channel.getChannelName(); - String channelName = cName + " (" + selName + ")"; - Object chCell = graph.insertVertex(parent, null, channelName, 150, 20, 60, 30); // insert a channel as a vertex - mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); - port_in.setVertex(true); - graph.addCell(port_in, chCell); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, chCell); // insert the output port of a channel - channelsIn.put(channel, port_in); - channelsOut.put(channel, port_out); - } - } - } - } - } - - // add input, output and reference edges - for (Edge edge: dataFlowGraph.getEdges()) { - DataFlowEdge dfEdge = (DataFlowEdge) edge; - if (dfEdge.isChannelToResource()) { - // output edge - DataTransferChannel channel = ((ChannelNode) dfEdge.getSource()).getChannel(); - ResourcePath dstRes = ((ResourceNode) dfEdge.getDestination()).getInSideResource(channel); - graph.insertEdge(parent, null, new SrcDstAttribute(channel, dstRes), channelsOut.get(channel), resources.get((ResourceNode) dfEdge.getDestination()), "movable=false"); - } else { - // input edge - DataTransferChannel channel = ((ChannelNode) dfEdge.getDestination()).getChannel(); - ResourcePath srcRes = ((ResourceNode) dfEdge.getSource()).getOutSideResource(channel); - Set> toRes = getResourceDependencyForChannel(channel, model, dataFlowGraph); - for(Map.Entry RtoR: toRes) { - graph.insertEdge(parent, null, null, - resources.get(RtoR.getValue()), - resources.get(RtoR.getKey()), "dashed=true;movable=false"); - } - - graph.insertEdge(parent, null, new SrcDstAttribute(srcRes, channel), resources.get((ResourceNode) dfEdge.getSource()), channelsIn.get(channel), "movable=false"); - } - } - - for (Channel ch: model.getChannels()) { - // reference edges - DataTransferChannel channel = (DataTransferChannel) ch; - for (ResourcePath refRes: channel.getReferenceResources()) { - graph.insertEdge(parent, null, null, resources.get(dataFlowGraph.getResourceNode(refRes)), channelsIn.get(channel), "dashed=true;movable=false"); - } - } - } finally { - graph.getModel().endUpdate(); - } - setDAGLayout(); - - bReflectingArchitectureModel = false; - return graph; - } + /** + * get writing texts "dtram" file information is written. + * + * @return formatted "dtram" info texts. + */ + private String toOutputString() { + StringBuilder fileString = new StringBuilder(); - public void createChildResourceVerticies(Object resource, ResourceNode resNode, Map resources, int w, int h) { - - for (ResourceNode childNode: resNode.getChildren()) { - ResourcePath childRes = childNode.getPrimaryResourcePath(); - Object childResource = graph.insertVertex(resource, null, - childRes.getName(), 0, 0, w, h, - "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - resources.put(childNode, childResource); - createChildResourceVerticies(childResource, childNode, resources, w, h); - } - } - - public void setDAGLayout() { - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - DAGLayout ctl = new DAGLayout(graph); - ctl.execute(parent); - } finally { - graph.getModel().endUpdate(); - } - } + fileString.append("model {\n"); + fileString.append(model.getSourceText()); + fileString.append("}\n"); - public void updateEdgeAttiributes(DataFlowGraph dataFlowGraph) { - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - // add input, output and reference edges - for (Edge e : dataFlowGraph.getEdges()) { - if (e instanceof DataFlowEdge) { - DataFlowEdge dataFlow = (DataFlowEdge) e; - if (!dataFlow.isChannelToResource()) { - ResourceNode srcRes = (ResourceNode) dataFlow.getSource(); - DataTransferChannel channel = ((ChannelNode) dataFlow.getDestination()).getChannel(); - // input edge - for (Object edge: graph.getChildEdges(parent)) { - mxCell edgeCell = (mxCell) edge; - if (edgeCell.getValue() instanceof SrcDstAttribute) { - SrcDstAttribute edgeAttr = (SrcDstAttribute) edgeCell.getValue(); - if (srcRes.getPrimaryResourcePath().equals(edgeAttr.getSource()) && channel.equals(edgeAttr.getDestination())) { - edgeCell.setValue(dataFlow.getAttribute()); - break; - } - } - } - } - } - } - } finally { - graph.getModel().endUpdate(); - } - graph.refresh(); - } + fileString.append("geometry {\n"); - public void setTreeLayout() { - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - mxCompactTreeLayout ctl = new mxCompactTreeLayout(graph); - ctl.setLevelDistance(100); - // ctl.setHorizontal(false); - ctl.setEdgeRouting(false); - ctl.execute(parent); - } finally { - graph.getModel().endUpdate(); - } - } + Object root = graph.getDefaultParent(); + for (int i = 0; i < graph.getModel().getChildCount(root); i++) { + Object cell = graph.getModel().getChildAt(root, i); + if (graph.getModel().isVertex(cell)) { + mxGraphView view = graph.getView(); + mxCellState state = view.getState(cell); + int x = (int) state.getX(); + int y = (int) state.getY(); + int w = (int) state.getWidth(); + int h = (int) state.getHeight(); - public void setCircleLayout() { - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - mxCircleLayout ctl = new mxCircleLayout(graph); - ctl.execute(parent); - } finally { - graph.getModel().endUpdate(); - } - } + for (Channel ch : model.getChannels()) { + if (ch instanceof FormulaChannel && state.getLabel().equals(ch.getChannelName())) { + fileString.append("\tnode fc ").append(state.getLabel()).append(":").append(x).append(",").append(y).append(",").append(w).append(",").append(h).append("\n"); + } else if (ch != null && state.getLabel().equals(ch.getChannelName())) { + fileString.append("\tnode c ").append(state.getLabel()).append(":").append(x).append(",").append(y).append(",").append(w).append(",").append(h).append("\n"); + } + } - public ResourcePath addResourcePath(ResourcePath parentPath, String resName) { - ResourcePath resourcePath = null; - if (parentPath == null) { - resourcePath = new ResourcePath(resName); - getModel().addResourcePath(resourcePath); - } else { - if (resName.startsWith(Parser.LEFT_CURLY_BRACKET) && resName.endsWith(Parser.RIGHT_CURLY_BRACKET)) { - TokenStream stream = new Parser.TokenStream(); - Parser parser = new Parser(stream); - stream.addLine(resName.substring(1, resName.length() - 1)); - try { - Expression exp = parser.parseTerm(stream, getModel()); - resourcePath = new ResourcePath(parentPath, exp); - getModel().addResourcePath(resourcePath); - } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - return null; - } - } else { - resourcePath = new ResourcePath(parentPath, resName); - getModel().addResourcePath(resourcePath); - } - } - resetDataFlowGraph(); - graph.getModel().beginUpdate(); - Object parent = graph.getDefaultParent(); - try { - graph.insertVertex(parent, null, resName, 20, 20, 80, 30, - "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - } finally { - graph.getModel().endUpdate(); - } - return resourcePath; - } + for (ResourcePath res : model.getResourcePaths()) { + if (res != null && state.getLabel().equals(res.getLeafResourceName())) + fileString.append("\tnode r ").append(state.getLabel()).append(":").append(x).append(",").append(y).append(",").append(w).append(",").append(h).append("\n"); + } - public void addChannel(DataTransferChannel channelGen) { - getModel().addChannel(channelGen); - resetDataFlowGraph(); - graph.getModel().beginUpdate(); - Object parent = graph.getDefaultParent(); - try { - mxGeometry geo1 = new mxGeometry(0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo1.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo1.setRelative(true); + for (Channel ioC : model.getInputChannels()) { + if (ioC != null && state.getLabel().equals(ioC.getChannelName())) { + fileString.append("\tnode ioc ").append(state.getLabel()).append(":").append(x).append(",").append(y).append(",").append(w).append(",").append(h).append("\n"); + } + } + } + } + fileString.append("}\n"); + return fileString.toString(); + } - mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo2.setRelative(true); + public void delete() { + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).delete(); + } - Object channel = graph.insertVertex(parent, null, channelGen.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex - mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); - port_in.setVertex(true); - graph.addCell(port_in, channel); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, channel); // insert the output port of a channel - } finally { - graph.getModel().endUpdate(); - } - } + public void setDAGLayout() { + mxCell root = (mxCell) graph.getDefaultParent(); - public void addIOChannel(DataTransferChannel ioChannelGen) { - getModel().addInputChannel(ioChannelGen); - resetDataFlowGraph(); - graph.getModel().beginUpdate(); - Object parent = graph.getDefaultParent(); - try { - mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo2.setRelative(true); + graph.getModel().beginUpdate(); + try { + DAGLayout ctl = new DAGLayout(graph); + ctl.execute(root); + } finally { + graph.getModel().endUpdate(); + } + } - Object channel = graph.insertVertex(parent, null, ioChannelGen.getChannelName(), 150, 20, 30, 30); // insert an I/O channel as a vertex - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, channel); // insert the output port of a channel - } finally { - graph.getModel().endUpdate(); - } - } + public void setTreeLayout() { + mxCell root = (mxCell) graph.getDefaultParent(); - public void addFormulaChannel(FormulaChannel formulaChannelGen) { - getModel().addChannel(formulaChannelGen); - resetDataFlowGraph(); - graph.getModel().beginUpdate(); - Object parent = graph.getDefaultParent(); - try { - mxGeometry geo1 = new mxGeometry(0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo1.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo1.setRelative(true); + graph.getModel().beginUpdate(); + try { + mxCompactTreeLayout ctl = new mxCompactTreeLayout(graph); + ctl.setLevelDistance(100); + // ctl.setHorizontal(false); + ctl.setEdgeRouting(false); + for (int i = 0; i < root.getChildCount(); i++) { + ctl.execute(root.getChildAt(i)); + } + } finally { + graph.getModel().endUpdate(); + } + } - mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo2.setRelative(true); + public void setCircleLayout() { + mxCell root = (mxCell) graph.getDefaultParent(); - Object channel = graph.insertVertex(parent, null, formulaChannelGen.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex - mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); - port_in.setVertex(true); - graph.addCell(port_in, channel); // insert the input port of a channel - mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); - port_out.setVertex(true); - graph.addCell(port_out, channel); // insert the output port of a channel - } finally { - graph.getModel().endUpdate(); - } - } + graph.getModel().beginUpdate(); + try { + mxCircleLayout ctl = new mxCircleLayout(graph); + for (int i = 0; i < root.getChildCount(); i++) { + ctl.execute(root.getChildAt(i)); + } + } finally { + graph.getModel().endUpdate(); + } + } - public boolean connectEdge(mxCell edge, mxCell src, mxCell dst) { - if (bReflectingArchitectureModel) return false; - DataTransferModel model = getModel(); - Channel srcCh = model.getChannel((String) src.getValue()); - if (srcCh == null) { - srcCh = model.getInputChannel((String) src.getValue()); - if (srcCh == null) { - ResourcePath srcRes = model.getResourcePath((String) src.getValue()); - Channel dstCh = model.getChannel((String) dst.getValue()); - if (srcRes == null || dstCh == null) return false; - // resource to channel edge - ChannelMember srcCm = new ChannelMember(srcRes); - ((DataTransferChannel ) dstCh).addChannelMemberAsInput(srcCm); - edge.setValue(new SrcDstAttribute(srcRes, dstCh)); - resetDataFlowGraph(); - return true; - } - } - ResourcePath dstRes = model.getResourcePath((String) dst.getValue()); - if (dstRes == null) return false; - // channel to resource edge - ChannelMember dstCm = new ChannelMember(dstRes); - ((DataTransferChannel) srcCh).addChannelMemberAsOutput(dstCm); - edge.setValue(new SrcDstAttribute(srcCh, dstRes)); - resetDataFlowGraph(); - return true; - } + public void addResourcePath(ResourcePath parentPath, String resName) { + // Force to change to data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).addResourcePath(parentPath, resName); + model = curStage.getModel(); + } - public void delete() { - for (Object obj: graph.getSelectionCells()) { - mxCell cell = (mxCell) obj; - if (cell.isEdge()) { - String srcName = (String) cell.getSource().getValue(); - String dstName = (String) cell.getTarget().getValue(); - if (model.getResourcePath(srcName) != null) { - // resource to channel edge - Channel ch = model.getChannel(dstName); - ch.removeChannelMember(model.getResourcePath(srcName)); - } else if (model.getResourcePath(dstName) != null) { - // channel to resource edge - Channel ch = model.getChannel(srcName); - if (ch == null) { - ch = model.getInputChannel(srcName); - } - ch.removeChannelMember(model.getResourcePath(dstName)); - } - } else if (cell.isVertex()) { - String name = (String) cell.getValue(); - if (model.getChannel(name) != null) { - model.removeChannel(name); - } else if (model.getInputChannel(name) != null) { - model.removeInputChannel(name); - } else if (model.getResourcePath(name) != null) { - model.removeResourcePath(name); - } - } - } - graph.removeCells(graph.getSelectionCells()); - resetDataFlowGraph(); - } + public void addChannel(DataTransferChannel channelGen) { + // Force to change to data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).addChannel(channelGen); + model = curStage.getModel(); + } - public void setChannelCode(DataTransferChannel ch, String code) { - ch.setSourceText(code); - TokenStream stream = new Parser.TokenStream(); - Parser parser = new Parser(stream); - - for (String line: code.split("\n")) { - stream.addLine(line); - } - try { - DataTransferChannel ch2 = parser.parseChannel(getModel()); - for (ChannelMember chm2: ch2.getInputChannelMembers()) { - for (ChannelMember chm: ch.getInputChannelMembers()) { - if (chm2.getResource() == chm.getResource()) { - chm.setStateTransition(chm2.getStateTransition()); - break; - } - } - } - for (ChannelMember chm2: ch2.getOutputChannelMembers()) { - for (ChannelMember chm: ch.getOutputChannelMembers()) { - if (chm2.getResource() == chm.getResource()) { - chm.setStateTransition(chm2.getStateTransition()); - break; - } - } - } - for (ChannelMember chm2: ch2.getReferenceChannelMembers()) { - for (ChannelMember chm: ch.getReferenceChannelMembers()) { - if (chm2.getResource() == chm.getResource()) { - chm.setStateTransition(chm2.getStateTransition()); - break; - } - } - } - resetDataFlowGraph(); - } catch (ExpectedRightBracket | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket - | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression - | WrongLHSExpression | WrongRHSExpression | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { - e.printStackTrace(); - } - } - - public Set> getResourceDependencyForChannel(DataTransferChannel ch, DataTransferModel model, DataFlowGraph dataFlowGraph) { - Set> resourceDpendency = new HashSet<>(); - if (ch.getOutputChannelMembers().size() > 0) { - try { - Map>> dependency = ch.fillOutsideResourcePaths(ch.getOutputChannelMembers().iterator().next(), JavaCodeGenerator.pullAccessor); - for (ChannelMember srcMem: dependency.keySet()) { - ResourceNode srcNode = dataFlowGraph.getResourceNode(srcMem.getResource()); - if (srcNode != null) { - for (ChannelMember dstMem: dependency.get(srcMem).getValue()) { - ResourceNode dstNode = dataFlowGraph.getResourceNode(dstMem.getResource()); - while (srcNode.getResourceHierarchy().getNumParameters() == 0 && srcNode.getParent() != null) { - srcNode = srcNode.getParent(); - } - resourceDpendency.add(new AbstractMap.SimpleEntry<>(srcNode, dstNode)); - } - } - } - } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage - | UnificationFailed | ValueUndefined e) { - e.printStackTrace(); - } - } - return resourceDpendency; - } + public void addIOChannel(DataTransferChannel ioChannelGen) { + // Force to change to data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).addIOChannel(ioChannelGen); + model = curStage.getModel(); + } - private class SrcDstAttribute extends EdgeAttribute { - private Object src; - private Object dst; + public void addFormulaChannel(FormulaChannel formulaChannelGen) { + // Force to change to data-flow modeling stage + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (stageChanged) { + return; + } + ((DataFlowModelingStage) curStage).addFormulaChannel(formulaChannelGen); + model = curStage.getModel(); + } - public SrcDstAttribute(Object src, Object dst) { - this.src = src; - this.dst = dst; - } + public boolean connectEdge(mxCell edge, mxCell src, mxCell dst) { + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) { + return false; + } + return ((DataFlowModelingStage) curStage).connectEdge(edge, src, dst); + } - public Object getSource() { - return src; - } + public mxGraph getGraph() { + return graph; + } - public Object getDestination() { - return dst; - } + public mxGraphComponent getGraphComponent() { + return graphComponent; + } - public String toString() { - return ""; - } - } + public DataTransferModel getModel() { + model = curStage.getModel(); + return model; + } + + public Stage getCurStage() { + return curStage; + } + + public ArrayList getCodes() { + return codes; + } + + public void setCodes(ArrayList codes) { + this.codes = codes; + } + + public String getCurFileName() { + return curFileName; + } + + public String getCurFilePath() { + return curFilePath; + } + + public static class SrcDstAttribute extends EdgeAttribute { + private final Object src; + private final Object dst; + + public SrcDstAttribute(Object src, Object dst) { + this.src = src; + this.dst = dst; + } + + public Object getSource() { + return src; + } + + public Object getDestination() { + return dst; + } + + public String toString() { + return ""; + } + } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/FlowCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/FlowCellEditor.java new file mode 100644 index 0000000..b4d7176 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/FlowCellEditor.java @@ -0,0 +1,27 @@ +package application.editor; + +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.swing.view.mxICellEditor; + +import java.util.EventObject; + +public abstract class FlowCellEditor implements mxICellEditor { + + protected Stage stage; + protected mxGraphComponent graphComponent; + + protected Object editingCell = null; + + protected FlowCellEditor(Stage stage, mxGraphComponent graphComponent) { + this.stage = stage; + this.graphComponent = graphComponent; + } + + public abstract void startEditing(Object cellObj, EventObject eventObj); + + public abstract void stopEditing(boolean cancel); + + public Object getEditingCell() { + return this.editingCell; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java b/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java new file mode 100644 index 0000000..f2cf45c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java @@ -0,0 +1,5 @@ +package application.editor; + +public interface IStageChangeListener { + void stageChanged(Stage newStage); +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java new file mode 100644 index 0000000..33114bd --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java @@ -0,0 +1,39 @@ +package application.editor; + +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; + +import java.awt.event.MouseListener; + +public abstract class Stage { + + public static final int PORT_DIAMETER = 8; + public static final int PORT_RADIUS = PORT_DIAMETER / 2; + + protected DataTransferModel model = null; + + protected mxGraphComponent graphComponent; + protected mxGraph graph; + + public Stage(mxGraphComponent graphComponent) { + this.graphComponent = graphComponent; + this.graph = graphComponent.getGraph(); + } + + public abstract void init(Stage prevStage); + + public abstract mxICellEditor createCellEditor(mxGraphComponent graphComponent); + + public abstract mxIEventListener createChangeEventListener(Editor editor); + + public abstract MouseListener createMouseEventListener(Editor editor); + + public abstract boolean canChangeFrom(Stage prevStage); + + public DataTransferModel getModel() { + return model; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowCellEditor.java new file mode 100644 index 0000000..c0709b6 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowCellEditor.java @@ -0,0 +1,107 @@ +package application.editor.stages; + +import application.editor.FlowCellEditor; +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxIGraphModel; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxConstants; +import com.mxgraph.util.mxUtils; +import models.algebra.Expression; +import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.DataTransferModel; +import models.visualModel.FormulaChannel; +import parser.Parser; +import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; +import parser.exceptions.ExpectedRightBracket; +import parser.exceptions.WrongJsonExpression; + +import javax.swing.*; +import java.awt.*; +import java.util.EventObject; + +public class DataFlowCellEditor extends FlowCellEditor { + + public DataFlowCellEditor(DataFlowModelingStage stage, mxGraphComponent graphComponent) { + super(stage, graphComponent); + } + + @Override + public void startEditing(Object cellObj, EventObject eventObj) { + if (editingCell != null) { + stopEditing(true); + } + if (graphComponent.getGraph().getModel().isEdge(cellObj)) { + return; + } + DataTransferModel model = stage.getModel(); + DataTransferChannel ch = (DataTransferChannel) model.getChannel((String) ((mxCell) cellObj).getValue()); + if (ch == null) { + ch = (DataTransferChannel) model.getInputChannel((String) ((mxCell) cellObj).getValue()); + if (ch == null) { + // selected cell is a resource + return; + } + } + JPanel panel = new JPanel(); + if (ch instanceof FormulaChannel) { + JLabel label1 = new JLabel("Formula: "); + JLabel label2 = new JLabel("Source: "); + GridBagLayout layout = new GridBagLayout(); + panel.setLayout(layout); + GridBagConstraints gbc = new GridBagConstraints(); + + gbc.gridx = 0; + gbc.gridy = 0; + layout.setConstraints(label1, gbc); + panel.add(label1); + + gbc.gridx = 1; + gbc.gridy = 0; + JTextField formulaText = new JTextField(((FormulaChannel) ch).getFormula(), 15); + layout.setConstraints(formulaText, gbc); + panel.add(formulaText); + + gbc.gridx = 0; + gbc.gridy = 1; + layout.setConstraints(label2, gbc); + panel.add(label2); + + gbc.gridx = 1; + gbc.gridy = 1; + JTextArea textArea = new JTextArea(ch.getSourceText(), 7, 15); + textArea.setEditable(false); + layout.setConstraints(textArea, gbc); + panel.add(textArea); + + int option = JOptionPane.showConfirmDialog(null, panel, "Edit Formula Channel", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + if (option == JOptionPane.OK_OPTION) { + Parser.TokenStream stream = new Parser.TokenStream(); + Parser parser = new Parser(stream); + + String formula = formulaText.getText(); + stream.addLine(formula.split(Parser.EQUALS)[1]); + + try { + Expression exp = parser.parseTerm(stream, stage.getModel()); + ((FormulaChannel) ch).setFormula(formula); + ((FormulaChannel) ch).setFormulaTerm(exp); + } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { + e.printStackTrace(); + } + } + } else { + JTextArea textArea = new JTextArea(ch.getSourceText(), 10, 20); + panel.add(textArea); + + int option = JOptionPane.showConfirmDialog(null, panel, "Channel Code", JOptionPane.OK_CANCEL_OPTION); + if (option == JOptionPane.OK_OPTION) { + ((DataFlowModelingStage) stage).setChannelCode(ch, textArea.getText()); + } + } + } + + @Override + public void stopEditing(boolean cancel) { + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java new file mode 100644 index 0000000..34117ba --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java @@ -0,0 +1,307 @@ +package application.editor.stages; + +import algorithms.Validation; +import application.editor.Editor; +import application.editor.FlowCellEditor; +import application.editor.Stage; +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGeometry; +import com.mxgraph.model.mxGraphModel; +import com.mxgraph.model.mxGraphModel.mxTerminalChange; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxEventSource.mxIEventListener; +import com.mxgraph.util.mxPoint; +import models.algebra.Expression; +import models.dataConstraintModel.Channel; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.ResourcePath; +import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.DataTransferModel; +import models.visualModel.FormulaChannel; +import parser.Parser; +import parser.exceptions.*; + +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.List; + +public class DataFlowModelingStage extends Stage { + + public DataFlowModelingStage(mxGraphComponent graphComponent) { + super(graphComponent); + } + + @Override + public void init(Stage prevStage) { + } + + @Override + public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { + return new DataFlowCellEditor(this, graphComponent); + } + + @Override + public mxIEventListener createChangeEventListener(Editor editor) { + return (sender, event) -> { + List terminals = new ArrayList<>(); + mxCell cell = null; + for (Object change : ((List) event.getProperties().get("changes"))) { + if (change instanceof mxTerminalChange) { + mxTerminalChange terminalChange = (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}); + graph.clearSelection(); + } + } + }; + } + + @Override + public MouseListener createMouseEventListener(Editor editor) { + return null; + } + + @Override + public boolean canChangeFrom(Stage prevStage) { + return true; + } + + public void clear() { + model = null; + + ((mxGraphModel) graph.getModel()).clear(); + } + + public DataTransferModel getModel() { + if (model == null) { + model = new DataTransferModel(); + } + return model; + } + + public void setModel(DataTransferModel model) { + // Clear the mxGraph + clear(); + + this.model = model; + } + + public boolean isValid() { + if (model == null) { + return false; + } + return Validation.checkUpdateConflict(model); + } + + public void addResourcePath(ResourcePath parentPath, String resName) { + ResourcePath resourcePath; + if (parentPath == null) { + resourcePath = new ResourcePath(resName); + getModel().addResourcePath(resourcePath); + } else { + if (resName.startsWith(Parser.LEFT_CURLY_BRACKET) && resName.endsWith(Parser.RIGHT_CURLY_BRACKET)) { + Parser.TokenStream stream = new Parser.TokenStream(); + Parser parser = new Parser(stream); + stream.addLine(resName.substring(1, resName.length() - 1)); + try { + Expression exp = parser.parseTerm(stream, getModel()); + resourcePath = new ResourcePath(parentPath, exp); + getModel().addResourcePath(resourcePath); + } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { + e.printStackTrace(); + } + } else { + resourcePath = new ResourcePath(parentPath, resName); + getModel().addResourcePath(resourcePath); + } + } + + graph.getModel().beginUpdate(); + mxCell root = (mxCell) graph.getDefaultParent(); + try { + graph.insertVertex(root, null, resName, 20, 20, 80, 30, "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex + } finally { + graph.getModel().endUpdate(); + } + } + + public void addChannel(DataTransferChannel channelGen) { + getModel().addChannel(channelGen); + + graph.getModel().beginUpdate(); + mxCell root = (mxCell) graph.getDefaultParent(); + try { + mxGeometry geo1 = new mxGeometry(0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + geo1.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + geo1.setRelative(true); + + mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + geo2.setRelative(true); + + Object channel = graph.insertVertex(root, null, channelGen.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex + mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); + port_in.setVertex(true); + graph.addCell(port_in, channel); // insert the input port of a channel + mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); + port_out.setVertex(true); + graph.addCell(port_out, channel); // insert the output port of a channel + } finally { + graph.getModel().endUpdate(); + } + } + + public void addIOChannel(DataTransferChannel ioChannelGen) { + getModel().addInputChannel(ioChannelGen); + + graph.getModel().beginUpdate(); + mxCell root = (mxCell) graph.getDefaultParent(); + try { + mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + geo2.setRelative(true); + + Object channel = graph.insertVertex(root, null, ioChannelGen.getChannelName(), 150, 20, 30, 30); // insert an I/O channel as a vertex + mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); + port_out.setVertex(true); + graph.addCell(port_out, channel); // insert the output port of a channel + } finally { + graph.getModel().endUpdate(); + } + } + + public void addFormulaChannel(FormulaChannel formulaChannelGen) { + getModel().addChannel(formulaChannelGen); + + graph.getModel().beginUpdate(); + mxCell root = (mxCell) graph.getDefaultParent(); + try { + mxGeometry geo1 = new mxGeometry(0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + geo1.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + geo1.setRelative(true); + + mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + geo2.setRelative(true); + + Object channel = graph.insertVertex(root, null, formulaChannelGen.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex + mxCell port_in = new mxCell(null, geo1, "shape=ellipse;perimter=ellipsePerimeter"); + port_in.setVertex(true); + graph.addCell(port_in, channel); // insert the input port of a channel + mxCell port_out = new mxCell(null, geo2, "shape=ellipse;perimter=ellipsePerimeter"); + port_out.setVertex(true); + graph.addCell(port_out, channel); // insert the output port of a channel + } finally { + graph.getModel().endUpdate(); + } + } + + public boolean connectEdge(mxCell edge, mxCell src, mxCell dst) { + DataTransferModel model = getModel(); + Channel srcCh = model.getChannel((String) src.getValue()); + if (srcCh == null) { + srcCh = model.getInputChannel((String) src.getValue()); + if (srcCh == null) { + ResourcePath srcRes = model.getResourcePath((String) src.getValue()); + Channel dstCh = model.getChannel((String) dst.getValue()); + if (srcRes == null || dstCh == null) { + return false; + } + // resource to channel edge + ChannelMember srcCm = new ChannelMember(srcRes); + ((DataTransferChannel) dstCh).addChannelMemberAsInput(srcCm); + edge.setValue(new Editor.SrcDstAttribute(srcRes, dstCh)); + return true; + } + } + ResourcePath dstRes = model.getResourcePath((String) dst.getValue()); + if (dstRes == null) { + return false; + } + // channel to resource edge + ChannelMember dstCm = new ChannelMember(dstRes); + ((DataTransferChannel) srcCh).addChannelMemberAsOutput(dstCm); + edge.setValue(new Editor.SrcDstAttribute(srcCh, dstRes)); + return true; + } + + public void delete() { + for (Object obj : graph.getSelectionCells()) { + mxCell cell = (mxCell) obj; + if (cell.isEdge()) { + String srcName = (String) cell.getSource().getValue(); + String dstName = (String) cell.getTarget().getValue(); + if (model.getResourcePath(srcName) != null) { + // resource to channel edge + Channel ch = model.getChannel(dstName); + ch.removeChannelMember(model.getResourcePath(srcName)); + } else if (model.getResourcePath(dstName) != null) { + // channel to resource edge + Channel ch = model.getChannel(srcName); + if (ch == null) { + ch = model.getInputChannel(srcName); + } + ch.removeChannelMember(model.getResourcePath(dstName)); + } + } else if (cell.isVertex()) { + String name = (String) cell.getValue(); + if (model.getChannel(name) != null) { + model.removeChannel(name); + } else if (model.getInputChannel(name) != null) { + model.removeInputChannel(name); + } else if (model.getResourcePath(name) != null) { + model.removeResourcePath(name); + } + } + } + graph.removeCells(graph.getSelectionCells()); + } + + public void setChannelCode(DataTransferChannel ch, String code) { + ch.setSourceText(code); + Parser.TokenStream stream = new Parser.TokenStream(); + Parser parser = new Parser(stream); + + for (String line : code.split("\n")) { + stream.addLine(line); + } + try { + DataTransferChannel ch2 = parser.parseChannel(getModel()); + for (ChannelMember chm2 : ch2.getInputChannelMembers()) { + for (ChannelMember chm : ch.getInputChannelMembers()) { + if (chm2.getResource() == chm.getResource()) { + chm.setStateTransition(chm2.getStateTransition()); + break; + } + } + } + for (ChannelMember chm2 : ch2.getOutputChannelMembers()) { + for (ChannelMember chm : ch.getOutputChannelMembers()) { + if (chm2.getResource() == chm.getResource()) { + chm.setStateTransition(chm2.getStateTransition()); + break; + } + } + } + for (ChannelMember chm2 : ch2.getReferenceChannelMembers()) { + for (ChannelMember chm : ch.getReferenceChannelMembers()) { + if (chm2.getResource() == chm.getResource()) { + chm.setStateTransition(chm2.getStateTransition()); + break; + } + } + } + } catch (ExpectedRightBracket | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | + ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | + WrongLHSExpression | WrongRHSExpression | ExpectedAssignment | ExpectedRightCurlyBracket | + WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { + e.printStackTrace(); + } + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionCellEditor.java new file mode 100644 index 0000000..7d6d99b --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionCellEditor.java @@ -0,0 +1,133 @@ +package application.editor.stages; + +import application.editor.FlowCellEditor; +import com.mxgraph.model.mxIGraphModel; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxConstants; +import com.mxgraph.util.mxUtils; +import com.mxgraph.view.mxCellState; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; + +import javax.swing.*; +import java.awt.*; +import java.util.EventObject; +import java.util.List; + +public class PushPullSelectionCellEditor extends FlowCellEditor { + + public int DEFAULT_MIN_WIDTH = 70; + public int DEFAULT_MIN_HEIGHT = 30; + public double DEFAULT_MINIMUM_EDITOR_SCALE = 1; + + protected double minimumEditorScale = DEFAULT_MINIMUM_EDITOR_SCALE; + protected int minimumWidth = DEFAULT_MIN_WIDTH; + protected int minimumHeight = DEFAULT_MIN_HEIGHT; + + private EventObject trigger; + private JComboBox comboBox; + + public PushPullSelectionCellEditor(PushPullSelectionStage stage, mxGraphComponent graphComponent) { + super(stage, graphComponent); + } + + @Override + public void startEditing(Object cellObj, EventObject eventObj) { + if (editingCell != null) { + stopEditing(true); + } + if (!graphComponent.getGraph().getModel().isEdge(cellObj)) { + return; + } + mxCellState state = graphComponent.getGraph().getView().getState(cellObj); + if (state != null && state.getLabel() != null && !state.getLabel().isEmpty()) { + editingCell = cellObj; + trigger = eventObj; + + double scale = Math.max(minimumEditorScale, graphComponent.getGraph().getView().getScale()); + Object value = graphComponent.getGraph().getModel().getValue(cellObj); + if (value instanceof PushPullAttribute) { + PushPullAttribute attr = (PushPullAttribute) value; + comboBox = new JComboBox<>(attr.getOptionStrings()); + comboBox.setBorder(BorderFactory.createEmptyBorder()); + comboBox.setOpaque(false); + comboBox.setBounds(getEditorBounds(state, scale)); + comboBox.setVisible(true); + graphComponent.getGraphControl().add(comboBox, 0); + comboBox.updateUI(); + } + } + } + + @Override + public void stopEditing(boolean cancel) { + if (editingCell == null) { + return; + } + comboBox.transferFocusUpCycle(); + Object cell = editingCell; + editingCell = null; + if (!cancel) { + EventObject trig = trigger; + trigger = null; + Object value = graphComponent.getGraph().getModel().getValue(cell); + if (value instanceof PushPullAttribute) { + PushPullAttribute attr = (PushPullAttribute) value; + List options = attr.getOptions(); + PushPullValue selected = null; + for (PushPullValue option : options) { + if (option.toString().equals(getCurrentValue())) { + selected = option; + break; + } + } + if (selected != null) { + options.remove(selected); + options.add(0, selected); + } + graphComponent.labelChanged(cell, attr, trig); + } + } else { + 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 = 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 -= (int) state.getWidth(); + } else if (horizontal.equals(mxConstants.ALIGN_RIGHT)) { + bounds.x += (int) state.getWidth(); + } + String vertical = mxUtils.getString(state.getStyle(), mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE); + if (vertical.equals(mxConstants.ALIGN_TOP)) { + bounds.y -= (int) state.getHeight(); + } else if (vertical.equals(mxConstants.ALIGN_BOTTOM)) { + bounds.y += (int) state.getHeight(); + } + } + bounds.setSize((int) Math.max(bounds.getWidth(), Math.round(minimumWidth * scale)), (int) Math.max(bounds.getHeight(), Math.round(minimumHeight * scale))); + return bounds; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java new file mode 100644 index 0000000..5f4ae42 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java @@ -0,0 +1,295 @@ +package application.editor.stages; + +import algorithms.DataTransferModelAnalyzer; +import application.editor.Editor; +import application.editor.FlowCellEditor; +import application.editor.Stage; +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.mxPoint; +import generators.JavaCodeGenerator; +import models.Edge; +import models.algebra.*; +import models.dataConstraintModel.Channel; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.ResourcePath; +import models.dataConstraintModel.Selector; +import models.dataFlowModel.*; + +import java.awt.event.MouseListener; +import java.util.*; + +public class PushPullSelectionStage extends Stage { + + private DataFlowGraph dataFlowGraph = null; + + public PushPullSelectionStage(mxGraphComponent graphComponent) { + super(graphComponent); + } + + @Override + public void init(Stage prevStage) { + if (prevStage instanceof DataFlowModelingStage) { + model = prevStage.getModel(); + dataFlowGraph = analyzeDataTransferModel(model); + } + } + + @Override + public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { + return new PushPullSelectionCellEditor(this, graphComponent); + } + + @Override + public mxIEventListener createChangeEventListener(Editor editor) { + return (sender, eventObject) -> { + List terminals = new ArrayList<>(); + mxCell cell = null; + for (Object change : ((List) eventObject.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}); + graph.clearSelection(); + } + }; + } + + @Override + public MouseListener createMouseEventListener(Editor editor) { + return null; + } + + @Override + public boolean canChangeFrom(Stage prevStage) { + if (prevStage instanceof DataFlowModelingStage) { + return ((DataFlowModelingStage) prevStage).isValid(); + } + return false; + } + + private DataFlowGraph analyzeDataTransferModel(DataTransferModel model) { + DataFlowGraph flowGraph = DataTransferModelAnalyzer.createDataFlowGraphWithStateStoringAttribute(model); + DataFlowGraph dataFlowGraph = DataTransferModelAnalyzer.annotateWithSelectableDataTransferAttiribute(flowGraph); + updateEdgeAttributes(dataFlowGraph); + return dataFlowGraph; + } + + private void updateEdgeAttributes(DataFlowGraph dataFlowGraph) { + mxCell root = (mxCell) graph.getDefaultParent(); + + graph.getModel().beginUpdate(); + try { + // add input, output and reference edges + for (Edge e : dataFlowGraph.getEdges()) { + if (e instanceof DataFlowEdge) { + DataFlowEdge dataFlow = (DataFlowEdge) e; + if (!dataFlow.isChannelToResource()) { + ResourceNode srcRes = (ResourceNode) dataFlow.getSource(); + DataTransferChannel channel = ((ChannelNode) dataFlow.getDestination()).getChannel(); + // input edge + for (Object edge : graph.getChildEdges(root)) { + mxCell edgeCell = (mxCell) edge; + if (edgeCell.getValue() instanceof Editor.SrcDstAttribute) { + Editor.SrcDstAttribute edgeAttr = (Editor.SrcDstAttribute) edgeCell.getValue(); + if (srcRes.getPrimaryResourcePath().equals(edgeAttr.getSource()) && channel.equals(edgeAttr.getDestination())) { + edgeCell.setValue(dataFlow.getAttribute()); + break; + } + } + } + } + } + } + } finally { + graph.getModel().endUpdate(); + } + graph.refresh(); + } + + /** + * Construct a mxGraph from DataFlowGraph + */ + public void constructGraph() { + ((mxGraphModel) graph.getModel()).clear(); + mxCell parent = (mxCell) graph.getDefaultParent(); + + graph.getModel().beginUpdate(); + try { + Map channelsIn = new HashMap<>(); + Map channelsOut = new HashMap<>(); + Map resources = new HashMap<>(); + + mxGeometry geoPortIn = new mxGeometry(0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + geoPortIn.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + geoPortIn.setRelative(true); + + mxGeometry geoPortOut = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + geoPortOut.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + geoPortOut.setRelative(true); + + // create resource vertices + for (ResourceNode resourceNode : dataFlowGraph.getRootResourceNodes()) { + int w = 80; + int h = 30; + ResourcePath resourcePath = resourceNode.getPrimaryResourcePath(); + Object resource = graph.insertVertex(parent, null, resourcePath.getLeafResourceName(), 20, 20, w, h, "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex + resources.put(resourceNode, resource); + createChildResourceVertices(resource, resourceNode, resources, w, h); + } + + // create channel vertices + for (ChannelNode channelNode : dataFlowGraph.getRootChannelNodes()) { + DataTransferChannel channel = channelNode.getChannel(); + if (!channel.getInputResources().isEmpty()) { + // Normal channel + if (channelsIn.get(channel) == null || channelsOut.get(channel) == null) { + if (Objects.equals(channel.getSelectors().toString(), "[]")) { + Object channelCell = graph.insertVertex(parent, null, channel.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex + + mxCell portIn = new mxCell(null, geoPortIn, "shape=ellipse;perimter=ellipsePerimeter"); + portIn.setVertex(true); + graph.addCell(portIn, channelCell); // insert the input port of a channel + channelsIn.put(channel, portIn); + + mxCell port_out = new mxCell(null, geoPortOut, "shape=ellipse;perimter=ellipsePerimeter"); + port_out.setVertex(true); + graph.addCell(port_out, channelCell); // insert the output port of a channel + channelsOut.put(channel, port_out); + } else { + for (Selector s : channel.getSelectors()) { + Expression exp = s.getExpression(); + String selectorName = exp.toString(); + String channelName = channel.getChannelName(); + String cellName = channelName + " (" + selectorName + ")"; + + Object channelCell = graph.insertVertex(parent, null, cellName, 150, 20, 60, 30); // insert a channel as a vertex + + mxCell portIn = new mxCell(null, geoPortIn, "shape=ellipse;perimter=ellipsePerimeter"); + portIn.setVertex(true); + graph.addCell(portIn, channelCell); // insert the input port of a channel + channelsIn.put(channel, portIn); + + mxCell portOut = new mxCell(null, geoPortOut, "shape=ellipse;perimter=ellipsePerimeter"); + portOut.setVertex(true); + graph.addCell(portOut, channelCell); // insert the output port of a channel + channelsOut.put(channel, portOut); + } + } + } + } else { + // I/O channel + if (channelsOut.get(channel) == null) { + if (Objects.equals(channel.getSelectors().toString(), "[]")) { + Object chCell = graph.insertVertex(parent, null, channel.getChannelName(), 150, 20, 30, 30); // insert a channel as a vertex + mxCell port_in = new mxCell(null, geoPortIn, "shape=ellipse;perimter=ellipsePerimeter"); + port_in.setVertex(true); + graph.addCell(port_in, chCell); // insert the input port of a channel + mxCell port_out = new mxCell(null, geoPortOut, "shape=ellipse;perimter=ellipsePerimeter"); + port_out.setVertex(true); + graph.addCell(port_out, chCell); // insert the output port of a channel + channelsIn.put(channel, port_in); + channelsOut.put(channel, port_out); + } else { + for (Selector s : channel.getSelectors()) { + Expression exp = s.getExpression(); + String selectorName = exp.toString(); + String channelName = channel.getChannelName(); + String cellName = channelName + " (" + selectorName + ")"; + Object chCell = graph.insertVertex(parent, null, cellName, 150, 20, 60, 30); // insert a channel as a vertex + + mxCell port_in = new mxCell(null, geoPortIn, "shape=ellipse;perimter=ellipsePerimeter"); + port_in.setVertex(true); + graph.addCell(port_in, chCell); // insert the input port of a channel + channelsIn.put(channel, port_in); + + mxCell port_out = new mxCell(null, geoPortOut, "shape=ellipse;perimter=ellipsePerimeter"); + port_out.setVertex(true); + graph.addCell(port_out, chCell); // insert the output port of a channel + channelsOut.put(channel, port_out); + } + } + } + } + } + + // add input, output and reference edges + for (Edge edge : dataFlowGraph.getEdges()) { + DataFlowEdge dataFlowEdge = (DataFlowEdge) edge; + if (dataFlowEdge.isChannelToResource()) { + // output edge + DataTransferChannel channel = ((ChannelNode) dataFlowEdge.getSource()).getChannel(); + ResourcePath dstRes = ((ResourceNode) dataFlowEdge.getDestination()).getInSideResource(channel); + graph.insertEdge(parent, null, new Editor.SrcDstAttribute(channel, dstRes), channelsOut.get(channel), resources.get((ResourceNode) dataFlowEdge.getDestination()), "movable=false"); + } else { + // input edge + DataTransferChannel channel = ((ChannelNode) dataFlowEdge.getDestination()).getChannel(); + ResourcePath srcRes = ((ResourceNode) dataFlowEdge.getSource()).getOutSideResource(channel); + Set> toRes = getResourceDependencyForChannel(channel, dataFlowGraph); + for (Map.Entry RtoR : toRes) { + graph.insertEdge(parent, null, null, resources.get(RtoR.getValue()), resources.get(RtoR.getKey()), "dashed=true;movable=false"); + } + + graph.insertEdge(parent, null, new Editor.SrcDstAttribute(srcRes, channel), resources.get((ResourceNode) dataFlowEdge.getSource()), channelsIn.get(channel), "movable=false"); + } + } + + for (Channel ch : model.getChannels()) { + // reference edges + DataTransferChannel channel = (DataTransferChannel) ch; + for (ResourcePath refRes : channel.getReferenceResources()) { + graph.insertEdge(parent, null, null, resources.get(dataFlowGraph.getResourceNode(refRes)), channelsIn.get(channel), "dashed=true;movable=false"); + } + } + } finally { + graph.getModel().endUpdate(); + } + } + + private void createChildResourceVertices(Object resource, ResourceNode resNode, Map resources, int w, int h) { + for (ResourceNode childNode : resNode.getChildren()) { + ResourcePath childRes = childNode.getPrimaryResourcePath(); + Object childResource = graph.insertVertex(resource, null, childRes.getName(), 0, 0, w, h, "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex + resources.put(childNode, childResource); + createChildResourceVertices(childResource, childNode, resources, w, h); + } + } + + private Set> getResourceDependencyForChannel(DataTransferChannel ch, DataFlowGraph dataFlowGraph) { + Set> resourceDependency = new HashSet<>(); + if (!ch.getOutputChannelMembers().isEmpty()) { + try { + Map>> dependency = ch.fillOutsideResourcePaths(ch.getOutputChannelMembers().iterator().next(), JavaCodeGenerator.pullAccessor); + for (ChannelMember srcMem : dependency.keySet()) { + ResourceNode srcNode = dataFlowGraph.getResourceNode(srcMem.getResource()); + if (srcNode != null) { + for (ChannelMember dstMem : dependency.get(srcMem).getValue()) { + ResourceNode dstNode = dataFlowGraph.getResourceNode(dstMem.getResource()); + while (srcNode.getResourceHierarchy().getNumParameters() == 0 && srcNode.getParent() != null) { + srcNode = srcNode.getParent(); + } + resourceDependency.add(new AbstractMap.SimpleEntry<>(srcNode, dstNode)); + } + } + } + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | + UnificationFailed | ValueUndefined e) { + e.printStackTrace(); + } + } + return resourceDependency; + } + + public DataFlowGraph getDataFlowGraph() { + return dataFlowGraph; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java index 8d219c5..46bc39a 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/simulator/InputEventCellEditor.java @@ -54,6 +54,7 @@ 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.ChannelState; @@ -174,7 +175,7 @@ graphComponent.setCellEditor(new InputEventCellEditor(graphComponent, simulator, this.editor)); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork - | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedRightBracket | WrongJsonExpression | ExpectedColon e) { + | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/simulator/SimulatorWindow.java b/AlgebraicDataflowArchitectureModel/src/application/simulator/SimulatorWindow.java index 6dfb078..9bcacd4 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/simulator/SimulatorWindow.java +++ b/AlgebraicDataflowArchitectureModel/src/application/simulator/SimulatorWindow.java @@ -1,149 +1,111 @@ package application.simulator; -import java.io.BufferedReader; -import java.io.FileReader; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.swing.JFrame; - +import algorithms.TypeInference; +import application.editor.Editor; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGeometry; import com.mxgraph.model.mxGraphModel; -import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.swing.handler.mxRubberband; +import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.util.mxEvent; import com.mxgraph.util.mxEventObject; -import com.mxgraph.util.mxPoint; import com.mxgraph.util.mxEventSource.mxIEventListener; import com.mxgraph.view.mxGraph; - -import algorithms.TypeInference; -import application.editor.DataTransferModelingCellEditor; -import application.editor.Editor; -import application.layouts.DAGLayout; -import generators.JavaCodeGenerator; -import models.Edge; -import models.EdgeAttribute; -import models.algebra.Expression; -import models.algebra.InvalidMessage; -import models.algebra.ParameterizedIdentifierIsFutureWork; -import models.algebra.UnificationFailed; -import models.algebra.ValueUndefined; -import models.dataConstraintModel.Channel; -import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.ResourcePath; -import models.dataConstraintModel.Selector; -import models.dataFlowModel.ChannelNode; -import models.dataFlowModel.DataFlowEdge; -import models.dataFlowModel.DataFlowGraph; -import models.dataFlowModel.DataTransferChannel; import models.dataFlowModel.DataTransferModel; -import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; -import models.dataFlowModel.ResourceNode; -import parser.Parser; -import parser.ParserDTRAM; -import parser.exceptions.ExpectedColon; -import parser.exceptions.ExpectedRightBracket; -import parser.exceptions.WrongJsonExpression; -import parser.Parser.TokenStream; import simulator.Event; -import simulator.Resource; -import simulator.ResourceIdentifier; import simulator.Simulator; import simulator.SystemState; import simulator.interfaces.INativeReceiver; +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; + public class SimulatorWindow extends JFrame implements INativeReceiver { - private static final long serialVersionUID = -2425820512017088254L; - public static final String title = "Simulation Tool"; + private static final long serialVersionUID = -2425820512017088254L; + public static final String title = "Simulation Tool"; - final int PORT_DIAMETER = 8; - final int PORT_RADIUS = PORT_DIAMETER / 2; - - private Editor editor = null; - private mxGraph graph = null; - private mxGraphComponent graphComponent = null; - - private Simulator simulator = null; + final int PORT_DIAMETER = 8; + final int PORT_RADIUS = PORT_DIAMETER / 2; - private boolean bReflectingArchitectureModel = false; - private double x = 20; - private double y = 20; - private SimulatorMenuBar menuBar; - - public SimulatorWindow(Editor editor) { - setTitle(title); - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - - this.graph = new mxGraph() { - public boolean isPort(Object cell) { - mxGeometry geo = getCellGeometry(cell); - - return (geo != null) ? geo.isRelative() : false; - } - - public boolean isCellFoldable(Object cell, boolean collapse) { - return false; - } - }; - - this.graphComponent = new mxGraphComponent(graph); - this.editor = editor; - - 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); - graph.setCellsDisconnectable(true); - - setTitle(title); - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - setSize(870,640); - setVisible(true); - - DataTransferModel model = this.editor.getModel(); - TypeInference.infer(model); - simulator = new Simulator(model); - SimulationLayout layout = new SimulationLayout(simulator.getCurState()); - layout.constructSimulateGraph(graph, simulator); - graphComponent.setCellEditor(new InputEventCellEditor(graphComponent, simulator, this.editor)); - simulator.addSystemReceiver(this); - - menuBar = new SimulatorMenuBar(this); - setJMenuBar(menuBar); - } - + private Editor editor = null; + private mxGraph graph = null; + private mxGraphComponent graphComponent = null; - @Override - public void onReceiveFromModel(Event event, SystemState nextSystemState) { - SimulationLayout layout = new SimulationLayout(nextSystemState); - layout.constructSimulateGraph(graph, simulator); - } + private Simulator simulator = null; + + private boolean bReflectingArchitectureModel = false; + private double x = 20; + private double y = 20; + private SimulatorMenuBar menuBar; + + public SimulatorWindow(Editor editor) { + setTitle(title); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + this.graph = new mxGraph() { + public boolean isPort(Object cell) { + mxGeometry geo = getCellGeometry(cell); + + return (geo != null) ? geo.isRelative() : false; + } + + public boolean isCellFoldable(Object cell, boolean collapse) { + return false; + } + }; + + this.graphComponent = new mxGraphComponent(graph); + this.editor = editor; + + 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); + graph.setCellsDisconnectable(true); + + setTitle(title); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setSize(870, 640); + setVisible(true); + + DataTransferModel model = this.editor.getModel(); + TypeInference.infer(model); + simulator = new Simulator(model); + SimulationLayout layout = new SimulationLayout(simulator.getCurState()); + layout.constructSimulateGraph(graph, simulator); + graphComponent.setCellEditor(new InputEventCellEditor(graphComponent, simulator, this.editor)); + simulator.addSystemReceiver(this); + + menuBar = new SimulatorMenuBar(this); + setJMenuBar(menuBar); + } + + + @Override + public void onReceiveFromModel(Event event, SystemState nextSystemState) { + SimulationLayout layout = new SimulationLayout(nextSystemState); + layout.constructSimulateGraph(graph, simulator); + } // public mxGraph constructSimulateGraph(Set simulateRes, DataTransferModel model, DataFlowGraph dataFlowGraph) { // bReflectingArchitectureModel = true; @@ -193,21 +155,21 @@ // resNode.getState().getValue().toString(), 0.5, 0.5, 0.25, 0.25, "opacity=0;verticalAlign=down;", true); // insert a state label as a vertex // } // } - - public mxGraphComponent getGraphComponent() { - return graphComponent; - } - public Editor getEditor() { - return editor; - } + public mxGraphComponent getGraphComponent() { + return graphComponent; + } - public void setEditor(Editor editor) { - this.editor = editor; - } + public Editor getEditor() { + return editor; + } - public Simulator getSimulator() { - return simulator; - } + public void setEditor(Editor editor) { + this.editor = editor; + } + + public Simulator getSimulator() { + return simulator; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java b/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java new file mode 100644 index 0000000..cddad6c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java @@ -0,0 +1,87 @@ +package application.views; + +import application.ApplicationWindow; +import application.editor.Editor; +import application.editor.IStageChangeListener; +import application.editor.Stage; +import application.editor.stages.DataFlowModelingStage; +import application.editor.stages.PushPullSelectionStage; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class NavigationWindow extends JDialog implements IStageChangeListener { + + private static final String TITLE = "Navigation"; + private final Editor editor; + + private final JToggleButton dataFlowModelingButton; + private final JToggleButton pushPullSelectionButton; + + private boolean forbidReentry = false; + + public NavigationWindow(ApplicationWindow owner, Editor editor) { + super(owner); + this.editor = editor; + dataFlowModelingButton = new JToggleButton("Data Flow Modeling"); + pushPullSelectionButton = new JToggleButton("Push Pull Selection"); + dataFlowModelingButton.addActionListener(new DataFlowModelingButtonListener()); + pushPullSelectionButton.addActionListener(new PushPullSelectionButtonListener()); + pushPullSelectionButton.setEnabled(false); + dataFlowModelingButton.setSelected(true); + + setTitle(TITLE); + setDefaultCloseOperation(HIDE_ON_CLOSE); + Container panel = getContentPane(); + panel.setLayout(new GridLayout(2, 1)); + + ButtonGroup group = new ButtonGroup(); + group.add(dataFlowModelingButton); + group.add(pushPullSelectionButton); + panel.add(dataFlowModelingButton); + panel.add(pushPullSelectionButton); + + pack(); + + Point location = new Point(owner.getX() + (owner.getWidth() / 2) - (this.getWidth() / 2), owner.getY() + (owner.getHeight() / 2) - (this.getHeight() / 2)); + setLocation(location); + + setResizable(false); + } + + @Override + public void stageChanged(Stage newStage) { + if (forbidReentry) { + return; + } + if (newStage instanceof DataFlowModelingStage) { + dataFlowModelingButton.setSelected(true); + pushPullSelectionButton.setEnabled(editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)); + } else if (newStage instanceof PushPullSelectionStage) { + pushPullSelectionButton.setSelected(true); + dataFlowModelingButton.setEnabled(editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)); + } + } + + private class DataFlowModelingButtonListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + forbidReentry = true; + editor.changeStage(Editor.STAGE_DATA_FLOW_MODELING); + forbidReentry = false; + pushPullSelectionButton.setEnabled(editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)); + } + } + + private class PushPullSelectionButtonListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + forbidReentry = true; + editor.changeStage(Editor.STAGE_PUSH_PULL_SELECTION); + forbidReentry = false; + dataFlowModelingButton.setEnabled(editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)); + } + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java index a1184ad..3362f4f 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java @@ -26,6 +26,7 @@ import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; import parser.exceptions.ExpectedLeftCurlyBracket; @@ -86,6 +87,7 @@ public static final String COLON = ":"; public static final String DOT = "."; public static final String DOT_REGX = "\\."; + public static final String DOUBLE_QUOT = "\""; public Parser(final TokenStream stream) { this.stream = stream; @@ -107,14 +109,14 @@ public DataTransferModel doParse() throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedRightCurlyBracket, ExpectedInOrOutOrRefOrSubKeyword, ExpectedStateTransition, ExpectedEquals, - ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, WrongPathExpression, WrongJsonExpression, ExpectedColon { + ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { return parseDataFlowModel(); } public DataTransferModel parseDataFlowModel() throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedRightCurlyBracket, ExpectedInOrOutOrRefOrSubKeyword, ExpectedStateTransition, ExpectedEquals, - ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, WrongPathExpression, WrongJsonExpression, ExpectedColon { + ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { DataTransferModel model = new DataTransferModel(); DataTransferChannel channel; while ((channel = parseChannel(model)) != null) { @@ -131,7 +133,7 @@ throws ExpectedLeftCurlyBracket, ExpectedRightBracket, ExpectedRightCurlyBracket, ExpectedAssignment, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedChannel, ExpectedChannelName, ExpectedInOrOutOrRefOrSubKeyword, - ExpectedStateTransition, ExpectedEquals, WrongPathExpression, WrongJsonExpression, ExpectedColon { + ExpectedStateTransition, ExpectedEquals, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { if (!stream.hasNext()) return null; if (stream.checkNext().equals(RIGHT_CURLY_BRACKET)) return null; @@ -212,7 +214,7 @@ public void parseInit(DataTransferModel model) throws ExpectedLeftCurlyBracket, ExpectedAssignment, ExpectedRHSExpression, WrongRHSExpression, - ExpectedRightBracket, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon { + ExpectedRightBracket, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { String leftBracket = stream.next(); if (!leftBracket.equals(LEFT_CURLY_BRACKET)) throw new ExpectedLeftCurlyBracket(stream.getLine()); while (stream.hasNext() && !stream.checkNext().equals(RIGHT_CURLY_BRACKET)) { @@ -240,7 +242,7 @@ public ChannelMember parseChannelMember(DataTransferModel model, final String inOrOutOrRef) throws ExpectedRightBracket, ExpectedRightCurlyBracket, ExpectedStateTransition, ExpectedEquals, - ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, WrongPathExpression, WrongJsonExpression, ExpectedColon { + ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { if (!stream.hasNext()) throw new ExpectedStateTransition(stream.getLine()); StateTransitionTerm leftTerm = parseStateTransitionTerm(stream, model); if (leftTerm == null || !(leftTerm instanceof Term)) throw new WrongLHSExpression(stream.getLine()); @@ -287,7 +289,7 @@ return channelMember; } - public Expression parseTerm(TokenStream stream, DataTransferModel model) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon { + public Expression parseTerm(TokenStream stream, DataTransferModel model) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { ArrayList expressions = new ArrayList<>(); ArrayList operators = new ArrayList<>(); String operator = null; @@ -317,6 +319,10 @@ } else if (leftBracketOrMinusOrNeg.equals(NEG)) { minusOrNeg = DataTransferModel.neg; symbolName = stream.next(); + } else if (leftBracketOrMinusOrNeg.equals(DOUBLE_QUOT)) { + symbolName = DOUBLE_QUOT + stream.next() + DOUBLE_QUOT; + String doubleQuot = stream.next(); + if (!doubleQuot.equals(DOUBLE_QUOT)) throw new ExpectedDoubleQuotation(stream.getLine()); } else { symbolName = leftBracketOrMinusOrNeg; } @@ -363,7 +369,7 @@ } else { exp = new Constant(symbolName, DataTransferModel.typeInt); } - } else if (symbolName.startsWith("\"") && symbolName.endsWith("\"")) { + } else if (symbolName.startsWith(DOUBLE_QUOT) && symbolName.endsWith(DOUBLE_QUOT)) { // a string value exp = new Constant(symbolName, DataTransferModel.typeString); } else { @@ -424,37 +430,83 @@ stream.next(); } else if (operator.equals(DOT)) { // json accessor - Expression exp = expressions.remove(0); - stream.next(); // DOT - if (stream.checkNext() == null) throw new WrongJsonExpression(stream.getLine()); - String literalOrLeftCurlyBracket = stream.next(); - Expression paramTerm = null; - if (literalOrLeftCurlyBracket.equals(LEFT_CURLY_BRACKET)) { - // parameter - paramTerm = parseTerm(stream, model); - String rightCurlyBracket = stream.next(); - if (rightCurlyBracket == null || !rightCurlyBracket.equals(RIGHT_CURLY_BRACKET)) throw new WrongJsonExpression(stream.getLine()); + while (operator.equals(DOT)) { + Expression exp = expressions.remove(0); + stream.next(); // DOT + if (stream.checkNext() == null) throw new WrongJsonExpression(stream.getLine()); + String literalOrLeftCurlyBracket = stream.next(); + Expression paramTerm = null; + if (literalOrLeftCurlyBracket.equals(LEFT_CURLY_BRACKET)) { + // parameter + paramTerm = parseTerm(stream, model); + String rightCurlyBracket = stream.next(); + if (rightCurlyBracket == null || !rightCurlyBracket.equals(RIGHT_CURLY_BRACKET)) throw new WrongJsonExpression(stream.getLine()); + } else { + // literal + paramTerm = new Constant(literalOrLeftCurlyBracket, DataTransferModel.typeString); + } + Type paramType = null; + if (paramTerm instanceof Variable) { + paramType = ((Variable) paramTerm).getType(); + } else if (paramTerm instanceof Term) { + paramType = ((Term) paramTerm).getType(); + } + Term term = null; + if (paramType != null && DataConstraintModel.typeInt.isAncestorOf(paramType)) { + term = new JsonAccessor(DataConstraintModel.dotParam); + } else { + term = new JsonAccessor(DataConstraintModel.dot); + } + term.addChild(exp); + term.addChild(paramTerm); + expressions.add(term); + operator = stream.checkNext(); + if (operator == null) break; + } + if (operator == null) { + break; + } else if (operator.equals(ADD)) { + operators.add(DataTransferModel.add); + stream.next(); + } else if (operator.equals(MUL)) { + operators.add(DataTransferModel.mul); + stream.next(); + } else if (operator.equals(SUB)) { + operators.add(DataTransferModel.sub); // not minus + stream.next(); + } else if (operator.equals(DIV)) { + operators.add(DataTransferModel.div); + stream.next(); + } else if (operator.equals(MOD)) { + operators.add(DataTransferModel.mod); + stream.next(); + } else if (operator.equals(EQ)) { + operators.add(DataTransferModel.eq); + stream.next(); + } else if (operator.equals(NEQ)) { + operators.add(DataTransferModel.neq); + stream.next(); + } else if (operator.equals(GT)) { + operators.add(DataTransferModel.gt); + stream.next(); + } else if (operator.equals(LT)) { + operators.add(DataTransferModel.lt); + stream.next(); + } else if (operator.equals(GE)) { + operators.add(DataTransferModel.ge); + stream.next(); + } else if (operator.equals(LE)) { + operators.add(DataTransferModel.le); + stream.next(); + } else if (operator.equals(AND)) { + operators.add(DataTransferModel.and); + stream.next(); + } else if (operator.equals(OR)) { + operators.add(DataTransferModel.or); + stream.next(); } else { - // literal - paramTerm = new Constant(literalOrLeftCurlyBracket, DataTransferModel.typeString); + break; } - Type paramType = null; - if (paramTerm instanceof Variable) { - paramType = ((Variable) paramTerm).getType(); - } else if (paramTerm instanceof Term) { - paramType = ((Term) paramTerm).getType(); - } - Term term = null; - if (paramType != null && DataConstraintModel.typeInt.isAncestorOf(paramType)) { - term = new JsonAccessor(DataConstraintModel.dotParam); - } else { - term = new JsonAccessor(DataConstraintModel.dot); - } - term.addChild(exp); - term.addChild(paramTerm); - expressions.add(term); - operator = stream.checkNext(); - if (operator == null || !operator.equals(DOT)) break; } else { break; } @@ -550,21 +602,25 @@ // return jsonTerm; // } - private Expression parseJsonTerm(TokenStream stream, DataTransferModel model) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon { + private Expression parseJsonTerm(TokenStream stream, DataTransferModel model) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { JsonTerm jsonTerm = new JsonTerm(); while (stream.checkNext() != null && !stream.checkNext().equals(RIGHT_CURLY_BRACKET)) { + if (stream.checkNext() == null || !stream.checkNext().equals(DOUBLE_QUOT)) throw new ExpectedDoubleQuotation(stream.getLine()); + String doubleQuot = stream.next(); String key = stream.next(); + if (stream.checkNext() == null || !stream.checkNext().equals(DOUBLE_QUOT)) throw new ExpectedDoubleQuotation(stream.getLine()); + doubleQuot = stream.next(); if (stream.checkNext() == null || !stream.checkNext().equals(COLON)) throw new ExpectedColon(stream.getLine()); String colon = stream.next(); Expression value = parseTerm(stream, model); - jsonTerm.addMember(key, value); + jsonTerm.addMember(DOUBLE_QUOT + key + DOUBLE_QUOT, value); if (stream.checkNext() == null || !stream.checkNext().equals(COMMA)) break; String comma = stream.next(); } return jsonTerm; } - private Expression parseListTerm(TokenStream stream2, DataTransferModel model) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon { + private Expression parseListTerm(TokenStream stream2, DataTransferModel model) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { Term listTerm = new Constant(DataConstraintModel.nil); listTerm.setType(DataConstraintModel.typeList); while (stream.checkNext() != null && !stream.checkNext().equals(RIGHT_SQUARE_BRACKET)) { @@ -597,7 +653,7 @@ } public StateTransitionTerm parseStateTransitionTerm(TokenStream stream, DataTransferModel model) - throws ExpectedRightBracket, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon { + throws ExpectedRightBracket, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { ResourcePath resourcePath = parseResourcePath(stream, model); StateTransitionTerm term = new StateTransitionTerm(resourcePath); int arity = 0; @@ -637,7 +693,7 @@ } public ResourcePath parseResourcePath(TokenStream stream, DataTransferModel model) - throws ExpectedRightBracket, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon { + throws ExpectedRightBracket, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { ResourcePath path = null; do { String literalOrLeftCurlyBracket = stream.next(); @@ -682,90 +738,34 @@ public void addLine(String line) { lines.add(line); line = line.trim(); - tokens.add( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - splitBy( - line.split("[ \t]"), - ADD, - ADD_REGX), - MUL, - MUL_REGX), - SUB, - SUB_REGX), - DIV, - DIV_REGX), - MOD, - MOD), - EQ, - EQ), - NEQ, - NEQ), - GE, - GE), - LE, - LE), - GT, - GT), - LT, - LT), - AND, - AND), - OR, - OR_REGX), - NEG, - NEG), - DOT, - DOT_REGX), - COMMA, - COMMA), - COLON, - COLON), - LEFT_BRACKET, - LEFT_BRACKET_REGX), - RIGHT_BRACKET, - RIGHT_BRACKET_REGX), - EQUALS, - EQUALS), - LEFT_CURLY_BRACKET, - LEFT_CURLY_BRACKET_REGX), - RIGHT_CURLY_BRACKET, - RIGHT_CURLY_BRACKET_REGX), - LEFT_SQUARE_BRACKET, - LEFT_SQUARE_BRACKET_REGX), - RIGHT_SQUARE_BRACKET, - RIGHT_SQUARE_BRACKET_REGX)); + ArrayList tokenList = splitByDoubleQuotation(line); + tokenList = splitBy(tokenList, ADD, ADD_REGX); + tokenList = splitBy(tokenList, MUL, MUL_REGX); + tokenList = splitBy(tokenList, SUB, SUB_REGX); + tokenList = splitBy(tokenList, DIV, DIV_REGX); + tokenList = splitBy(tokenList, MOD, MOD); + tokenList = splitBy(tokenList, EQ, EQ); + tokenList = splitBy(tokenList, NEQ, NEQ); + tokenList = splitBy(tokenList, GE, GE); + tokenList = splitBy(tokenList, LE, LE); + tokenList = splitBy(tokenList, GT, GT); + tokenList = splitBy(tokenList, LT, LT); + tokenList = splitBy(tokenList, AND, AND); + tokenList = splitBy(tokenList, OR, OR_REGX); + tokenList = splitBy(tokenList, NEG, NEG); + tokenList = splitBy(tokenList, DOT, DOT_REGX); + tokenList = splitBy(tokenList, COMMA, COMMA); + tokenList = splitBy(tokenList, COLON, COLON); + tokenList = splitBy(tokenList, LEFT_BRACKET, LEFT_BRACKET_REGX); + tokenList = splitBy(tokenList, RIGHT_BRACKET, RIGHT_BRACKET_REGX); + tokenList = splitBy(tokenList, EQUALS, EQUALS); + tokenList = splitBy(tokenList, LEFT_CURLY_BRACKET, LEFT_CURLY_BRACKET_REGX); + tokenList = splitBy(tokenList, RIGHT_CURLY_BRACKET, RIGHT_CURLY_BRACKET_REGX); + tokenList = splitBy(tokenList, LEFT_SQUARE_BRACKET, LEFT_SQUARE_BRACKET_REGX); + tokenList = splitBy(tokenList, RIGHT_SQUARE_BRACKET, RIGHT_SQUARE_BRACKET_REGX); + tokens.add(tokenList); } - private ArrayList splitBy(String[] tokens, final String delimiter, final String delimiterRegx) { - ArrayList newTokens = new ArrayList<>(); - for (String token: tokens) { - newTokens.add(new Token(token)); - } - return splitBy(newTokens, delimiter, delimiterRegx); - } - private ArrayList splitBy(final List tokens, final String delimiter, final String delimiterRegx) { ArrayList newTokens = new ArrayList<>(); for (Token token: tokens) { @@ -791,6 +791,33 @@ } return newTokens; } + + private ArrayList splitByDoubleQuotation(String line) { + ArrayList newTokens = new ArrayList<>(); + String[] tokens = line.split(DOUBLE_QUOT); + boolean fFirstToken = true; + for (int i = 0; i < tokens.length; i++) { + String token = tokens[i]; + if (!fFirstToken) { + newTokens.add(new Token(DOUBLE_QUOT, true)); + } + if (!fFirstToken || token.length() > 0) { + if (i % 2 == 0) { + for (String t: token.split("[ \t]")) { + newTokens.add(new Token(t)); + } + } else { + // string literal + newTokens.add(new Token(token, true)); + } + } + fFirstToken = false; + } + if (line.endsWith(DOUBLE_QUOT)) { + newTokens.add(new Token(DOUBLE_QUOT, true)); + } + return newTokens; + } public String next() { if (line >= tokens.size()) return null; diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java b/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java index 6ea7dec..eae7ac7 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java @@ -15,6 +15,7 @@ import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedFormulaChannel; import parser.exceptions.ExpectedGeometry; @@ -67,9 +68,10 @@ * @param reader * @throws WrongJsonExpression * @throws ExpectedColon + * @throws ExpectedDoubleQuotation */ public DataTransferModel doParseModel() - throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefOrSubKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, ExpectedModel, ExpectedGeometry, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon { + throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefOrSubKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, ExpectedModel, ExpectedGeometry, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { DataTransferModel model = getParsedModel(); return model; } @@ -91,9 +93,10 @@ * @param stream * @throws WrongJsonExpression * @throws ExpectedColon + * @throws ExpectedDoubleQuotation */ private DataTransferModel getParsedModel() - throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefOrSubKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, ExpectedModel, ExpectedGeometry, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon { + throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefOrSubKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, ExpectedModel, ExpectedGeometry, ExpectedRightCurlyBracket, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { if (!stream.hasNext()) throw new NullPointerException(); diff --git a/AlgebraicDataflowArchitectureModel/src/parser/exceptions/ExpectedDoubleQuotation.java b/AlgebraicDataflowArchitectureModel/src/parser/exceptions/ExpectedDoubleQuotation.java new file mode 100644 index 0000000..434bec3 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/parser/exceptions/ExpectedDoubleQuotation.java @@ -0,0 +1,8 @@ +package parser.exceptions; + +public class ExpectedDoubleQuotation extends ParseException { + + public ExpectedDoubleQuotation(int line) { + super(line); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java index 643be88..58a9df8 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java @@ -373,9 +373,11 @@ ResourceIdentifier resId = ResourceIdentifier.createFrom(inputResPath); for (Map.Entry chParamEnt: channelSelectorAndValues) { Selector sel = chParamEnt.getKey(); - Integer paramIdx = channelSelectorToInputResourcePathParam.get(sel).get(inputResPath); - if (paramIdx != null) { - resId.setPathParam(paramIdx, chParamEnt.getValue()); + if (channelSelectorToInputResourcePathParam.get(sel) != null) { + Integer paramIdx = channelSelectorToInputResourcePathParam.get(sel).get(inputResPath); + if (paramIdx != null) { + resId.setPathParam(paramIdx, chParamEnt.getValue()); + } } } for (Expression var: dependingParameters.keySet()) { @@ -391,9 +393,11 @@ ResourceIdentifier resId = ResourceIdentifier.createFrom(outputResPath); for (Map.Entry chParamEnt: channelSelectorAndValues) { Selector sel = chParamEnt.getKey(); - Integer paramIdx = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); - if (paramIdx != null) { - resId.setPathParam(paramIdx, chParamEnt.getValue()); + if (channelSelectorToOutputResourcePathParam.get(sel) != null) { + Integer paramIdx = channelSelectorToOutputResourcePathParam.get(sel).get(outputResPath); + if (paramIdx != null) { + resId.setPathParam(paramIdx, chParamEnt.getValue()); + } } } for (Expression var: dependingParameters.keySet()) { diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java b/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java index 14e30bb..ac2c94b 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java @@ -32,14 +32,18 @@ || DataConstraintModel.typeList.isAncestorOf(resType) || DataConstraintModel.typeMap.isAncestorOf(resType) || DataConstraintModel.typeJson.isAncestorOf(resType)) { - if (DataConstraintModel.typeList.isAncestorOf(resType)) { + if (resType != null && DataConstraintModel.typeList.isAncestorOf(resType)) { // List resource state = new ListResourceState(); - } else if (DataConstraintModel.typeMap.isAncestorOf(resType)) { + } else if (resType != null && DataConstraintModel.typeMap.isAncestorOf(resType)) { // Map resource state = new MapResourceState(); } else { // Json resource + if (resType == null) { + resType = DataConstraintModel.typeJson; + resourceHierarchy.setResourceStateType(resType); + } state = new JsonResourceState(); children = new LinkedHashMap<>(); for (ResourceHierarchy child: resourceHierarchy.getChildren()) { diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java index 5f25bdb..645ed14 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java @@ -361,7 +361,7 @@ if (resStateValue instanceof Constant) { } else if (resStateValue instanceof JsonTerm) { JsonTerm jsonValue = (JsonTerm) resStateValue; - MapResourceState state = new MapResourceState(); + JsonResourceState state = new JsonResourceState(); Map.Entry createInfo = null; for (String key: jsonValue.keySet()) { String memberName = key.replace("\"", ""); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/SwingPresenter.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/SwingPresenter.java index e935244..4d95497 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/SwingPresenter.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/SwingPresenter.java @@ -124,14 +124,14 @@ if (value instanceof JsonTerm) { JsonTerm widget = (JsonTerm) value; Resource widgetResource = widgetsResource.getChildrenMap().get(newWid); - Expression type = widget.get("\"type\""); + Expression type = widget.get("type"); if (type.toString().equals("\"button\"")) { // Add a button component. - Expression text = widget.get("\"text\""); - Expression x = widget.get("\"x\""); - Expression y = widget.get("\"y\""); - Expression width = widget.get("\"width\""); - Expression height = widget.get("\"height\""); + Expression text = widget.get("text"); + Expression x = widget.get("x"); + Expression y = widget.get("y"); + Expression width = widget.get("width"); + Expression height = widget.get("height"); JButton button = new JButton(text.toString().replace("\"", "")); if (x != null && y != null) { button.setLocation(Integer.parseInt(x.toString()), Integer.parseInt(y.toString())); @@ -163,7 +163,7 @@ } resources.put(newWid, widgetResource); - Resource widgetXResource = widgetResource.getChildrenMap().get("\"x\""); + Resource widgetXResource = widgetResource.getChildrenMap().get("x"); if (widgetXResource != null) { ComponentXReceiver nativeXReceiver = new ComponentXReceiver(button); // widgetResource => button simulator.addNativeReceiver(nativeXReceiver, setXChannel, widgetXResource); @@ -175,7 +175,7 @@ resources.put(newWid, widgetXResource); } - Resource widgetYResource = widgetResource.getChildrenMap().get("\"y\""); + Resource widgetYResource = widgetResource.getChildrenMap().get("y"); if (widgetYResource != null) { ComponentYReceiver nativeYReceiver = new ComponentYReceiver(button); // widgetResource => button simulator.addNativeReceiver(nativeYReceiver, setYChannel, widgetYResource); @@ -187,7 +187,7 @@ resources.put(newWid, widgetYResource); } - Resource widgetWidthResource = widgetResource.getChildrenMap().get("\"width\""); + Resource widgetWidthResource = widgetResource.getChildrenMap().get("width"); if (widgetWidthResource != null) { ComponentWidthReceiver nativeWidthReceiver = new ComponentWidthReceiver(button); // widgetResource => button simulator.addNativeReceiver(nativeWidthReceiver, setWidthChannel, widgetWidthResource); @@ -199,7 +199,7 @@ resources.put(newWid, widgetWidthResource); } - Resource widgetHeightResource = widgetResource.getChildrenMap().get("\"height\""); + Resource widgetHeightResource = widgetResource.getChildrenMap().get("height"); if (widgetHeightResource != null) { ComponentHeightReceiver nativeHeightReceiver = new ComponentHeightReceiver(button); // widgetResource => button simulator.addNativeReceiver(nativeHeightReceiver, setHeightChannel, widgetHeightResource); @@ -212,11 +212,11 @@ } } else if (type.toString().equals("\"label\"")) { // Add a label component. - Expression text = widget.get("\"text\""); - Expression x = widget.get("\"x\""); - Expression y = widget.get("\"y\""); - Expression width = widget.get("\"width\""); - Expression height = widget.get("\"height\""); + Expression text = widget.get("text"); + Expression x = widget.get("x"); + Expression y = widget.get("y"); + Expression width = widget.get("width"); + Expression height = widget.get("height"); JLabel label = new JLabel(text.toString().replace("\"", "")); if (x != null && y != null) { label.setLocation(Integer.parseInt(x.toString()), Integer.parseInt(y.toString())); @@ -295,10 +295,10 @@ } } else if (type.toString().equals("\"textInput\"")) { // Add a text input component. - Expression x = widget.get("\"x\""); - Expression y = widget.get("\"y\""); - Expression width = widget.get("\"width\""); - Expression height = widget.get("\"height\""); + Expression x = widget.get("x"); + Expression y = widget.get("y"); + Expression width = widget.get("width"); + Expression height = widget.get("height"); JTextField textField = new JTextField(10); if (x != null && y != null) { textField.setLocation(Integer.parseInt(x.toString()), Integer.parseInt(y.toString())); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/timers/TimerService.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/timers/TimerService.java index 70d6b51..1ef8061 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/timers/TimerService.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/timers/TimerService.java @@ -68,7 +68,7 @@ JsonTerm timerValue = (JsonTerm) value; Resource timerResource = timersResource.getChildrenMap().get(tid); // Add a timer. - Expression intervalExp = timerValue.get("\"interval\""); + Expression intervalExp = timerValue.get("interval"); long interval = Long.parseLong(((Constant) intervalExp).toString()); ScheduledThreadPoolExecutor timer = new ScheduledThreadPoolExecutor(0); timers.put(tid, timer); diff --git a/AlgebraicDataflowArchitectureModel/src/tests/CodeGeneratorTest.java b/AlgebraicDataflowArchitectureModel/src/tests/CodeGeneratorTest.java index b318c30..8ee6b46 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/CodeGeneratorTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/CodeGeneratorTest.java @@ -18,6 +18,7 @@ import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; import parser.exceptions.ExpectedLeftCurlyBracket; @@ -45,7 +46,7 @@ System.out.println(codetree); } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { + | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } catch (FileNotFoundException e) { diff --git a/AlgebraicDataflowArchitectureModel/src/tests/DataStorageDecisionTest.java b/AlgebraicDataflowArchitectureModel/src/tests/DataStorageDecisionTest.java index b228862..0db9f4b 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/DataStorageDecisionTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/DataStorageDecisionTest.java @@ -14,6 +14,7 @@ import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; import parser.exceptions.ExpectedLeftCurlyBracket; @@ -43,7 +44,7 @@ } } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { + | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } catch (FileNotFoundException e) { diff --git a/AlgebraicDataflowArchitectureModel/src/tests/DataStorageNecessityTest.java b/AlgebraicDataflowArchitectureModel/src/tests/DataStorageNecessityTest.java index 73eff57..d95fb08 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/DataStorageNecessityTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/DataStorageNecessityTest.java @@ -13,6 +13,7 @@ import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; import parser.exceptions.ExpectedLeftCurlyBracket; @@ -43,7 +44,7 @@ } } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { + | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } catch (FileNotFoundException e) { diff --git a/AlgebraicDataflowArchitectureModel/src/tests/EdgeTransitionSelectableTest.java b/AlgebraicDataflowArchitectureModel/src/tests/EdgeTransitionSelectableTest.java index c3b11ab..b88f7c3 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/EdgeTransitionSelectableTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/EdgeTransitionSelectableTest.java @@ -13,6 +13,7 @@ import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; import parser.exceptions.ExpectedLeftCurlyBracket; @@ -42,7 +43,7 @@ } } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { + | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } catch (FileNotFoundException e) { diff --git a/AlgebraicDataflowArchitectureModel/src/tests/InverseTest.java b/AlgebraicDataflowArchitectureModel/src/tests/InverseTest.java index 165013e..0d0efe1 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/InverseTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/InverseTest.java @@ -22,6 +22,7 @@ import parser.Parser; import parser.Parser.TokenStream; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedRightBracket; import parser.exceptions.WrongJsonExpression; @@ -111,7 +112,7 @@ assertTrue(inv.contains(z)); assertFalse(inv.contains(v)); } - } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon e) { + } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } diff --git a/AlgebraicDataflowArchitectureModel/src/tests/NativeAccessTest.java b/AlgebraicDataflowArchitectureModel/src/tests/NativeAccessTest.java index e014bab..a91d089 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/NativeAccessTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/NativeAccessTest.java @@ -16,6 +16,7 @@ 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; @@ -92,7 +93,7 @@ Expression sendMessage = parser.parseTerm(stream, model); textSender.sendToModel(sendMessage); // Send a message to the model - } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon e) { + } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } diff --git a/AlgebraicDataflowArchitectureModel/src/tests/SimulatorTest.java b/AlgebraicDataflowArchitectureModel/src/tests/SimulatorTest.java index ca760bb..6221b58 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/SimulatorTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/SimulatorTest.java @@ -21,6 +21,7 @@ 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; @@ -156,6 +157,8 @@ customer_add_2.getStateTransition().setNextStateExpression(nextStateExp6); c.addChannelMemberAsOutput(customer_add_2); + model.addInputChannel(cio_addCustomer); + model.addInputChannel(cio_addCompany); model.addInputChannel(cio_setCustomerOff); model.addInputChannel(cio_setCompanyAdd); model.addChannel(c); @@ -217,7 +220,7 @@ System.out.println("companies:" + nextNextNextState.getResource(ResourceIdentifier.createFrom(companies)).getState().getValue()); System.out.println("customers:" + nextNextNextState.getResource(ResourceIdentifier.createFrom(customers)).getState().getValue()); - } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined e) { + } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined | ExpectedDoubleQuotation e) { e.printStackTrace(); } } diff --git a/AlgebraicDataflowArchitectureModel/src/tests/UpdateConflictCheckTest.java b/AlgebraicDataflowArchitectureModel/src/tests/UpdateConflictCheckTest.java index c507ae9..de362c9 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/UpdateConflictCheckTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/UpdateConflictCheckTest.java @@ -12,6 +12,7 @@ import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; import parser.exceptions.ExpectedLeftCurlyBracket; @@ -36,7 +37,7 @@ } catch (ExpectedRightBracket | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedRightCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedAssignment - | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { + | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } catch (FileNotFoundException e) { diff --git a/AlgebraicDataflowArchitectureModel/src/tests/parser/ParseTest.java b/AlgebraicDataflowArchitectureModel/src/tests/parser/ParseTest.java index 6234ba9..8c5eae4 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/parser/ParseTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/parser/ParseTest.java @@ -18,6 +18,7 @@ import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; +import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; import parser.exceptions.ExpectedLeftCurlyBracket; @@ -58,7 +59,7 @@ | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage - | UnificationFailed | ValueUndefined | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon e) { + | UnificationFailed | ValueUndefined | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } catch (FileNotFoundException e) {