diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractSystemAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractSystemAction.java new file mode 100644 index 0000000..e3f827d --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractSystemAction.java @@ -0,0 +1,23 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +import graphicalrefactor.editor.Editor; +import graphicalrefactor.views.GraphicalRefactor; + +public abstract class AbstractSystemAction extends AbstractAction { + + protected GraphicalRefactor frame; + + public AbstractSystemAction(String name, GraphicalRefactor frame) { + super(name); + this.frame = frame; + } + + public void setFrame(GraphicalRefactor frame) { + this.frame = frame; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractViewerAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractViewerAction.java index 97181bf..13c4a07 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractViewerAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractViewerAction.java @@ -6,7 +6,7 @@ import com.mxgraph.swing.mxGraphComponent; -public class AbstractViewerAction extends AbstractAction { +public abstract class AbstractViewerAction extends AbstractAction { protected mxGraphComponent graphComponent = null; @@ -14,9 +14,4 @@ super(name); this.graphComponent = graphComponent; } - - @Override - public void actionPerformed(ActionEvent e) { - } - } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DeleteAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DeleteAction.java new file mode 100644 index 0000000..1ac8a47 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DeleteAction.java @@ -0,0 +1,23 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; + +import graphicalrefactor.editor.Editor; + +public class DeleteAction extends AbstractEditorAction { + + /** + * + */ + private static final long serialVersionUID = -4410145389391154784L; + + public DeleteAction(Editor editor) { + super("Delete", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + editor.delete(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java index 78a39ac..53939bd 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java @@ -39,6 +39,7 @@ ModelExtension.extendModel(model); TypeInference.infer(graph, model); String fileName = editor.getCurFileName(); + if (fileName == null) fileName = "Main"; String mainTypeName = fileName.split("\\.")[0]; boolean exist = false; for (IdentifierTemplate id: model.getIdentifierTemplates()) { diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java index 0236d5d..dfa7a57 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java @@ -40,6 +40,7 @@ ModelExtension.extendModel(model); TypeInference.infer(graph, model); String fileName = editor.getCurFileName(); + if (fileName == null) fileName = "Main"; String mainTypeName = fileName.split("\\.")[0]; boolean exist = false; for (IdentifierTemplate id: model.getIdentifierTemplates()) { diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewChannelAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewChannelAction.java new file mode 100644 index 0000000..9d8f747 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewChannelAction.java @@ -0,0 +1,28 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JOptionPane; + +import graphicalrefactor.editor.Editor; +import models.dataFlowModel.DataflowChannelGenerator; + +public class NewChannelAction extends AbstractEditorAction { + + /** + * + */ + private static final long serialVersionUID = 5979007029473101802L; + + public NewChannelAction(Editor editor) { + super("Channel...", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + String channelName = JOptionPane.showInputDialog("Channel Name:"); + if (channelName == null) return; + editor.addChannelGenerator(new DataflowChannelGenerator(channelName)); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewFormulaChannelAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewFormulaChannelAction.java new file mode 100644 index 0000000..7fb9299 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewFormulaChannelAction.java @@ -0,0 +1,62 @@ +package graphicalrefactor.actions; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import graphicalrefactor.editor.Editor; +import graphicalrefactor.views.GraphicalRefactor; +import models.visualModel.FormulaChannelGenerator; + +public class NewFormulaChannelAction extends AbstractEditorAction implements ActionListener { + + /** + * + */ + private static final long serialVersionUID = 5345875219049178252L; + + public NewFormulaChannelAction(Editor editor) { + super("FormulaChannel...", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + JPanel panel = new JPanel(); + GridLayout layout = new GridLayout(2,2); + panel.setLayout(layout); + layout.setVgap(5); + layout.setHgap(20); + panel.add(new JLabel("Channel Name:")); + JTextField channelText = new JTextField(); + panel.add(channelText); + panel.add(new JLabel("Symbol:")); + JTextField symbolText = new JTextField(); + panel.add(symbolText); + + int r = JOptionPane.showConfirmDialog( + null, // �I�[�i�[�E�B���h�E + panel, // ���b�Z�[�W + "New Formula Channel", // �E�B���h�E�^�C�g�� + JOptionPane.OK_CANCEL_OPTION, // �I�v�V�����i�{�^���̎�ށj + JOptionPane.QUESTION_MESSAGE); // ���b�Z�[�W�^�C�v�i�A�C�R���̎�ށj + + String channelName = channelText.getText(); + String symbol = symbolText.getText(); + if(r == JOptionPane.OK_OPTION) { + editor.addFormulaChannelGenerator(new FormulaChannelGenerator(channelName, editor.getModel().getSymbol(symbol))); + } + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewIOChannelAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewIOChannelAction.java new file mode 100644 index 0000000..7e2c884 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewIOChannelAction.java @@ -0,0 +1,29 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JOptionPane; + + +import graphicalrefactor.editor.Editor; +import models.dataFlowModel.DataflowChannelGenerator; + +public class NewIOChannelAction extends AbstractEditorAction { + + /** + * + */ + private static final long serialVersionUID = -1657072017390171313L; + + public NewIOChannelAction(Editor editor) { + super("I/O Channel", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + String channelName = JOptionPane.showInputDialog("I/O Channel Name:"); + if (channelName == null) return; + editor.addIOChannelGenerator(new DataflowChannelGenerator(channelName)); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewModelAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewModelAction.java new file mode 100644 index 0000000..c79d868 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewModelAction.java @@ -0,0 +1,24 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; + +import graphicalrefactor.editor.Editor; +import graphicalrefactor.views.GraphicalRefactor; + +public class NewModelAction extends AbstractSystemAction { + /** + * + */ + private static final long serialVersionUID = 8484493203589724589L; + + public NewModelAction(GraphicalRefactor frame) { + super("Model", frame); + } + + @Override + public void actionPerformed(ActionEvent e) { + frame.getEditor().clear(); + frame.setTitle(frame.title); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewResourceAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewResourceAction.java new file mode 100644 index 0000000..600daf7 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewResourceAction.java @@ -0,0 +1,28 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JOptionPane; + +import graphicalrefactor.editor.Editor; +import models.dataConstraintModel.IdentifierTemplate; + +public class NewResourceAction extends AbstractEditorAction { + + /** + * + */ + private static final long serialVersionUID = -4439207504700741286L; + + public NewResourceAction(Editor editor) { + super("Resource...", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + String resName = JOptionPane.showInputDialog("Resourece Name:"); + if (resName == null) return; + editor.addIdentifierTemplate(new IdentifierTemplate(resName, 0)); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/OpenAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/OpenAction.java index e018590..2fcfe73 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/OpenAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/OpenAction.java @@ -5,10 +5,12 @@ import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileNameExtensionFilter; import graphicalrefactor.editor.Editor; +import graphicalrefactor.views.GraphicalRefactor; -public class OpenAction extends AbstractEditorAction { +public class OpenAction extends AbstractSystemAction { /** * */ @@ -16,17 +18,21 @@ private String lastDir = null; - public OpenAction(Editor editor) { - super("Open...", editor); + public OpenAction(GraphicalRefactor 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"); 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() { @@ -40,11 +46,15 @@ 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()); } } } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAction.java index 118f37a..62f0609 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAction.java @@ -2,22 +2,25 @@ import java.awt.event.ActionEvent; -import javax.swing.AbstractAction; +import graphicalrefactor.editor.Editor; +import graphicalrefactor.views.GraphicalRefactor; -public class SaveAction extends AbstractAction { +public class SaveAction extends AbstractSystemAction { /** * */ private static final long serialVersionUID = 5660460585305281982L; - public SaveAction() { - super("Save"); + public SaveAction(GraphicalRefactor frame) { + super("Save", frame); } @Override public void actionPerformed(ActionEvent e) { - // TODO Auto-generated method stub - + Editor editor = frame.getEditor(); + if (editor != null && editor.getCurFileName() != null) { + editor.save(); + } } } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAsAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAsAction.java new file mode 100644 index 0000000..05a90ca --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAsAction.java @@ -0,0 +1,62 @@ +package graphicalrefactor.actions; + +import java.awt.event.ActionEvent; +import java.io.File; + +import javax.swing.AbstractAction; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileNameExtensionFilter; + +import graphicalrefactor.editor.Editor; +import graphicalrefactor.views.GraphicalRefactor; + +public class SaveAsAction extends AbstractSystemAction { + /** + * + */ + private static final long serialVersionUID = -2599502783032684084L; + + private String lastDir = null; + + public SaveAsAction(GraphicalRefactor frame) { + super("Save As...", frame); + } + + @Override + public void actionPerformed(ActionEvent e) { + Editor editor = frame.getEditor(); + if (editor != null) { + String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); + + 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 lcase = file.getName().toLowerCase(); + return lcase.endsWith(".model"); + } + + @Override + public String getDescription() { + return null; + } + }; + fc.addChoosableFileFilter(defaultFilter); + fc.addChoosableFileFilter(model); + fc.addChoosableFileFilter(dtram); + int rc = fc.showDialog(null, "Save Model File"); + if (rc == JFileChooser.APPROVE_OPTION) { + lastDir = fc.getSelectedFile().getParent(); + editor.setCurFilePath(fc.getSelectedFile().getAbsolutePath()); + editor.save(); + frame.setTitle(frame.title + " - " + fc.getSelectedFile().getAbsolutePath()); + } + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java index 0a0e3a1..9a0a8a0 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java @@ -4,7 +4,10 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -19,8 +22,10 @@ import com.mxgraph.model.mxIGraphModel; import com.mxgraph.util.mxConstants; import com.mxgraph.util.mxPoint; +import com.mxgraph.view.mxCellState; import com.mxgraph.util.mxRectangle; import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; import algorithms.NecessityOfStoringResourceStates; import algorithms.SelectableDataTransfers; @@ -28,6 +33,7 @@ import code.ast.CompilationUnit; import graphicalrefactor.layouts.*; import models.Edge; +import models.EdgeAttribute; import models.Node; import models.dataConstraintModel.ChannelGenerator; import models.dataConstraintModel.ChannelMember; @@ -38,16 +44,25 @@ import models.dataFlowModel.ResourceDependency; import models.dataFlowModel.ResourceDependencyGraph; import models.dataFlowModel.ResourceNode; +import models.visualModel.FormulaChannelGenerator; import parser.ExpectedAssignment; import parser.ExpectedChannel; import parser.ExpectedChannelName; import parser.ExpectedEquals; +import parser.ExpectedFormulaChannel; +import parser.ExpectedGeometry; import parser.ExpectedInOrOutOrRefKeyword; +import parser.ExpectedIoChannel; import parser.ExpectedLeftCurlyBracket; +import parser.ExpectedModel; +import parser.ExpectedNode; import parser.ExpectedRHSExpression; +import parser.ExpectedResource; import parser.ExpectedRightBracket; import parser.ExpectedStateTransition; import parser.Parser; +import parser.Parser.TokenStream; +import parser.ParserDTRAM; import parser.WrongLHSExpression; import parser.WrongRHSExpression; @@ -57,6 +72,7 @@ private mxGraph graph = null; private String curFileName = null; + private String curFilePath = null; private DataFlowModel model = null; private ResourceDependencyGraph resourceDependencyGraph = null; private ArrayList codes = null; @@ -74,17 +90,30 @@ } public DataFlowModel getModel() { + if (model == null) { + model = new DataFlowModel(); + } return model; } - public void setModel(DataFlowModel model) { - this.model = model; + public ResourceDependencyGraph getResourceDependencyGraph() { + if (resourceDependencyGraph == null) { + updateResourceDependencyGraph(getModel()); + } + return resourceDependencyGraph; } - public ResourceDependencyGraph getResourceDependencyGraph() { + public ResourceDependencyGraph updateResourceDependencyGraph(DataFlowModel model) { + ResourceDependencyGraph resourceGraph = NecessityOfStoringResourceStates.doDecide(model); + resourceDependencyGraph = SelectableDataTransfers.init(resourceGraph); + updateEdgeAttiributes(resourceDependencyGraph); return resourceDependencyGraph; } + public void resetResourceDependencyGraph() { + resourceDependencyGraph = null; + } + public void setResourceDependencyGraph(ResourceDependencyGraph resourceDependencyGraph) { this.resourceDependencyGraph = resourceDependencyGraph; } @@ -101,6 +130,24 @@ return curFileName; } + public String getCurFilePath() { + return curFilePath; + } + + public void setCurFilePath(String curFilePath) { + this.curFilePath = curFilePath; + this.curFileName = new File(curFilePath).getName(); + } + + public void clear() { + model = null; + ((mxGraphModel) graph.getModel()).clear(); + resourceDependencyGraph = null; + curFilePath = null; + curFileName = null; + codes = null; + } + /** * Open a given file, parse the file, construct a DataFlowModel and a mxGraph * @param file given file @@ -108,14 +155,55 @@ */ public DataFlowModel open(File file) { try { + + String extension =""; + if(file != null && file.exists()) { + //�t�@�C�������擾 + String name = file.getName(); + + //�g���q���擾 + extension = name.substring(name.lastIndexOf(".")); + } + if(extension.contains(".model")) { + openModel(file); + } else { + + ParserDTRAM parserDTRAM = new ParserDTRAM(new BufferedReader(new FileReader(file))); + + try { + model = parserDTRAM.doParseModel(); + graph = constructGraph(model); + parserDTRAM.doParseGeometry(graph); + curFilePath = file.getAbsolutePath(); + curFileName = file.getName(); + if (!UpdateConflictCheck.run(model)) return null; + updateResourceDependencyGraph(model); + return model; + } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefKeyword + | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression + | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedModel | ExpectedGeometry | ExpectedNode | ExpectedResource | ExpectedFormulaChannel | ExpectedIoChannel e) { + e.printStackTrace(); + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + return null; + } + + public DataFlowModel openModel(File file) { + try { + Parser parser = new Parser(new BufferedReader(new FileReader(file))); - try { + + try { model = parser.doParse(); + curFilePath = file.getAbsolutePath(); curFileName = file.getName(); if (!UpdateConflictCheck.run(model)) return null; - ResourceDependencyGraph resourceGraph = NecessityOfStoringResourceStates.doDecide(model); - resourceDependencyGraph = SelectableDataTransfers.init(resourceGraph); - graph = constructGraph(model, resourceDependencyGraph); + graph = constructGraph(model); + updateResourceDependencyGraph(model); return model; } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression @@ -127,6 +215,83 @@ } return null; } + + + public void save() { + if (curFilePath != null) { + try { + File file = new File(curFilePath); + String extension = ""; + if(file != null && file.exists()) { + //�t�@�C�������擾 + String name = file.getName(); + + //�g���q���擾 + extension = name.substring(name.lastIndexOf(".")); + } + if(extension.contains(".model")) { + saveModel(file); + } else { + + FileWriter filewriter = new FileWriter(file); + filewriter.write("model {\n"); + filewriter.write(model.getSourceText()); + filewriter.write("}\n"); + filewriter.write("geometry {\n"); + + 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(); + + for(ChannelGenerator ch: model.getChannelGenerators()) { + if(ch instanceof FormulaChannelGenerator && state.getLabel().equals(ch.getChannelName())) { + filewriter.write("node fc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"); + } else if(ch instanceof ChannelGenerator && state.getLabel().equals(ch.getChannelName())) { + filewriter.write("node c " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"); + } + } + + for (IdentifierTemplate res: model.getIdentifierTemplates()){ + if(res instanceof IdentifierTemplate && state.getLabel().equals(res.getResourceName())) + filewriter.write("node r " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"); + } + + for (ChannelGenerator ioC: model.getIOChannelGenerators()) { + if(ioC instanceof ChannelGenerator && state.getLabel().equals(ioC.getChannelName())) { + filewriter.write("node ioc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"); + } + } + } + } + + filewriter.write("}\n"); + filewriter.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + + 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(); + } + } + } /** * Construct a mxGraph from DataFlowModel and DataFlowModel @@ -134,7 +299,7 @@ * @param resourceDependencyGraph * @return constructed mxGraph */ - public mxGraph constructGraph(DataFlowModel model, ResourceDependencyGraph resourceDependencyGraph) { + public mxGraph constructGraph(DataFlowModel model) { ((mxGraphModel) graph.getModel()).clear(); Object parent = graph.getDefaultParent(); graph.getModel().beginUpdate(); @@ -150,80 +315,48 @@ Map channelsIn = new HashMap<>(); Map channelsOut = new HashMap<>(); Map resources = new HashMap<>(); - Map> resourceToChannels = new HashMap<>(); - Map> channelToResources = new HashMap<>(); - Set refEdgeCreated = new HashSet<>(); // create channel vertices - for (Edge e : resourceDependencyGraph.getEdges()) { - if (e instanceof ResourceDependency) { - ResourceDependency dependency = (ResourceDependency) e; - DataflowChannelGenerator channelGen = dependency.getChannelGenerator(); - if (channelsIn.get(channelGen) == null || channelsOut.get(channelGen) == null) { - 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 - channelsIn.put(channelGen, port_in); - channelsOut.put(channelGen, port_out); - } + for (ChannelGenerator c: model.getChannelGenerators()) { + DataflowChannelGenerator channelGen = (DataflowChannelGenerator) c; + if (channelsIn.get(channelGen) == null || channelsOut.get(channelGen) == null) { + 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 + channelsIn.put(channelGen, port_in); + channelsOut.put(channelGen, port_out); } } // create resource vertices - for (Node n : resourceDependencyGraph.getNodes()) { - if (n instanceof ResourceNode) { - ResourceNode resourceNode = (ResourceNode) n; - Object resource = graph.insertVertex(parent, null, - resourceNode.getIdentifierTemplate().getResourceName(), 20, 20, 80, 30, - "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex - resources.put(resourceNode.getIdentifierTemplate(), resource); - } + for (IdentifierTemplate res: model.getIdentifierTemplates()) { + Object resource = graph.insertVertex(parent, null, + res.getResourceName(), 20, 20, 80, 30, + "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex + resources.put(res, resource); } - + // add input, output and reference edges - for (Edge e : resourceDependencyGraph.getEdges()) { - if (e instanceof ResourceDependency) { - ResourceDependency dependency = (ResourceDependency) e; - DataflowChannelGenerator channelGen = dependency.getChannelGenerator(); - ResourceNode srcResource = (ResourceNode) dependency.getSource(); - ResourceNode dstResource = (ResourceNode) dependency.getDestination(); - // input edge - Map resToChannelEdges = resourceToChannels.get(srcResource); - if (resToChannelEdges == null) { - resToChannelEdges = new HashMap<>(); - resourceToChannels.put(srcResource, resToChannelEdges); - } - if (resToChannelEdges.get(channelGen) == null) { - mxCell edge = (mxCell) graph.insertEdge(parent, null, dependency.getAttribute(), resources.get(srcResource.getIdentifierTemplate()), channelsIn.get(channelGen), "movable=false"); - resToChannelEdges.put(channelGen, edge); - } else { - mxCell edge = resToChannelEdges.get(channelGen); - ((PushPullAttribute) edge.getValue()).intersectOptions(((PushPullAttribute) dependency.getAttribute()).getOptions()); - } - // output edge - Set resSet = channelToResources.get(channelGen); - if (resSet == null) { - resSet = new HashSet<>(); - channelToResources.put(channelGen, resSet); - } - if (!resSet.contains(dstResource)) { - graph.insertEdge(parent, null, null, channelsOut.get(channelGen), resources.get(dstResource.getIdentifierTemplate()), "movable=false"); - resSet.add(dstResource); - } - // reference edges - if (!refEdgeCreated.contains(channelGen)) { - refEdgeCreated.add(channelGen); - for (IdentifierTemplate refRes: channelGen.getReferenceIdentifierTemplates()) { - mxCell edge = (mxCell) graph.insertEdge(parent, null, null, resources.get(refRes), channelsIn.get(channelGen), "dashed=true;movable=false"); - } - } + for (ChannelGenerator ch: model.getChannelGenerators()) { + DataflowChannelGenerator channelGen = (DataflowChannelGenerator) ch; + // input edge + for (IdentifierTemplate srcRes: channelGen.getInputIdentifierTemplates()) { + graph.insertEdge(parent, null, new SrcDstAttribute(srcRes, channelGen), resources.get(srcRes), channelsIn.get(channelGen), "movable=false"); + } + // output edge + for (IdentifierTemplate dstRes: channelGen.getOutputIdentifierTemplates()) { + graph.insertEdge(parent, null, new SrcDstAttribute(channelGen, dstRes), channelsOut.get(channelGen), resources.get(dstRes), "movable=false"); + } + // reference edges + for (IdentifierTemplate refRes: channelGen.getReferenceIdentifierTemplates()) { + graph.insertEdge(parent, null, null, resources.get(refRes), channelsIn.get(channelGen), "dashed=true;movable=false"); } } - + for (ChannelGenerator ioChannelGen: model.getIOChannelGenerators()) { if (channelsOut.get(ioChannelGen) == null) { Object channel = graph.insertVertex(parent, null, ioChannelGen.getChannelName(), 150, 20, 30, 30); // insert an I/O channel as a vertex @@ -236,9 +369,6 @@ } } } - - graph.setAllowDanglingEdges(false); - graph.setCellsDisconnectable(false); } finally { graph.getModel().endUpdate(); } @@ -258,13 +388,42 @@ } } + public void updateEdgeAttiributes(ResourceDependencyGraph resourceDependencyGraph) { + Object parent = graph.getDefaultParent(); + graph.getModel().beginUpdate(); + try { + // add input, output and reference edges + for (Edge e : resourceDependencyGraph.getEdges()) { + if (e instanceof ResourceDependency) { + ResourceDependency dependency = (ResourceDependency) e; + DataflowChannelGenerator channelGen = dependency.getChannelGenerator(); + ResourceNode srcRes = (ResourceNode) dependency.getSource(); + // input edge + for (Object edge: graph.getChildEdges(parent)) { + mxCell edgeCell = (mxCell) edge; + if (edgeCell.getValue() instanceof SrcDstAttribute) { + SrcDstAttribute edgeAttr = (SrcDstAttribute) edgeCell.getValue(); + if (edgeAttr.getSrouce() == srcRes.getIdentifierTemplate() && edgeAttr.getDestination() == channelGen) { + edgeCell.setValue(dependency.getAttribute()); + break; + } + } + } + } + } + } finally { + graph.getModel().endUpdate(); + } + graph.refresh(); + } + public void setTreeLayout() { Object parent = graph.getDefaultParent(); graph.getModel().beginUpdate(); try { mxCompactTreeLayout ctl = new mxCompactTreeLayout(graph); ctl.setLevelDistance(100); -// ctl.setHorizontal(false); + // ctl.setHorizontal(false); ctl.setEdgeRouting(false); ctl.execute(parent); } finally { @@ -282,4 +441,210 @@ graph.getModel().endUpdate(); } } + + public void addIdentifierTemplate(IdentifierTemplate res) { + getModel().addIdentifierTemplate(res); + resetResourceDependencyGraph(); + graph.getModel().beginUpdate(); + Object parent = graph.getDefaultParent(); + try { + graph.insertVertex(parent, null, res.getResourceName(), 20, 20, 80, 30, + "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex + } finally { + graph.getModel().endUpdate(); + } + } + + public void addChannelGenerator(DataflowChannelGenerator channelGen) { + getModel().addChannelGenerator(channelGen); + resetResourceDependencyGraph(); + 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); + + 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(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 addIOChannelGenerator(DataflowChannelGenerator ioChannelGen) { + getModel().addIOChannelGenerator(ioChannelGen); + resetResourceDependencyGraph(); + 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); + + 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 addFormulaChannelGenerator(FormulaChannelGenerator formulaChannelGen) { + getModel().addChannelGenerator(formulaChannelGen); + resetResourceDependencyGraph(); + 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); + + 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(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(); + } + } + + public boolean connectEdge(mxCell edge, mxCell src, mxCell dst) { + DataFlowModel model = getModel(); + ChannelGenerator srcCh = model.getChannelGenerator((String) src.getValue()); + if (srcCh == null) { + srcCh = model.getIOChannelGenerator((String) src.getValue()); + if (srcCh == null) { + IdentifierTemplate srcRes = model.getIdentifierTemplate((String) src.getValue()); + ChannelGenerator dstCh = model.getChannelGenerator((String) dst.getValue()); + if (srcRes == null || dstCh == null) return false; + // resource to channel edge + ChannelMember srcCm = new ChannelMember(srcRes); + ((DataflowChannelGenerator ) dstCh).addChannelMemberAsInput(srcCm); + edge.setValue(new SrcDstAttribute(srcRes, dstCh)); + resetResourceDependencyGraph(); + return true; + } + } + IdentifierTemplate dstRes = model.getIdentifierTemplate((String) dst.getValue()); + if (dstRes == null) return false; + // channel to resource edge + ChannelMember dstCm = new ChannelMember(dstRes); + ((DataflowChannelGenerator) srcCh).addChannelMemberAsOutput(dstCm); + edge.setValue(new SrcDstAttribute(srcCh, dstRes)); + resetResourceDependencyGraph(); + 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.getIdentifierTemplate(srcName) != null) { + // resource to channel edge + ChannelGenerator ch = model.getChannelGenerator(dstName); + ch.removeChannelMember(model.getIdentifierTemplate(srcName)); + } else if (model.getIdentifierTemplate(dstName) != null) { + // channel to resource edge + ChannelGenerator ch = model.getChannelGenerator(srcName); + if (ch == null) { + ch = model.getIOChannelGenerator(srcName); + } + ch.removeChannelMember(model.getIdentifierTemplate(dstName)); + } + } else if (cell.isVertex()) { + String name = (String) cell.getValue(); + if (model.getChannelGenerator(name) != null) { + model.removeChannelGenerator(name); + } else if (model.getIOChannelGenerator(name) != null) { + model.removeIOChannelGenerator(name); + } else if (model.getIdentifierTemplate(name) != null) { + model.removeIdentifierTemplate(name); + } + } + } + graph.removeCells(graph.getSelectionCells()); + resetResourceDependencyGraph(); + } + + public void setChannelCode(DataflowChannelGenerator ch, String code) { + ch.setSourceText(code); + TokenStream stream = new TokenStream(); + for (String line: code.split("\n")) { + stream.addLine(line); + } + try { + DataflowChannelGenerator ch2 = Parser.parseChannel(stream, getModel()); + for (ChannelMember chm2: ch2.getInputChannelMembers()) { + for (ChannelMember chm: ch.getInputChannelMembers()) { + if (chm2.getIdentifierTemplate() == chm.getIdentifierTemplate()) { + chm.setStateTransition(chm2.getStateTransition()); + break; + } + } + } + for (ChannelMember chm2: ch2.getOutputChannelMembers()) { + for (ChannelMember chm: ch.getOutputChannelMembers()) { + if (chm2.getIdentifierTemplate() == chm.getIdentifierTemplate()) { + chm.setStateTransition(chm2.getStateTransition()); + break; + } + } + } + for (ChannelMember chm2: ch2.getReferenceChannelMembers()) { + for (ChannelMember chm: ch.getReferenceChannelMembers()) { + if (chm2.getIdentifierTemplate() == chm.getIdentifierTemplate()) { + chm.setStateTransition(chm2.getStateTransition()); + break; + } + } + } + resetResourceDependencyGraph(); + } catch (ExpectedRightBracket | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket + | ExpectedInOrOutOrRefKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression + | WrongLHSExpression | WrongRHSExpression | ExpectedAssignment e) { + e.printStackTrace(); + } + } + + private class SrcDstAttribute extends EdgeAttribute { + private Object src; + private Object dst; + + public SrcDstAttribute(Object src, Object dst) { + this.src = src; + this.dst = dst; + } + + public Object getSrouce() { + return src; + } + + public Object getDestination() { + return dst; + } + + public String toString() { + return ""; + } + } } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/ComboBoxCellEditor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/ComboBoxCellEditor.java deleted file mode 100644 index 334ba7b..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/ComboBoxCellEditor.java +++ /dev/null @@ -1,155 +0,0 @@ -package graphicalrefactor.views; - -import java.awt.Rectangle; -import java.util.EventObject; -import java.util.List; - -import javax.swing.BorderFactory; -import javax.swing.JComboBox; - -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.dataFlowModel.PushPullAttribute; -import models.dataFlowModel.PushPullValue; - -public class ComboBoxCellEditor 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; - - public ComboBoxCellEditor(mxGraphComponent graphComponent) { - this.graphComponent = graphComponent; - } - - @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)) 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/graphicalrefactor/views/GraphicalRefactor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactor.java index 8c93eba..ab035a5 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactor.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactor.java @@ -1,17 +1,26 @@ package graphicalrefactor.views; +import java.util.ArrayList; +import java.util.List; + import javax.swing.JFrame; +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.util.mxEvent; +import com.mxgraph.util.mxEventObject; +import com.mxgraph.util.mxEventSource.mxIEventListener; import com.mxgraph.view.mxGraph; import graphicalrefactor.editor.Editor; public class GraphicalRefactor extends JFrame { private static final long serialVersionUID = -8690140317781055614L; + public static final String title = "Visual Modeling Tool"; private Editor editor; private mxGraph graph; @@ -19,7 +28,7 @@ private mxGraphComponent graphComponent; public GraphicalRefactor() { - setTitle("Graphical Refactor"); + setTitle(title); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); graph = new mxGraph() { @@ -34,16 +43,37 @@ } }; - graphComponent = new mxGraphComponent(graph) { - protected mxICellEditor createCellEditor() { - return new ComboBoxCellEditor(this); - } - }; - getContentPane().add(graphComponent); - new mxRubberband(graphComponent); - editor = new Editor(graph); + graphComponent = new mxGraphComponent(graph) { + protected mxICellEditor createCellEditor() { + return new GraphicalRefactorCellEditor(this, 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); + menuBar = new GraphicalRefactorMenuBar(this); setJMenuBar(menuBar); setSize(870, 640); diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorCellEditor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorCellEditor.java new file mode 100644 index 0000000..688631e --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorCellEditor.java @@ -0,0 +1,251 @@ +package graphicalrefactor.views; + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Rectangle; +import java.util.EventObject; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.JComboBox; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +import com.mxgraph.model.mxCell; +import com.mxgraph.model.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 graphicalrefactor.editor.Editor; +import models.algebra.Expression; +import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.DataflowChannelGenerator; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.visualModel.FormulaChannelGenerator; +import parser.ExpectedRightBracket; +import parser.Parser; +import parser.Parser.TokenStream; + +public class GraphicalRefactorCellEditor 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 GraphicalRefactorCellEditor(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)) { + DataFlowModel model = editor.getModel(); + DataflowChannelGenerator ch = (DataflowChannelGenerator) model.getChannelGenerator((String) ((mxCell) cell).getValue()); + if (ch == null) { + ch = (DataflowChannelGenerator) model.getIOChannelGenerator((String) ((mxCell) cell).getValue()); + if(ch == null) { + //resource + return; + } + } + + if(ch instanceof FormulaChannelGenerator) { + + 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(((FormulaChannelGenerator) 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, // �I�[�i�[�E�B���h�E + panel, // ���b�Z�[�W + "Edit Formula Channel", // �E�B���h�E�^�C�g�� + JOptionPane.OK_CANCEL_OPTION, // �I�v�V�����i�{�^���̎�ށj + JOptionPane.QUESTION_MESSAGE); // ���b�Z�[�W�^�C�v�i�A�C�R���̎�ށj + if(r == JOptionPane.OK_OPTION) { + String formula = formulaText.getText(); + TokenStream stream = new TokenStream(); + stream.addLine(formula.split(Parser.EQUALS)[1]); + try { + Expression exp = Parser.parseTerm(stream, editor.getModel()); + ((FormulaChannelGenerator) ch).setFormula(formula); + ((FormulaChannelGenerator) ch).setFormulaTerm(exp); + } catch (ExpectedRightBracket 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/graphicalrefactor/views/GraphicalRefactorMenuBar.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java index e678111..1e29a75 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java @@ -3,16 +3,20 @@ import javax.swing.JMenu; import javax.swing.JMenuBar; -import com.mxgraph.view.mxGraph; - -import graphicalrefactor.actions.AbstractEditorAction; import graphicalrefactor.actions.CircleLayoutAction; +import graphicalrefactor.actions.DeleteAction; import graphicalrefactor.actions.DAGLayoutAction; import graphicalrefactor.actions.ExitAction; import graphicalrefactor.actions.OpenAction; import graphicalrefactor.actions.JavaPrototypeGenerateAction; import graphicalrefactor.actions.JerseyPrototypeGenerateAction; +import graphicalrefactor.actions.NewChannelAction; +import graphicalrefactor.actions.NewFormulaChannelAction; +import graphicalrefactor.actions.NewIOChannelAction; +import graphicalrefactor.actions.NewModelAction; +import graphicalrefactor.actions.NewResourceAction; import graphicalrefactor.actions.SaveAction; +import graphicalrefactor.actions.SaveAsAction; import graphicalrefactor.actions.TreeLayoutAction; import graphicalrefactor.actions.ZoomInAction; import graphicalrefactor.actions.ZoomOutAction; @@ -22,7 +26,11 @@ private static final long serialVersionUID = 4811536194182272888L; private GraphicalRefactor graphicalModelRefactor = null; - private OpenAction openAction = 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; @@ -31,14 +39,26 @@ public GraphicalRefactorMenuBar(GraphicalRefactor graphicalModelRefactor) { this.graphicalModelRefactor = graphicalModelRefactor; + JMenu newMenu = new JMenu("New"); + newMenu.add(new NewModelAction(graphicalModelRefactor)); + newMenu.add(newResourceAction = new NewResourceAction(graphicalModelRefactor.getEditor())); + newMenu.add(newChannelAction = new NewChannelAction(graphicalModelRefactor.getEditor())); + newMenu.add(newIOChannelAction = new NewIOChannelAction(graphicalModelRefactor.getEditor())); + newMenu.add(newFormulaChannelAction = new NewFormulaChannelAction(graphicalModelRefactor.getEditor())); JMenu menu = null; menu = add(new JMenu("File")); - menu.add(openAction = new OpenAction(graphicalModelRefactor.getEditor())); + menu.add(newMenu); + menu.add(new OpenAction(graphicalModelRefactor)); menu.addSeparator(); - menu.add(new SaveAction()); + menu.add(new SaveAction(graphicalModelRefactor)); + menu.add(new SaveAsAction(graphicalModelRefactor)); menu.addSeparator(); menu.add(new ExitAction()); + menu = add(new JMenu("Edit")); + menu.add(deleteAction = new DeleteAction(graphicalModelRefactor.getEditor())); + + menu = add(new JMenu("Layout")); menu.add(dagLayoutAction = new DAGLayoutAction(graphicalModelRefactor.getEditor())); menu.add(treeLayoutAction = new TreeLayoutAction(graphicalModelRefactor.getEditor())); @@ -58,8 +78,12 @@ } public void setEditor(Editor editor) { - openAction.setEditor(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/models/algebra/Variable.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Variable.java index 99ae839..fa0095b 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Variable.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Variable.java @@ -77,6 +77,11 @@ } public String toString() { + if (type == null) return name; + return name + ":" + type.getTypeName(); + } + + public String toImplementation(String[] sideEffects) { return name; } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ChannelGenerator.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ChannelGenerator.java index 1f1e01d..8a9bd1f 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ChannelGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ChannelGenerator.java @@ -8,6 +8,7 @@ protected Set groupSelectors = null; protected Set channelSelectors = null; protected Set channelMembers = null; + protected String sourceText = null; public ChannelGenerator(String channelName) { this.channelName = channelName; @@ -71,6 +72,15 @@ addSelector(selector); } } + + public void removeChannelMember(IdentifierTemplate id) { + for (ChannelMember cm: channelMembers) { + if (cm.getIdentifierTemplate() == id) { + channelMembers.remove(cm); + break; + } + } + } public Set getIdentifierTemplates() { Set identifierTemplates = new HashSet<>(); @@ -83,4 +93,15 @@ public String toString() { return channelName; } + + public void setSourceText(String sourceText) { + this.sourceText = sourceText; + } + + public String getSourceText() { + if (sourceText == null) { + return toString(); + } + return sourceText; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 878dbd8..c6fb2ea 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -242,7 +242,7 @@ return identifierTemplates.get(resourceName); } - public void addIdentifierTemplates(IdentifierTemplate identifierTemplate) { + public void addIdentifierTemplate(IdentifierTemplate identifierTemplate) { identifierTemplates.put(identifierTemplate.getResourceName(), identifierTemplate); } @@ -250,6 +250,17 @@ this.identifierTemplates = identifierTemplates; } + public void removeIdentifierTemplate(String resourceName) { + IdentifierTemplate id = identifierTemplates.get(resourceName); + identifierTemplates.remove(resourceName); + for (ChannelGenerator ch: channelGenerators.values()) { + ch.removeChannelMember(id); + } + for (ChannelGenerator ch: ioChannelGenerators.values()) { + ch.removeChannelMember(id); + } + } + public Collection getChannelGenerators() { return channelGenerators.values(); } @@ -274,10 +285,18 @@ } } + public void removeChannelGenerator(String channelName) { + channelGenerators.remove(channelName); + } + public Collection getIOChannelGenerators() { return ioChannelGenerators.values(); } + public ChannelGenerator getIOChannelGenerator(String channelName) { + return ioChannelGenerators.get(channelName); + } + public void setIOChannelGenerators(HashMap ioChannelGenerators) { this.ioChannelGenerators = ioChannelGenerators; for (ChannelGenerator g: ioChannelGenerators.values()) { @@ -294,6 +313,10 @@ } } + public void removeIOChannelGenerator(String ioChannelName) { + ioChannelGenerators.remove(ioChannelName); + } + public void addType(Type type) { types.put(type.getTypeName(), type); } @@ -368,4 +391,25 @@ } return out; } + + public String getSourceText() { + String out = ""; + String init = ""; + for (IdentifierTemplate identifierTemplate: identifierTemplates.values()) { + String initializer = identifierTemplate.getInitText(); + if (initializer != null) { + init += initializer; + } + } + if (init.length() > 0) { + out += "init {\n" + init + "}\n"; + } + for (ChannelGenerator channelGenerator: ioChannelGenerators.values()) { + out += channelGenerator.getSourceText(); + } + for (ChannelGenerator channelGenerator: channelGenerators.values()) { + out += channelGenerator.getSourceText(); + } + return out; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/IdentifierTemplate.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/IdentifierTemplate.java index d0e62ff..d91355c 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/IdentifierTemplate.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/IdentifierTemplate.java @@ -9,6 +9,7 @@ private Type resourceStateType = null; private int numParameters = 0; private Expression initialValue = null; + protected String initText = null; public IdentifierTemplate(String resourceName, int numParameters) { this.resourceName = resourceName; @@ -50,6 +51,14 @@ this.initialValue = initialValue; } + public void setInitText(String initText) { + this.initText = initText; + } + + public String getInitText() { + return initText; + } + public boolean equals(Object another) { if (!(another instanceof IdentifierTemplate)) return false; return resourceName.equals(((IdentifierTemplate) another).resourceName); diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataflowChannelGenerator.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataflowChannelGenerator.java index b4bdb35..62870b3 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataflowChannelGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataflowChannelGenerator.java @@ -78,6 +78,30 @@ addReferenceChannelMember(groupDependentResource); } + public void removeChannelMember(IdentifierTemplate id) { + for (ChannelMember cm: inputChannelMembers) { + if (cm.getIdentifierTemplate() == id) { + inputChannelMembers.remove(cm); + super.removeChannelMember(id); + return; + } + } + for (ChannelMember cm: outputChannelMembers) { + if (cm.getIdentifierTemplate() == id) { + outputChannelMembers.remove(cm); + super.removeChannelMember(id); + return; + } + } + for (ChannelMember cm: referenceChannelMembers) { + if (cm.getIdentifierTemplate() == id) { + referenceChannelMembers.remove(cm); + super.removeChannelMember(id); + return; + } + } + } + public Set getInputIdentifierTemplates() { Set inputIdentifierTemplates = new HashSet<>(); for (ChannelMember member: inputChannelMembers) { diff --git a/AlgebraicDataflowArchitectureModel/src/models/visualModel/FormulaChannelGenerator.java b/AlgebraicDataflowArchitectureModel/src/models/visualModel/FormulaChannelGenerator.java new file mode 100644 index 0000000..d5192a0 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/visualModel/FormulaChannelGenerator.java @@ -0,0 +1,161 @@ +package models.visualModel; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import models.algebra.Expression; +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.Variable; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataConstraintModel.StateTransition; +import models.dataFlowModel.DataflowChannelGenerator; + +public class FormulaChannelGenerator extends DataflowChannelGenerator { + private Symbol defaultOperator = null; + private String formula = null; + private Expression formulaRhs = null; + + public FormulaChannelGenerator(String channelName, Symbol defaultOperator) { + super(channelName); + this.defaultOperator = defaultOperator; + } + + public void addChannelMemberAsInput(ChannelMember channelMember) { +// StateTransition st = new StateTransition(); +// st.setCurStateExpression(new Variable(channelMember.getIdentifierTemplate().getResourceName() + "1")); +// st.setNextStateExpression(new Variable(channelMember.getIdentifierTemplate().getResourceName() + "2")); +// channelMember.setStateTransition(st); + super.addChannelMemberAsInput(channelMember); + if (formula != null && getInputChannelMembers().size() > 1) { + formula += " " + defaultOperator + " " + channelMember.getIdentifierTemplate().getResourceName(); + if (formulaRhs != null) { + if (formulaRhs instanceof Variable) { + Term newTerm = new Term(defaultOperator); + newTerm.addChild(formulaRhs); + newTerm.addChild(new Variable(channelMember.getIdentifierTemplate().getResourceName()), true); + formulaRhs = newTerm; + } else if (formulaRhs instanceof Term) { + Term newTerm = new Term(defaultOperator); + newTerm.addChild(formulaRhs); + newTerm.addChild(new Variable(channelMember.getIdentifierTemplate().getResourceName())); + formulaRhs = newTerm; + } + } + } else { + if (formula == null) formula = ""; + formula += channelMember.getIdentifierTemplate().getResourceName(); + formulaRhs = new Variable(channelMember.getIdentifierTemplate().getResourceName()); + } + if (formulaRhs != null) { + setFormulaTerm(formulaRhs); + } + } + + public void addChannelMemberAsOutput(ChannelMember channelMember) { +// StateTransition st = new StateTransition(); +// st.setCurStateExpression(new Variable(channelMember.getIdentifierTemplate().getResourceName() + "1")); +// channelMember.setStateTransition(st); + super.addChannelMemberAsOutput(channelMember); + if (getOutputChannelMembers().size() == 1) { + if (formula == null) formula = ""; + if (!formula.contains("==")) { + formula = channelMember.getIdentifierTemplate().getResourceName() + " == " + formula; + } + } + if (formulaRhs != null) { + setFormulaTerm(formulaRhs); + } + } + + public Symbol getDefaultOperator() { + return defaultOperator; + } + + public void setDefaultOperator(Symbol defaultOperator) { + this.defaultOperator = defaultOperator; + } + + public void setFormulaTerm(Expression rhs) { + formulaRhs = rhs; + Collection variables; + if (rhs instanceof Variable) { + variables = new ArrayList<>(); + variables.add((Variable) rhs); + } else if (rhs instanceof Term) { + variables = ((Term) rhs).getVariables().values(); + } else { + return; + } + Map curStates = new HashMap<>(); + Map nextStates = new HashMap<>(); + Map resToNextVar = new HashMap<>(); + for (ChannelMember cm: this.getInputChannelMembers()) { + IdentifierTemplate id = cm.getIdentifierTemplate(); + String resName = id.getResourceName(); + Variable curVar = new Variable(resName + "1"); + Variable nextVar = new Variable(resName + "2"); + curStates.put(id, curVar); + nextStates.put(id, nextVar); + for (Variable var: variables) { + if (var.getName().equals(resName)) { + resToNextVar.put(var, nextVar); + break; + } + } + } + Symbol update = new Symbol("update"); + update.setArity(resToNextVar.keySet().size()); + for (ChannelMember cm: getInputChannelMembers()) { + IdentifierTemplate id = cm.getIdentifierTemplate(); + StateTransition st = new StateTransition(); + st.setCurStateExpression(curStates.get(id)); + st.setNextStateExpression(nextStates.get(id)); + Term message = new Term(update); + for (Variable var: resToNextVar.values()) { + message.addChild(var); + } + st.setMessageExpression(message); + cm.setStateTransition(st); + } + + if (rhs instanceof Variable) { + rhs = resToNextVar.get((Variable) rhs); + } else if (rhs instanceof Term) { + formulaRhs = rhs; + for (Variable var: resToNextVar.keySet()) { + rhs = ((Term) rhs).substitute(var, resToNextVar.get(var)); + } + } + for (ChannelMember cm: getOutputChannelMembers()) { + IdentifierTemplate id = cm.getIdentifierTemplate(); + StateTransition st = new StateTransition(); + String resName = id.getResourceName(); + Variable curVar = new Variable(resName + "1"); + st.setCurStateExpression(curVar); + st.setNextStateExpression(rhs); + Term message = new Term(update); + for (Variable var: resToNextVar.values()) { + message.addChild(var); + } + st.setMessageExpression(message); + cm.setStateTransition(st); + } + } + + public Expression getFormulaTerm() { + return formulaRhs; + } + + public void setFormula(String formula) { + this.formula = formula; + } + + public String getFormula() { + return formula; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ExpectedFormulaChannel.java b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedFormulaChannel.java new file mode 100644 index 0000000..420655e --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedFormulaChannel.java @@ -0,0 +1,9 @@ +package parser; + +public class ExpectedFormulaChannel extends ParseException { + + public ExpectedFormulaChannel(int line) { + super(line); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ExpectedGeometry.java b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedGeometry.java new file mode 100644 index 0000000..b7927e0 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedGeometry.java @@ -0,0 +1,9 @@ +package parser; + +public class ExpectedGeometry extends ParseException { + + public ExpectedGeometry(int line) { + super(line); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ExpectedIoChannel.java b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedIoChannel.java new file mode 100644 index 0000000..d6885fd --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedIoChannel.java @@ -0,0 +1,9 @@ +package parser; + +public class ExpectedIoChannel extends ParseException { + + public ExpectedIoChannel(int line) { + super(line); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ExpectedModel.java b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedModel.java new file mode 100644 index 0000000..d3758e3 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedModel.java @@ -0,0 +1,9 @@ +package parser; + +public class ExpectedModel extends ParseException { + + public ExpectedModel(int line) { + super(line); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ExpectedNode.java b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedNode.java new file mode 100644 index 0000000..c82a553 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedNode.java @@ -0,0 +1,9 @@ +package parser; + +public class ExpectedNode extends ParseException { + + public ExpectedNode(int line) { + super(line); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ExpectedResource.java b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedResource.java new file mode 100644 index 0000000..b462e21 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/parser/ExpectedResource.java @@ -0,0 +1,9 @@ +package parser; + +public class ExpectedResource extends ParseException { + + public ExpectedResource(int line) { + super(line); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java index c41a255..77effe9 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java @@ -19,7 +19,7 @@ import models.dataFlowModel.DataflowChannelGenerator; public class Parser { - private BufferedReader reader; + protected BufferedReader reader; public static final String CHANNEL = "channel"; public static final String INIT = "init"; public static final String LEFT_CURLY_BRACKET = "{"; @@ -85,16 +85,20 @@ public static DataflowChannelGenerator parseChannel(TokenStream stream, DataFlowModel model) throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment { if (!stream.hasNext()) return null; - String channelOtInitKeyword = stream.next(); - if (!channelOtInitKeyword.equals(CHANNEL)) { - if (!channelOtInitKeyword.equals(INIT)) throw new ExpectedChannel(stream.getLine()); + if (stream.checkNext().equals(RIGHT_CURLY_BRACKET)) { + return null; + } + String channelOrInitKeyword = stream.next(); + if (!channelOrInitKeyword.equals(CHANNEL)) { + if (!channelOrInitKeyword.equals(INIT)) throw new ExpectedChannel(stream.getLine()); parseInit(stream, model); - channelOtInitKeyword = stream.next(); + channelOrInitKeyword = stream.next(); } if (!stream.hasNext()) throw new ExpectedChannelName(stream.getLine()); String channelName = stream.next(); if (channelName.equals(LEFT_CURLY_BRACKET)) throw new ExpectedChannelName(stream.getLine()); + int fromLine = stream.getLine(); DataflowChannelGenerator channel = new DataflowChannelGenerator(channelName); String leftBracket = stream.next(); if (!leftBracket.equals(LEFT_CURLY_BRACKET)) throw new ExpectedLeftCurlyBracket(stream.getLine()); @@ -120,6 +124,8 @@ throw new ExpectedInOrOutOrRefKeyword(stream.getLine()); } } + int toLine = stream.getLine(); + channel.setSourceText(stream.getSourceText(fromLine, toLine)); return channel; } @@ -128,10 +134,11 @@ if (!leftBracket.equals(LEFT_CURLY_BRACKET)) throw new ExpectedLeftCurlyBracket(stream.getLine()); String resourceName = null; while (stream.hasNext() && !(resourceName = stream.next()).equals(RIGHT_CURLY_BRACKET)) { + int fromLine = stream.getLine(); IdentifierTemplate identifier = model.getIdentifierTemplate(resourceName); if (identifier == null) { identifier = new IdentifierTemplate(resourceName, 0); - model.addIdentifierTemplates(identifier); + model.addIdentifierTemplate(identifier); } if (!stream.hasNext()) throw new ExpectedAssignment(stream.getLine()); @@ -141,12 +148,14 @@ String equals = stream.next(); if (!equals.equals(ASSIGNMENT)) throw new ExpectedAssignment(stream.getLine()); + int toLine = stream.getLine(); Expression rightTerm = null; if (!stream.hasNext()) throw new ExpectedRHSExpression(stream.getLine()); rightTerm = parseTerm(stream, model); if (rightTerm == null) throw new WrongRHSExpression(stream.getLine()); identifier.setInitialValue(rightTerm); + identifier.setInitText(stream.getSourceText(fromLine, toLine)); } } @@ -171,7 +180,7 @@ IdentifierTemplate identifier = model.getIdentifierTemplate(resourceName); if (identifier == null) { identifier = new IdentifierTemplate(resourceName, 0); - model.addIdentifierTemplates(identifier); + model.addIdentifierTemplate(identifier); } ChannelMember channelMember = new ChannelMember(identifier); StateTransition stateTransition = new StateTransition(); @@ -336,6 +345,7 @@ public static class TokenStream { private ArrayList> tokens = new ArrayList<>(); + private ArrayList lines = new ArrayList<>(); private int line = 0; private int n = 0; @@ -345,6 +355,7 @@ } public void addLine(String line) { + lines.add(line); line = line.trim(); tokens.add( splitBy( @@ -440,5 +451,13 @@ public int getLine() { return line; } + + public String getSourceText(int from, int to) { + String text = ""; + for (int l = from; l <= to; l++) { + text += lines.get(l) + "\n"; + } + return text; + } } } diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java b/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java new file mode 100644 index 0000000..0012395 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java @@ -0,0 +1,154 @@ +package parser; + +import java.io.BufferedReader; +import java.io.IOException; + +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGeometry; +import com.mxgraph.model.mxIGraphModel; +import com.mxgraph.view.mxCellState; +import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; + + +import models.dataFlowModel.DataFlowModel; + +public class ParserDTRAM extends Parser { + + + private static TokenStream stream; + + public static final String MODEL = "model"; + public static final String GEOMETRY = "geometry"; + public static final String NODE = "node"; + public static final String RESOURCE = "r"; + public static final String CHANNEL = "c"; + public static final String FORMULA_CHANNEL = "fc"; + public static final String IO_CHANNEL = "ioc"; + + + public ParserDTRAM(BufferedReader reader) { + super(reader); + } + + public DataFlowModel doParseModel() + throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, ExpectedModel, ExpectedGeometry { + stream = new TokenStream(); + try { + String line; + while ((line = reader.readLine()) != null) { + stream.addLine(line); + } + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + DataFlowModel model = parseModel(stream); + return model; + } + + public void doParseGeometry(mxGraph graph) + throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, ExpectedModel, ExpectedGeometry, ExpectedNode, ExpectedResource, ExpectedFormulaChannel, ExpectedIoChannel{ + + parseGeometry(stream, graph); + } + + public static DataFlowModel parseModel(TokenStream stream) + throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, ExpectedModel, ExpectedGeometry { + + if (!stream.hasNext()) { + return null; + } + + String modelKeyword = stream.next(); + if (!modelKeyword.equals(MODEL)) { + throw new ExpectedModel(stream.getLine()); + } + + if (!stream.hasNext()) { + throw new ExpectedModel(stream.getLine()); + } + + String leftBracket = stream.next(); + if (!leftBracket.equals(LEFT_CURLY_BRACKET)) { + throw new ExpectedLeftCurlyBracket(stream.getLine()); + } + + DataFlowModel model = Parser.parseDataFlowModel(stream); + + String rightBracket = stream.next(); + if(!rightBracket.equals(RIGHT_CURLY_BRACKET)) { + throw new ExpectedRightBracket(stream.getLine()); + } + return model; + } + + public static void parseGeometry(TokenStream stream, mxGraph graph) + throws ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedInOrOutOrRefKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment,ExpectedModel, ExpectedGeometry, ExpectedNode, ExpectedResource, ExpectedFormulaChannel, ExpectedIoChannel { + + + String geometry = stream.next(); + if (!geometry.equals(GEOMETRY)) { + throw new ExpectedGeometry(stream.getLine()); + } + + String leftBracket = stream.next(); + if(!leftBracket.equals(LEFT_CURLY_BRACKET)) { + throw new ExpectedLeftCurlyBracket(stream.getLine()); + } + + String node = stream.next(); + while (node.equals(NODE)) { + String rOrFcOrIocOrC = stream.next(); + if (!rOrFcOrIocOrC.equals(RESOURCE) &&!rOrFcOrIocOrC.equals(FORMULA_CHANNEL) &&!rOrFcOrIocOrC.equals(IO_CHANNEL) &&!rOrFcOrIocOrC.equals(CHANNEL)) { + throw new ExpectedNode(stream.getLine()); + } + + String name = stream.next(); + + String colon = stream.next(); + + String x = stream.next(); + int xC = Integer.parseInt(x); // C = Coordinate(���W) + + String comma1 = stream.next(); + + String y = stream.next(); + int yC = Integer.parseInt(y); + + String comma2 = stream.next(); + + String w = stream.next(); + int wC = Integer.parseInt(w); + + String comma3 = stream.next(); + + String h = stream.next(); + int hC = Integer.parseInt(h); + + Object root = graph.getDefaultParent(); + mxIGraphModel graphModel = graph.getModel(); + for (int i = 0; i < graph.getModel().getChildCount(root); i++) { + Object cell = graph.getModel().getChildAt(root, i); + if (graph.getModel().isVertex(cell)) { + mxGeometry geom = (mxGeometry) ((mxCell) cell).getGeometry().clone(); + mxGraphView view = graph.getView(); + mxCellState state = view.getState(cell); + if (name.equals(state.getLabel())){ + geom.setX(xC); + geom.setY(yC); + graphModel.setGeometry(cell, geom); + } + } + } + node = stream.next(); + } + if (!node.equals(RIGHT_CURLY_BRACKET)) { + throw new ExpectedRightBracket(stream.getLine()); + } + } +} + + + diff --git a/AlgebraicDataflowArchitectureModel/src/tests/FormulaChannelTest.java b/AlgebraicDataflowArchitectureModel/src/tests/FormulaChannelTest.java new file mode 100644 index 0000000..2cf2b37 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/tests/FormulaChannelTest.java @@ -0,0 +1,55 @@ +package tests; + +import org.junit.Test; + +import models.algebra.Symbol; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.IdentifierTemplate; +import models.visualModel.FormulaChannelGenerator; + +public class FormulaChannelTest { + + @Test + public void test() { + IdentifierTemplate id1 = new IdentifierTemplate("r1", 0); + IdentifierTemplate id2 = new IdentifierTemplate("r2", 0); + IdentifierTemplate id3 = new IdentifierTemplate("r3", 0); + + FormulaChannelGenerator ch1 = new FormulaChannelGenerator("ch1", DataConstraintModel.add); + System.out.println(ch1.getFormula()); + System.out.println(ch1.getFormulaTerm()); + System.out.println(ch1.getSourceText()); + ch1.addChannelMemberAsInput(new ChannelMember(id1)); + System.out.println(ch1.getFormula()); + System.out.println(ch1.getFormulaTerm()); + System.out.println(ch1.getSourceText()); + ch1.addChannelMemberAsInput(new ChannelMember(id2)); + System.out.println(ch1.getFormula()); + System.out.println(ch1.getFormulaTerm()); + System.out.println(ch1.getSourceText()); + ch1.addChannelMemberAsOutput(new ChannelMember(id3)); + System.out.println(ch1.getFormula()); + System.out.println(ch1.getFormulaTerm()); + System.out.println(ch1.getSourceText()); + + FormulaChannelGenerator ch2 = new FormulaChannelGenerator("ch2", DataConstraintModel.mul); + System.out.println(ch2.getFormula()); + System.out.println(ch2.getFormulaTerm()); + System.out.println(ch2.getSourceText()); + ch2.addChannelMemberAsOutput(new ChannelMember(id3)); + System.out.println(ch2.getFormula()); + System.out.println(ch2.getFormulaTerm()); + System.out.println(ch2.getSourceText()); + ch2.addChannelMemberAsInput(new ChannelMember(id1)); + System.out.println(ch2.getFormula()); + System.out.println(ch2.getFormulaTerm()); + System.out.println(ch2.getSourceText()); + ch2.addChannelMemberAsInput(new ChannelMember(id2)); + System.out.println(ch2.getFormula()); + System.out.println(ch2.getFormulaTerm()); + System.out.println(ch2.getSourceText()); + + } + +}