diff --git a/AlgebraicDataflowArchitectureModel/models/Clock.dtram b/AlgebraicDataflowArchitectureModel/models/Clock.dtram new file mode 100644 index 0000000..380ceca --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/models/Clock.dtram @@ -0,0 +1,27 @@ +model { +channel CIO1 { + out min(m, tick) == mod(m + 1, 60) +} +channel HourUpdate { + in hour(h, update(h')) == h' + out hour_hand(h_ang, update(h')) == h' / 6 * PI +} +channel MinUpdate { + in min(m, update(m')) == m' + out min_hand(m_ang, update(m')) == m' / 30 * PI +} +channel Clock { + in min(m, update(m')) == m' + out hour(h, update(m')) == if(eq(m', 0), mod(h + 1, 24), h) +} +} +geometry { + node c HourUpdate:520,340,30,30 + node c MinUpdate:520,100,30,30 + node c Clock:280,220,30,30 + node r min_hand:670,100,80,30 + node r min:250,100,80,30 + node r hour:270,340,80,30 + node r hour_hand:680,340,80,30 + node ioc CIO1:100,100,30,30 +} diff --git a/AlgebraicDataflowArchitectureModel/src/Main.java b/AlgebraicDataflowArchitectureModel/src/Main.java index 119bdd3..54fdaf8 100644 --- a/AlgebraicDataflowArchitectureModel/src/Main.java +++ b/AlgebraicDataflowArchitectureModel/src/Main.java @@ -1,11 +1,11 @@ -import graphicalrefactor.views.GraphicalRefactor; +import application.ApplicationWindow; public class Main { public static void main(String[] args) { - GraphicalRefactor frame = new GraphicalRefactor(); + ApplicationWindow frame = new ApplicationWindow(); frame.setVisible(true); } diff --git a/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java b/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java new file mode 100644 index 0000000..c837ba4 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java @@ -0,0 +1,103 @@ +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.ShowNavigationAction; +import application.actions.ShowSwitchLayerWindowAction; +import application.actions.TreeLayoutAction; +import application.actions.ZoomInAction; +import application.actions.ZoomOutAction; +import application.editor.Editor; + +public class ApplicationMenuBar extends JMenuBar { + private static final long serialVersionUID = 4811536194182272888L; + + private Editor editor = null; + + 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; + + public ApplicationMenuBar(ApplicationWindow applicationWindow) { + this.applicationWindow = applicationWindow; + this.editor = editor; + 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())); + + + 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("Generate")); + menu.add(javaPrototypeGenerateAction = new JavaPrototypeGenerateAction(applicationWindow.getEditor())); + menu.add(jerseyPrototypeGenerateAction = new JerseyPrototypeGenerateAction(applicationWindow.getEditor())); + + menu = add(new JMenu("Window")); + menu.add(new ShowNavigationAction(applicationWindow)); + menu.add(new ShowSwitchLayerWindowAction(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 new file mode 100644 index 0000000..4630830 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java @@ -0,0 +1,99 @@ +package application; + +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 application.editor.Editor; +import application.editor.stages.DataFlowCellEditor; +import application.views.NavigationWindow; +import application.views.controlFlowDelegation.ShowFlowWindow; + +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 NavigationWindow navigationWindow = null; + private ShowFlowWindow FlowLayerWindow = null; + + 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); + + getContentPane().add(graphComponent); + new mxRubberband(graphComponent); + graph.setAllowDanglingEdges(false); + graph.setCellsDisconnectable(true); + + menuBar = new ApplicationMenuBar(this); + setJMenuBar(menuBar); + setSize(870, 640); + + navigationWindow = new NavigationWindow(this, editor); + navigationWindow.setVisible(true); + + FlowLayerWindow = new ShowFlowWindow(this); + FlowLayerWindow.setVisible(false); + + editor.addStageChangeListener(navigationWindow); + editor.addStageChangeListener(FlowLayerWindow); + } + + 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); + } + + public void showSwitchLayerWindow() { + FlowLayerWindow.setVisible(true); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractEditorAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractEditorAction.java new file mode 100644 index 0000000..8b09b17 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractEditorAction.java @@ -0,0 +1,23 @@ +package application.actions; + +import javax.swing.AbstractAction; +import javax.swing.Icon; + +import com.mxgraph.view.mxGraph; + +import application.editor.Editor; + +public abstract class AbstractEditorAction extends AbstractAction { + + protected Editor editor; + + public AbstractEditorAction(String name, Editor editor) { + super(name); + this.editor = editor; + } + + public void setEditor(Editor editor) { + this.editor = editor; + } + +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractSystemAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractSystemAction.java new file mode 100644 index 0000000..f734ae0 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractSystemAction.java @@ -0,0 +1,23 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +import application.ApplicationWindow; +import application.editor.Editor; + +public abstract class AbstractSystemAction extends AbstractAction { + + protected ApplicationWindow frame; + + public AbstractSystemAction(String name, ApplicationWindow frame) { + super(name); + this.frame = frame; + } + + public void setFrame(ApplicationWindow frame) { + this.frame = frame; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractViewerAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractViewerAction.java new file mode 100644 index 0000000..422c537 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/AbstractViewerAction.java @@ -0,0 +1,17 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +import com.mxgraph.swing.mxGraphComponent; + +public abstract class AbstractViewerAction extends AbstractAction { + + protected mxGraphComponent graphComponent = null; + + public AbstractViewerAction(String name, mxGraphComponent graphComponent) { + super(name); + this.graphComponent = graphComponent; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/CircleLayoutAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/CircleLayoutAction.java new file mode 100644 index 0000000..ba643bc --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/CircleLayoutAction.java @@ -0,0 +1,18 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.editor.Editor; + +public class CircleLayoutAction extends AbstractEditorAction { + + public CircleLayoutAction(Editor editor) { + super("Circle Layout", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + editor.setCircleLayout(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/DAGLayoutAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/DAGLayoutAction.java new file mode 100644 index 0000000..8dcc54f --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/DAGLayoutAction.java @@ -0,0 +1,18 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.editor.Editor; + +public class DAGLayoutAction extends AbstractEditorAction { + + public DAGLayoutAction(Editor editor) { + super("DAG Layout", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + editor.setDAGLayout(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/DeleteAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/DeleteAction.java new file mode 100644 index 0000000..23225f1 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/DeleteAction.java @@ -0,0 +1,23 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.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/application/actions/ExitAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ExitAction.java new file mode 100644 index 0000000..4069533 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ExitAction.java @@ -0,0 +1,22 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +public class ExitAction extends AbstractAction { + /** + * + */ + private static final long serialVersionUID = -8733766417378036850L; + + public ExitAction() { + super("Exit"); + } + + @Override + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java new file mode 100644 index 0000000..92b552b --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/JavaPrototypeGenerateAction.java @@ -0,0 +1,101 @@ +package application.actions; + +import java.awt.event.ActionEvent; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import javax.swing.JFileChooser; + +import algorithms.*; +import application.editor.Editor; +import code.ast.*; +import generators.CodeGenerator; +import generators.DataTransferMethodAnalyzer; +import generators.JavaCodeGenerator; +import generators.JavaMethodBodyGenerator; +import generators.JavaSpecific; +import models.controlFlowModel.ControlFlowGraph; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.ModelExtension; +import models.dataFlowModel.DataFlowGraph; + +public class JavaPrototypeGenerateAction extends AbstractEditorAction { + /** + * + */ + private static final long serialVersionUID = -3694103632055735068L; + + private String lastDir = null; + + public JavaPrototypeGenerateAction(Editor editor) { + super("Generate Plain Java Prototype", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + DataFlowGraph dataFlowgraph = editor.getDataFlowGraph(); + if (dataFlowgraph == null) { + editor.changeStage(Editor.STAGE_PUSH_PULL_SELECTION); + dataFlowgraph = editor.getDataFlowGraph(); + } + if (dataFlowgraph != null) { + DataTransferModel model = editor.getModel(); + ModelExtension.extendModel(model); + TypeInference.infer(model); + DataTransferMethodAnalyzer.decideToStoreResourceStates(dataFlowgraph); + String fileName = editor.getCurFileName(); + if (fileName == null) fileName = "Main"; + String mainTypeName = fileName.split("\\.")[0]; + boolean exist = false; + for (IdentifierTemplate id: model.getIdentifierTemplates()) { + String resourceName = id.getResourceName().substring(0, 1).toUpperCase() + id.getResourceName().substring(1); + if (mainTypeName.equals(resourceName)) { + exist = true; + } + } + if (!exist) { + CodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. + } else { + CodeGenerator.resetMainTypeName(); // use the default main type's name. + } + ControlFlowGraph controlFlowGraph = editor.getControlFlowGraph(); + if (controlFlowGraph != null) { + editor.setCodes(CodeGenerator.doGenerate(model, controlFlowGraph, new JavaSpecific())); + } else { + editor.setCodes(CodeGenerator.doGenerate(model, dataFlowgraph, new JavaSpecific())); + } + ModelExtension.recoverModel(model); + for (CompilationUnit file : editor.getCodes()) { + System.out.println(file); + } + + String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); + JFileChooser fc = new JFileChooser(wd); + fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + int rc = fc.showSaveDialog(null); + if (rc == JFileChooser.APPROVE_OPTION) { + lastDir = fc.getSelectedFile().getPath(); + for (CompilationUnit cu : editor.getCodes()) { + save(fc.getSelectedFile(), cu); + } + } + } + } + + private void save(File dir, CompilationUnit cu) { + File javaFile = new File(dir.getPath(), cu.getFileName()); + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(javaFile)); + writer.write(cu.toString()); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/JerseyPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/JerseyPrototypeGenerateAction.java new file mode 100644 index 0000000..25986ec --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/JerseyPrototypeGenerateAction.java @@ -0,0 +1,94 @@ +package application.actions; + +import java.awt.event.ActionEvent; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import javax.swing.JFileChooser; + +import algorithms.*; +import application.editor.Editor; +import code.ast.*; +import generators.DataTransferMethodAnalyzer; +import generators.JerseyCodeGenerator; +import generators.JerseyMethodBodyGenerator; +import models.algebra.Type; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.ModelExtension; +import models.dataFlowModel.DataFlowGraph; + +public class JerseyPrototypeGenerateAction extends AbstractEditorAction { + /** + * + */ + private static final long serialVersionUID = 1117065654665887436L; + + private String lastDir = null; + + public JerseyPrototypeGenerateAction(Editor editor) { + super("Generate JAX-RS Prototype", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + DataFlowGraph graph = editor.getDataFlowGraph(); + if (graph == null) { + editor.changeStage(Editor.STAGE_PUSH_PULL_SELECTION); + graph = editor.getDataFlowGraph(); + } + if (graph != null) { + DataTransferModel model = editor.getModel(); + ModelExtension.extendModel(model); + TypeInference.infer(model); + DataTransferMethodAnalyzer.decideToStoreResourceStates(graph); + String fileName = editor.getCurFileName(); + if (fileName == null) fileName = "Main"; + String mainTypeName = fileName.split("\\.")[0]; + boolean exist = false; + for (IdentifierTemplate id: model.getIdentifierTemplates()) { + String resourceName = id.getResourceName().substring(0, 1).toUpperCase() + id.getResourceName().substring(1); + if (mainTypeName.equals(resourceName)) { + exist = true; + } + } + if (!exist) { + JerseyCodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. + } else { + JerseyCodeGenerator.resetMainTypeName(); // use the default main type's name. + } + editor.setCodes(JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model))); + ModelExtension.recoverModel(model); + for (CompilationUnit file : editor.getCodes()) { + System.out.println(file); + } + + String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); + JFileChooser fc = new JFileChooser(wd); + fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + int rc = fc.showSaveDialog(null); + if (rc == JFileChooser.APPROVE_OPTION) { + lastDir = fc.getSelectedFile().getPath(); + for (CompilationUnit cu : editor.getCodes()) { + save(fc.getSelectedFile(), cu); + } + } + } + } + + private void save(File dir, CompilationUnit cu) { + File javaFile = new File(dir.getPath(), cu.getFileName()); + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(javaFile)); + writer.write(cu.toString()); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/NewChannelAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/NewChannelAction.java new file mode 100644 index 0000000..e8148f5 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/NewChannelAction.java @@ -0,0 +1,28 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JOptionPane; + +import application.editor.Editor; +import models.dataFlowModel.DataTransferChannelGenerator; + +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 DataTransferChannelGenerator(channelName)); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/NewFormulaChannelAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/NewFormulaChannelAction.java new file mode 100644 index 0000000..d26d8a8 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/NewFormulaChannelAction.java @@ -0,0 +1,62 @@ +package application.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 application.ApplicationWindow; +import application.editor.Editor; +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/application/actions/NewIOChannelAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/NewIOChannelAction.java new file mode 100644 index 0000000..8d819d8 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/NewIOChannelAction.java @@ -0,0 +1,28 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JOptionPane; + +import application.editor.Editor; +import models.dataFlowModel.DataTransferChannelGenerator; + +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 DataTransferChannelGenerator(channelName)); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/NewModelAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/NewModelAction.java new file mode 100644 index 0000000..517f525 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/NewModelAction.java @@ -0,0 +1,24 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.ApplicationWindow; +import application.editor.Editor; + +public class NewModelAction extends AbstractSystemAction { + /** + * + */ + private static final long serialVersionUID = 8484493203589724589L; + + public NewModelAction(ApplicationWindow frame) { + super("Model", frame); + } + + @Override + public void actionPerformed(ActionEvent e) { + frame.getEditor().clear(); + frame.setTitle(frame.title); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/NewResourceAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/NewResourceAction.java new file mode 100644 index 0000000..5c230f7 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/NewResourceAction.java @@ -0,0 +1,28 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.JOptionPane; + +import application.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/application/actions/OpenAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/OpenAction.java new file mode 100644 index 0000000..d01c518 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/OpenAction.java @@ -0,0 +1,62 @@ +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; + +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"); + + 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, "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/application/actions/SaveAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/SaveAction.java new file mode 100644 index 0000000..0b41331 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/SaveAction.java @@ -0,0 +1,26 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.ApplicationWindow; +import application.editor.Editor; + +public class SaveAction extends AbstractSystemAction { + /** + * + */ + private static final long serialVersionUID = 5660460585305281982L; + + public SaveAction(ApplicationWindow frame) { + super("Save", frame); + } + + @Override + public void actionPerformed(ActionEvent e) { + Editor editor = frame.getEditor(); + if (editor != null && editor.getCurFileName() != null) { + editor.save(); + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/SaveAsAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/SaveAsAction.java new file mode 100644 index 0000000..9542cdb --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/SaveAsAction.java @@ -0,0 +1,77 @@ +package application.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 application.ApplicationWindow; +import application.editor.Editor; + +public class SaveAsAction extends AbstractSystemAction { + /** + * + */ + private static final long serialVersionUID = -2599502783032684084L; + + private String lastDir = null; + + public SaveAsAction(ApplicationWindow 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"); + + // choose a file extension from a dialog. + if (rc == JFileChooser.APPROVE_OPTION) { + + // if extension filter is filled, then attaching extension by choosing filter. + // but if it's not filled, then using default extension name. + String extension = ""; + if(fc.getFileFilter() instanceof FileNameExtensionFilter) { + FileNameExtensionFilter selectedFilter = (FileNameExtensionFilter)fc.getFileFilter(); + extension = "." + selectedFilter.getExtensions()[0].toString(); + } + + lastDir = fc.getSelectedFile().getParent(); + + String fileName = fc.getSelectedFile().getAbsolutePath() + extension; + editor.setCurFilePath(fileName); + + // overwriting file + editor.save(); + frame.setTitle(ApplicationWindow.title + " - " + fc.getSelectedFile().getAbsolutePath()); + } + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java new file mode 100644 index 0000000..ac58b48 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java @@ -0,0 +1,18 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.ApplicationWindow; + +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/actions/ShowSwitchLayerWindowAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowSwitchLayerWindowAction.java new file mode 100644 index 0000000..b137463 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowSwitchLayerWindowAction.java @@ -0,0 +1,16 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.ApplicationWindow; + +public class ShowSwitchLayerWindowAction extends AbstractSystemAction { + public ShowSwitchLayerWindowAction(ApplicationWindow frame) { + super("Show Flow", frame); + } + + @Override + public void actionPerformed(ActionEvent e) { + frame.showSwitchLayerWindow(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/TreeLayoutAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/TreeLayoutAction.java new file mode 100644 index 0000000..c2324c8 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/TreeLayoutAction.java @@ -0,0 +1,18 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.editor.Editor; + +public class TreeLayoutAction extends AbstractEditorAction { + + public TreeLayoutAction(Editor editor) { + super("Tree Layout", editor); + } + + @Override + public void actionPerformed(ActionEvent e) { + editor.setTreeLayout(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/ZoomInAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ZoomInAction.java new file mode 100644 index 0000000..d3b2c85 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ZoomInAction.java @@ -0,0 +1,28 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; + +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxResources; + +import application.editor.Editor; + +public class ZoomInAction extends AbstractViewerAction { + /** + * + */ + private static final long serialVersionUID = 6758532166946195926L; + + public ZoomInAction(mxGraphComponent graphComponent) { + super("Zoom In", graphComponent); + } + + @Override + public void actionPerformed(ActionEvent e) { + graphComponent.zoomIn(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/ZoomOutAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ZoomOutAction.java new file mode 100644 index 0000000..032e8b2 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ZoomOutAction.java @@ -0,0 +1,26 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +import com.mxgraph.swing.mxGraphComponent; + +import application.editor.Editor; + +public class ZoomOutAction extends AbstractViewerAction { + /** + * + */ + private static final long serialVersionUID = 8657530769383486605L; + + public ZoomOutAction(mxGraphComponent graphComponent) { + super("Zoom Out", graphComponent); + } + + @Override + public void actionPerformed(ActionEvent e) { + graphComponent.zoomOut(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java new file mode 100644 index 0000000..9aa7f96 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java @@ -0,0 +1,506 @@ +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.ArrayList; +import java.util.List; + +import com.mxgraph.layout.mxCircleLayout; +import com.mxgraph.layout.mxCompactTreeLayout; +import com.mxgraph.model.mxCell; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxEvent; +import com.mxgraph.util.mxEventSource.mxIEventListener; +import com.mxgraph.view.mxCellState; +import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; + +import application.editor.stages.ControlFlowDelegationStage; +import application.editor.stages.DataFlowModelingStage; +import application.editor.stages.PushPullSelectionStage; +import application.layouts.*; +import code.ast.CompilationUnit; +import models.EdgeAttribute; +import models.controlFlowModel.ControlFlowGraph; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.DataTransferChannelGenerator; +import models.dataFlowModel.DataFlowGraph; +import models.visualModel.FormulaChannelGenerator; +import parser.Parser; +import parser.exceptions.ExpectedAssignment; +import parser.exceptions.ExpectedChannel; +import parser.exceptions.ExpectedChannelName; +import parser.exceptions.ExpectedEquals; +import parser.exceptions.ExpectedFormulaChannel; +import parser.exceptions.ExpectedGeometry; +import parser.exceptions.ExpectedInOrOutOrRefKeyword; +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.WrongLHSExpression; +import parser.exceptions.WrongRHSExpression; +import parser.ParserDTRAM; + +public class Editor { + public DataTransferModel model = null; + public mxGraph graph = null; + private mxGraphComponent graphComponent = null; + private mxIEventListener curChangeEventListener = null; + + protected Stage curStage = null; + protected List stageQueue = null; + private List stageChangeListeners = null; + + protected String curFileName = null; + protected String curFilePath = null; + protected ArrayList codes = null; + + public static DataFlowModelingStage STAGE_DATA_FLOW_MODELING = null; + public static PushPullSelectionStage STAGE_PUSH_PULL_SELECTION = null; + public static ControlFlowDelegationStage STAGE_CONTROL_FLOW_DELEGATION = null; + + public Editor(mxGraphComponent graphComponent) { + this.graphComponent = graphComponent; + this.graph = graphComponent.getGraph(); + + STAGE_DATA_FLOW_MODELING = new DataFlowModelingStage(graph); + STAGE_PUSH_PULL_SELECTION = new PushPullSelectionStage(graph); + STAGE_CONTROL_FLOW_DELEGATION = new ControlFlowDelegationStage(graph); + + graphComponent.setCellEditor(STAGE_DATA_FLOW_MODELING.createCellEditor(graphComponent)); + + stageQueue = new ArrayList<>(); + stageQueue.add(STAGE_DATA_FLOW_MODELING); + stageQueue.add(STAGE_PUSH_PULL_SELECTION); + stageQueue.add(STAGE_CONTROL_FLOW_DELEGATION); + curStage = STAGE_DATA_FLOW_MODELING; + + stageChangeListeners = new ArrayList<>(); + } + + public mxGraph getGraph() { + return graph; + } + + public mxGraphComponent getGraphComponent() { + return this.graphComponent; + } + + public DataTransferModel getModel() { + model = curStage.getModel(); + return model; + } + + public Stage getCurStage() { + return curStage; + } + + public boolean canChange(Stage nextStage) { + return nextStage.canChangeFrom(curStage); + } + + public boolean nextStage() { + int curStageNo = stageQueue.indexOf(curStage); + if (curStageNo + 1 >= stageQueue.size()) return false; + return changeStage(stageQueue.get(curStageNo + 1)); + } + + public boolean changeStage(Stage nextStage) { + if (!nextStage.canChangeFrom(curStage)) return false; + nextStage.init(curStage); + graphComponent.setCellEditor(nextStage.createCellEditor(graphComponent)); + if (curChangeEventListener != null) { + graph.getModel().removeListener(curChangeEventListener); + } + curChangeEventListener = nextStage.createChangeEventListener(this); + if (curChangeEventListener != null) { + graph.getModel().addListener(mxEvent.CHANGE, curChangeEventListener); + } + curStage = nextStage; + notifyStageChangeListeners(); + return true; + } + + public void addStageChangeListener(IStageChangeListener stageChangeListener) { + stageChangeListeners.add(stageChangeListener); + } + + private void notifyStageChangeListeners() { + for (IStageChangeListener l: stageChangeListeners) { + l.stageChanged(curStage); + } + } + + public DataFlowGraph getDataFlowGraph() { + if (curStage instanceof PushPullSelectionStage) { + return ((PushPullSelectionStage) curStage).getDataFlowGraph(); + } else if (curStage instanceof ControlFlowDelegationStage) { + return ((ControlFlowDelegationStage) curStage).getControlFlowGraph().getDataFlowGraph(); + } + return null; + } + + public ControlFlowGraph getControlFlowGraph() { + if (curStage instanceof ControlFlowDelegationStage) { + return ((ControlFlowDelegationStage) curStage).getControlFlowGraph(); + } + return null; + } + + public ArrayList getCodes() { + return codes; + } + + public void setCodes(ArrayList codes) { + this.codes = codes; + } + + public String getCurFileName() { + return curFileName; + } + + public String getCurFilePath() { + return curFilePath; + } + + public void setCurFilePath(String curFilePath) { + this.curFilePath = curFilePath; + this.curFileName = new File(curFilePath).getName(); + } + + public void clear() { + // Force to change to the data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return; + + model = null; + ((DataFlowModelingStage) curStage).clear(); + + curFilePath = null; + curFileName = null; + codes = null; + } + + /** + * 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) { + // Force to change to the data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return null; + + try { + String extension =""; + if(file != null && file.exists()) { + // get file's name + String name = file.getName(); + + // get file's extension + extension = name.substring(name.lastIndexOf(".")); + } + if(extension.contains(".model")) { + openModel(file); + } else { + // Parse the .dtram file. + ParserDTRAM parserDTRAM = new ParserDTRAM(new BufferedReader(new FileReader(file))); + try { + model = parserDTRAM.doParseModel(); + if (curStage instanceof DataFlowModelingStage) { + // Update the mxGraph. + ((DataFlowModelingStage) curStage).setModel(model); + } + // Restore the geometry. + parserDTRAM.doParseGeometry(graph); + + // Change to the push/pull selection stage, analyze the data transfer model and construct a data-flow graph. + changeStage(STAGE_PUSH_PULL_SELECTION); + + curFilePath = file.getAbsolutePath(); + curFileName = file.getName(); + 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 DataTransferModel openModel(File file) { + // Force to change to data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return null; + + try { + // Parse the .model file. + Parser parser = new Parser(new BufferedReader(new FileReader(file))); + try { + model = parser.doParse(); + if (curStage instanceof DataFlowModelingStage) { + // Update the mxGraph. + ((DataFlowModelingStage) curStage).setModel(model); + } + // Set DAG layout. + setDAGLayout(); + + // Change to the push/pull selection stage, analyze the data transfer model and construct a data-flow graph. + changeStage(STAGE_PUSH_PULL_SELECTION); + + curFilePath = file.getAbsolutePath(); + curFileName = file.getName(); + return model; + } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefKeyword + | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression + | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment e) { + e.printStackTrace(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /************************************************************* + * [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(); + + // 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(); + } + } + } + + 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(); + } + } + } + + /**-------------------------------------------------------------------------------- + * 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"; + + fileString += "geometry {\n"; + + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell nodeLayer = (mxCell) root.getChildAt(Stage.NODE_LAYER); + mxCell dataFlowLayer = (mxCell) root.getChildAt(Stage.DATA_FLOW_LAYER); + for (int i = 0; i < graph.getModel().getChildCount(nodeLayer); i++) { + Object cell = graph.getModel().getChildAt(nodeLayer, 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 (IdentifierTemplate res: model.getIdentifierTemplates()){ + if(res instanceof IdentifierTemplate && state.getLabel().equals(res.getResourceName())) + fileString += "\tnode r " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"; + } + + for (ChannelGenerator ioC: model.getIOChannelGenerators()) { + if(ioC instanceof ChannelGenerator && state.getLabel().equals(ioC.getChannelName())) { + fileString += "\tnode ioc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"; + } + } + } + } + for (int i = 0; i < graph.getModel().getChildCount(dataFlowLayer); i++) { + Object cell = graph.getModel().getChildAt(dataFlowLayer, 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())) { + fileString += "\tnode fc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; + } else if(ch instanceof ChannelGenerator && state.getLabel().equals(ch.getChannelName())) { + fileString +="\tnode c " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; + } + } + } + } + fileString += "}\n"; + + return fileString; + } + + public void setDAGLayout() { + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell dataFlowLayer = (mxCell) root.getChildAt(Stage.DATA_FLOW_LAYER); + graph.getModel().beginUpdate(); + try { + DAGLayout ctl = new DAGLayout(graph); + ctl.execute(dataFlowLayer); +// for(int i = 0; i < root.getChildCount(); i++) { +// ctl.execute(root.getChildAt(i)); +// } + } finally { + graph.getModel().endUpdate(); + } + } + + public void setTreeLayout() { + mxCell root = (mxCell) graph.getDefaultParent(); + 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(); + } + } + + public void setCircleLayout() { + mxCell root = (mxCell) graph.getDefaultParent(); + 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 void addIdentifierTemplate(IdentifierTemplate res) { + // Force to change to the data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return; + + ((DataFlowModelingStage) curStage).addIdentifierTemplate(res); + model = ((DataFlowModelingStage) curStage).getModel(); + } + + public void addChannelGenerator(DataTransferChannelGenerator channelGen) { + // Force to change to the data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return; + + ((DataFlowModelingStage) curStage).addChannelGenerator(channelGen); + model = ((DataFlowModelingStage) curStage).getModel(); + + } + + public void addIOChannelGenerator(DataTransferChannelGenerator ioChannelGen) { + // Force to change to the data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return; + + ((DataFlowModelingStage) curStage).addIOChannelGenerator(ioChannelGen); + model = ((DataFlowModelingStage) curStage).getModel(); + } + + public void addFormulaChannelGenerator(FormulaChannelGenerator formulaChannelGen) { + // Force to change to the data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return; + + ((DataFlowModelingStage) curStage).addFormulaChannelGenerator(formulaChannelGen); + model = ((DataFlowModelingStage) curStage).getModel(); + } + + public boolean connectEdge(mxCell edge, mxCell src, mxCell dst) { + // Force to change to the data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return false; + + boolean isConnected = ((DataFlowModelingStage) curStage).connectEdge(edge, src, dst); + + return isConnected; + } + + public void delete() { + // Force to change to the data-flow modeling stage. + boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); + if (!stageChanged) return; + + ((DataFlowModelingStage) curStage).delete(); + } + + public static 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/application/editor/FlowCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/FlowCellEditor.java new file mode 100644 index 0000000..24f98e3 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/FlowCellEditor.java @@ -0,0 +1,45 @@ +package application.editor; + +import java.util.EventObject; + +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.swing.view.mxICellEditor; + +abstract public class FlowCellEditor implements mxICellEditor { + + protected Stage stage = null; + protected mxGraphComponent graphComponent = null; + + protected Object editingCell = null; + + /************************************************************* + * [ *constructor] + /************************************************************* + * + * @param stage + * @param graphComponent + */ + protected FlowCellEditor(Stage stage, mxGraphComponent graphComponent) { + this.stage = stage; + this.graphComponent = graphComponent; + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + public Object getEditingCell() { + return this.editingCell; + } + + /************************************************************* + * + */ + abstract public void startEditing(Object arg0, EventObject arg1); + + /************************************************************* + * + */ + abstract public void stopEditing(boolean cancel); +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java b/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java new file mode 100644 index 0000000..a345fe2 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java @@ -0,0 +1,5 @@ +package application.editor; + +public interface IStageChangeListener { + public void stageChanged(Stage newStage); +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/InEdgeAttribute.java b/AlgebraicDataflowArchitectureModel/src/application/editor/InEdgeAttribute.java new file mode 100644 index 0000000..5956f6c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/InEdgeAttribute.java @@ -0,0 +1,19 @@ +package application.editor; + +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResourceNode; + +public class InEdgeAttribute extends PushPullAttribute { + private ResourceNode srcRes; + + public InEdgeAttribute(PushPullAttribute attr, ResourceNode srcRes) { + super(); + super.setOptions(attr.getOptions()); + this.srcRes = srcRes; + } + + public ResourceNode getSrcResource() { + return srcRes; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/OutEdgeAttribute.java b/AlgebraicDataflowArchitectureModel/src/application/editor/OutEdgeAttribute.java new file mode 100644 index 0000000..3d5c286 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/OutEdgeAttribute.java @@ -0,0 +1,18 @@ +package application.editor; + +import application.editor.Editor.SrcDstAttribute; +import models.EdgeAttribute; +import models.dataFlowModel.ResourceNode; + +public class OutEdgeAttribute extends SrcDstAttribute { + private ResourceNode dstRes; + + public OutEdgeAttribute(SrcDstAttribute attr, ResourceNode dstRes) { + super(attr.getSrouce(), attr.getDestination()); + this.dstRes = dstRes; + } + + public ResourceNode getDstResource() { + return dstRes; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java new file mode 100644 index 0000000..c3873bc --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Stage.java @@ -0,0 +1,73 @@ +package application.editor; + +import com.mxgraph.model.mxCell; +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; + +abstract public class Stage { + protected DataTransferModel model = null; + protected mxGraph graph = null; + public static final int NODE_LAYER = 0; + public static final int DATA_FLOW_LAYER = 0; + public static final int PUSH_FLOW_LAYER = 1; + public static final int PULL_FLOW_LAYER = 2; + + /************************************************************* + * [ *constructor] + /************************************************************* + * + * @param graph + */ + public Stage(mxGraph graph) { + this.graph = graph; + } + + /************************************************************* + * + * @return model + */ + public DataTransferModel getModel() { + return model; + } + + abstract public boolean canChangeFrom(Stage prevStage); + abstract public void init(Stage prevStage); + abstract public mxICellEditor createCellEditor(mxGraphComponent graphComponent); + abstract public mxIEventListener createChangeEventListener(Editor editor); + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + public void setEnabledForLayer(final int layerNo, final boolean isEnable) { + mxCell rootCell = (mxCell) graph.getDefaultParent(); + if(rootCell== null) return; + if(rootCell.getChildCount() <= 0) return; + + graph.getModel().setVisible(rootCell.getChildAt(layerNo), isEnable); + graph.refresh(); + } + + /************************************************************* + * Showing layers are specified number of layers. + * @param you want to show numbers of layers. + */ + public void showOnlyLayer(final int... argsOfLayers) { + mxCell rootCell = (mxCell) graph.getDefaultParent(); + if(rootCell== null) return; + if(rootCell.getChildCount() <= 0) return; + + for(int i = 0; i < rootCell.getChildCount(); i++) { + graph.getModel().setVisible(rootCell.getChildAt(i), false); + } + + for(int layerNo : argsOfLayers) { + graph.getModel().setVisible(rootCell.getChildAt(layerNo), true); + } + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java new file mode 100644 index 0000000..dcd8786 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationCellEditor.java @@ -0,0 +1,245 @@ +package application.editor.stages; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.EventObject; + +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +import com.mxgraph.model.mxCell; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.swing.mxGraphComponent.mxGraphControl; +import com.mxgraph.view.mxCellState; + +import application.editor.FlowCellEditor; +import application.editor.Stage; +import models.controlFlowModel.CallEdgeAttribute; +import models.controlFlowModel.ObjectNodeAttribute; +import models.dataFlowModel.PushPullValue; + +/************************************************************* + * + */ +public class ControlFlowDelegationCellEditor extends FlowCellEditor { + private ControlFlowDelegationStageStatus curState = null; + private mxCell targetEdgeCell = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + * @param graph + */ + public ControlFlowDelegationCellEditor(ControlFlowDelegationStage stage, mxGraphComponent graphComponent) { + super(stage, graphComponent); + curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; + + // If required handlers have already resistered, + // then remove them before each add. + mxGraphControl graphControl = graphComponent.getGraphControl(); + for(MouseListener listener : graphControl.getMouseListeners()) { + if(listener instanceof InsertObjectNodeAction) + graphControl.removeMouseListener(listener); + } + + // Adding handlers + graphControl.addMouseListener(new InsertObjectNodeAction()); + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + @Override + public void startEditing(Object cellObj, EventObject eventObj) { + if( editingCell != null) stopEditing(true); + + System.out.println("state:" + curState.name()); + + switch(curState) { + case SELECTING_AN_EDGE: + + // Branching based on the edge click event. + // | double clicked > Showing delegatable nodes. + // | right clicked > Inserting a stateless node. + // (added listener -> InsertObjectNodeAction) + if( graphComponent.getGraph().getModel().isEdge(cellObj)) { + // cache a target edge of cell; + targetEdgeCell = (mxCell)cellObj; + + showDelegatableNodesBySelectedEdge(cellObj); + curState = ControlFlowDelegationStageStatus.SHOWING_DELEGATABLE_NODES; + + // If the label of the edge is clicked, + // then inputing a call order you want. + mxCellState state = graphComponent.getGraph().getView().getState(cellObj); + if(state == null || state.getLabel() == null || state.getLabel().equals("")) return; + + changeCallOrderOfCallEdge(cellObj); + } + break; + + case SHOWING_DELEGATABLE_NODES: + if( graphComponent.getGraph().getModel().isVertex(cellObj) ) { + // invocating delegation method + if(!(cellObj instanceof mxCell)) throw new ClassCastException(); + + ((ControlFlowDelegationStage)stage) + .showDelegatedGraph(graphComponent.getGraph(), targetEdgeCell, (mxCell)cellObj); + + curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; + } + else { + System.out.println("cancel showing state."); + ((ControlFlowDelegationStage)stage). resetAllStyleOfCells(); + curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; + } + break; + } + } + + /************************************************************* + * + */ + @Override + public void stopEditing(boolean cancel) { + + } + + + /************************************************************* + * [ *private ] + /************************************************************* + * [ view ] + /************************************************************* + * + * Todo: support to PUSH/PULL each layer + */ + private void showDelegatableNodesBySelectedEdge(Object cellObj) { + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)graphComponent.getGraph().getModel().getValue(cellObj); + if(callEdgeAttr == null) return; + + ((ControlFlowDelegationStage)stage) + .showDelegatableNodes(graphComponent.getGraph(), callEdgeAttr); + } + + /************************************************************* + * + */ + private void changeCallOrderOfCallEdge(final Object cellObj) { + String input = ""; + int inputOrder = 0; + + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)graphComponent.getGraph().getModel().getValue(cellObj); + if(callEdgeAttr == null) return; + + input = JOptionPane.showInputDialog("Call order"); + if( input == null) return; + if( !isNumeric(input) ) { + JOptionPane.showMessageDialog(graphComponent, "Input value must type of number."); + return; + } + + inputOrder = Integer.parseInt(input); + + final int endOfOrderOfSrc = callEdgeAttr.getSourceObjectNode().getOutdegree(); + + if(inputOrder <= 0 || endOfOrderOfSrc < inputOrder) { + JOptionPane.showMessageDialog(graphComponent, "Input order must be between 1 and " + endOfOrderOfSrc + "."); + return; + } + + int curOrder = callEdgeAttr.getSourceObjectNode().getOutEdgeCallOrder(callEdgeAttr.getCallEdge()); + callEdgeAttr.getSourceObjectNode().sortOutEdgesByCallOrder(curOrder, inputOrder); + graphComponent.refresh(); + } + + + /************************************************************* + * + */ + private boolean isNumeric(final String str) { + if(str == null) return false; + return str.matches("[0-9.]+"); + } + + /************************************************************* + * + */ + private boolean isDuplicatedName(final String name) { + mxCell root = (mxCell)graphComponent.getGraph().getDefaultParent(); + + for(int i = 0; i < root.getChildCount(); i++) { + mxCell layerCell = (mxCell)root.getChildAt(i); + for(int j = 0; j < layerCell.getChildCount(); j++) { + mxCell cell = (mxCell)layerCell.getChildAt(i); + + ObjectNodeAttribute attr = null; + if(cell.getValue() instanceof ObjectNodeAttribute) + attr = (ObjectNodeAttribute)cell.getValue(); + else continue; + + if( !(attr.getObjectNode().getName().equals(name))) continue; + return true; + } + } + return false; + } + + /************************************************************* + * [ *inner class ] + /************************************************************* + * [ action ] + * Inserting an intermediation object type of . + */ + private class InsertObjectNodeAction extends MouseAdapter { + @Override + public void mouseReleased(MouseEvent e) { + // if the right mouse button was clicked, + // then pop up the dialog name to insert a mediator-object. + if( !curState.equals(ControlFlowDelegationStageStatus.SELECTING_AN_EDGE)) return; + if( !SwingUtilities.isRightMouseButton(e) )return; + + Object cellObj = graphComponent.getCellAt(e.getX(), e.getY()); + insertObjectNode(cellObj); + } + + /*************************************************************/ + private void insertObjectNode(final Object cellObj) { + if(cellObj == null) return; + + mxCell edgeCell = null; + if(cellObj instanceof mxCell) edgeCell = (mxCell)cellObj; + else return; + + curState = ControlFlowDelegationStageStatus.SELECTING_AN_EDGE; + + // Inputing name to the dialog. + String objName = JOptionPane.showInputDialog("Object Name:"); + if(objName == null) return; + + if( objName.isEmpty()) { + JOptionPane.showMessageDialog(graphComponent, "You must input a name. \nIt mustn't be empty."); + return; + } + + CallEdgeAttribute callEdgeAttr = null; + if(edgeCell.getValue() instanceof CallEdgeAttribute) { + callEdgeAttr = (CallEdgeAttribute)edgeCell.getValue(); + } + else throw new ClassCastException(); + + if( isDuplicatedName(objName) ) { + JOptionPane.showMessageDialog(graphComponent, "The named object has already existed."); + return; + } + + ((ControlFlowDelegationStage)stage) + .insertObjectNodeCellInControlFlowLayer(graphComponent.getGraph(), edgeCell, objName); + } + + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java new file mode 100644 index 0000000..a53f4f6 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStage.java @@ -0,0 +1,546 @@ +package application.editor.stages; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGeometry; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxEventSource.mxIEventListener; +import com.mxgraph.util.mxPoint; +import com.mxgraph.view.mxGraph; + +import application.editor.Editor; +import application.editor.FlowCellEditor; +import application.editor.Stage; +import models.Edge; +import models.Node; +import models.controlFlowModel.CallEdge; +import models.controlFlowModel.CallEdgeAttribute; +import models.controlFlowModel.CallGraph; +import models.controlFlowModel.ControlFlowDelegator; +import models.controlFlowModel.ControlFlowGraph; +import models.controlFlowModel.EntryPointObjectNode; +import models.controlFlowModel.ObjectNode; +import models.controlFlowModel.ObjectNodeAttribute; +import models.controlFlowModel.StatefulObjectNode; +import models.dataFlowModel.DataFlowGraph; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.ResourceNodeAttribute; + +/************************************************************* + * + */ +public class ControlFlowDelegationStage extends Stage { + public final int PORT_DIAMETER = 8; + public final int PORT_RADIUS = PORT_DIAMETER / 2; + + private ControlFlowGraph controlFlowGraph = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + * @param graph + */ + public ControlFlowDelegationStage(mxGraph graph) { + super(graph); + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + @Override + public boolean canChangeFrom(Stage prevStage) { + if (prevStage instanceof PushPullSelectionStage) return true; + return false; + } + + /************************************************************* + * + */ + @Override + public void init(Stage prevStage) { + if (prevStage instanceof PushPullSelectionStage) { + model = ((PushPullSelectionStage) prevStage).getModel(); + + DataFlowGraph dataFlowGraph = ((PushPullSelectionStage) prevStage).getDataFlowGraph(); + + controlFlowGraph = new ControlFlowGraph(dataFlowGraph, model); + + graph = clearControlFlowGraphCells(graph); + graph = constructGraph(graph, controlFlowGraph); + } + } + + /************************************************************* + * + */ + @Override + public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { + return new ControlFlowDelegationCellEditor(this, graphComponent); + } + + @Override + public mxIEventListener createChangeEventListener(Editor editor) { + return null; + } + + public ControlFlowGraph getControlFlowGraph() { + return controlFlowGraph; + } + + /************************************************************* + * + */ + public void showDelegatableNodes(mxGraph graph, final CallEdgeAttribute callEdgeAttr){ + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell layerCell = null; + switch(callEdgeAttr.getSelectedOption()) { + case PUSH: + layerCell = (mxCell)root.getChildAt(Stage.PUSH_FLOW_LAYER); + break; + + case PULL: + case PUSHorPULL: + layerCell = (mxCell)root.getChildAt(Stage.PULL_FLOW_LAYER); + } + + graph.getModel().beginUpdate(); + try { + ObjectNode delegatingNode = callEdgeAttr.getDestinationObjectNode(); + + for(Object node : graph.getChildVertices(layerCell)) { + if( !(node instanceof mxCell) ) continue; + mxCell cell = (mxCell)node; + + ObjectNodeAttribute objNodeAttr = (ObjectNodeAttribute)cell.getValue(); + if(objNodeAttr == null) return; + + ObjectNode objNode = objNodeAttr.getObjectNode(); + ControlFlowDelegator delegator = new ControlFlowDelegator(controlFlowGraph); + List delegatableNodes = delegator.searchDelegatableNodes(callEdgeAttr.getCallEdge()); + + if(delegatableNodes.contains(objNode)) // enable + graph.getModel().setStyle(cell, objNodeAttr.getEnableStyle()); + else // disable + graph.getModel().setStyle(cell, objNodeAttr.getDisableStyle()); + + + // base-Node + if(delegatingNode.equals(objNodeAttr.getObjectNode())) + graph.getModel().setStyle(cell, objNodeAttr.getDelegatingStyle()); + } + } + finally { + graph.getModel().endUpdate(); + graph.refresh(); + } + } + + /************************************************************* + * Showing the delegated graph. + */ + public void showDelegatedGraph(mxGraph graph, mxCell targetEdgeCell, final mxCell dstObjNodeCell) { + ObjectNode dstObjNode = ((ObjectNodeAttribute)dstObjNodeCell.getValue()).getObjectNode(); + if(dstObjNode == null) throw new ClassCastException(); + + CallEdgeAttribute targetEdgeAttr = (CallEdgeAttribute)targetEdgeCell.getValue(); + if(targetEdgeAttr == null) throw new ClassCastException(); + + ControlFlowDelegator delegator = new ControlFlowDelegator(controlFlowGraph); + delegator.delegateCallEdge(targetEdgeAttr.getCallEdge(), dstObjNode); + + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell layerCell = null; + switch(targetEdgeAttr.getSelectedOption()) { + case PUSH: + layerCell = (mxCell)root.getChildAt(Stage.PUSH_FLOW_LAYER); + break; + + case PULL: + case PUSHorPULL: + layerCell = (mxCell)root.getChildAt(Stage.PULL_FLOW_LAYER); + } + + try { + mxCell dstNodeCell = targetEdgeAttr.getDestinationCell(); + + // Removing the target edge from graph model. + if(graph.getModel().getValue(targetEdgeCell) != null) { + graph.getModel().remove(targetEdgeCell); + } + + // Insert an edge + CallEdgeAttribute newAttr = new CallEdgeAttribute(targetEdgeAttr.getCallEdge(), targetEdgeAttr.getOriginalSourceObjectNode(),dstObjNodeCell, dstNodeCell); + graph.insertEdge(layerCell, "", newAttr, dstObjNodeCell, dstNodeCell, "movable=false;"); + + resetAllStyleOfCells(); + } + finally { + graph.getModel().endUpdate(); + } + } + + /************************************************************* + * + */ + public void resetAllStyleOfCells() { + mxCell root = (mxCell)graph.getDefaultParent(); + + graph.getModel().beginUpdate(); + try { + for(int i = Stage.PUSH_FLOW_LAYER; i <= Stage.PULL_FLOW_LAYER; i++) { + mxCell layerCell = (mxCell)root.getChildAt(i); + for(Object node : graph.getChildVertices(layerCell)) { + mxCell cell = null; + if(node instanceof mxCell) cell = (mxCell)node; + else continue; + + ObjectNodeAttribute objNodeAttr = (ObjectNodeAttribute)(cell.getValue()); + if(objNodeAttr == null) throw new NullPointerException(""); + + graph.getModel().setStyle(cell, objNodeAttr.getDefaultStyle()); + } + } + } + finally { + graph.getModel().endUpdate(); + graph.refresh(); + } + } + + /************************************************************* + * Inserting an intermediation object type of . + * todo: support to PUSH/PULL-layer + */ + public void insertObjectNodeCellInControlFlowLayer(mxGraph graph, mxCell targetEdge, final String insertObjName) { + CallEdgeAttribute callEdgeAttr = (CallEdgeAttribute)targetEdge.getValue(); + if(callEdgeAttr == null) throw new NullPointerException(); + + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell layerCell = null; + switch(callEdgeAttr.getSelectedOption()) { + case PUSH: + layerCell = (mxCell)root.getChildAt(Stage.PUSH_FLOW_LAYER); + break; + + case PULL: + case PUSHorPULL: + layerCell = (mxCell)root.getChildAt(Stage.PULL_FLOW_LAYER); + } + + graph.getModel().beginUpdate(); + + try { + // Inserting the node type of to the graph. + ObjectNode insertObjNode = new ObjectNode(insertObjName); + ObjectNodeAttribute objNodeAttr = new ObjectNodeAttribute(insertObjNode); + + mxPoint srcPoint = new mxPoint(callEdgeAttr.getSourceCell().getGeometry().getX(), callEdgeAttr.getSourceCell().getGeometry().getY()); + mxPoint dstPoint = new mxPoint(callEdgeAttr.getDestinationCell().getGeometry().getX(), callEdgeAttr.getDestinationCell().getGeometry().getY()); + mxPoint insertPoint = new mxPoint( + (srcPoint.getX() + dstPoint.getX())/2, + (srcPoint.getY() + dstPoint.getY())/2); + + mxCell insertObjNodeCell = + (mxCell)graph.insertVertex(layerCell, null, objNodeAttr, + /* coordinate*/ insertPoint.getX(), insertPoint.getY(), + /* scale */ 40, 40, + objNodeAttr.getDefaultStyle()); + insertObjNodeCell.setValue(objNodeAttr); + + addObjectNodeToCallGraphl(insertObjNode, callEdgeAttr.getSelectedOption()); + + // Reconnecting each edges of the node. + ObjectNode srcObjNode = callEdgeAttr.getSourceObjectNode(); + ObjectNode dstObjNode = callEdgeAttr.getDestinationObjectNode(); + if(srcObjNode == null || dstObjNode == null) throw new NullPointerException(); + if(!(srcObjNode instanceof ObjectNode && dstObjNode instanceof ObjectNode)) throw new ClassCastException(); + + // Connecting I/O Edges to the insert object. + CallEdge srcToInsertEdge = callEdgeAttr.getCallEdge(); + CallEdge insertToDstEdge = new CallEdge(insertObjNode, dstObjNode, callEdgeAttr.getSelectedOption()); + if(srcToInsertEdge == null || insertToDstEdge == null) throw new NullPointerException(); + + // Remove the destination edge of the object node. + // After add the "srcToInsertEdge" to the destination object node. + dstObjNode.removeInEdge(srcToInsertEdge); + dstObjNode.addInEdge(insertToDstEdge); + + srcToInsertEdge.setDestination(insertObjNode); // changing the out of edge of the sourceObjectNode + + insertObjNode.addInEdge(srcToInsertEdge); + insertObjNode.addOutEdge(insertToDstEdge); + + // Update the cell of the graph. + for(int i =0; i < layerCell.getChildCount(); i++) { + mxCell nodeCell = (mxCell)layerCell.getChildAt(i); + if( !nodeCell.isVertex()) continue; + + // Checking "nodeCell" has an instance of + ObjectNodeAttribute cellObjNodeAttr = (ObjectNodeAttribute)nodeCell.getValue(); + if(cellObjNodeAttr == null) throw new ClassCastException("dosen't have the value of "); + + // Is "nodeCell" the same as the source cell of the call edge? + if(nodeCell.equals(callEdgeAttr.getSourceCell())){ + mxCell srcNodeCell = callEdgeAttr.getSourceCell(); + CallEdgeAttribute newInEdgeAttr = new CallEdgeAttribute(srcToInsertEdge, srcNodeCell, insertObjNodeCell); + + // If the target call edge hasn't removed yet. + // then it removes from mxGraphModel. + if(graph.getModel().getValue(targetEdge) != null) + graph.getModel().remove(targetEdge); + + mxCell outPortCell = (mxCell)srcNodeCell.getChildAt(0); + if(outPortCell != null) { + graph.insertEdge(layerCell, null, newInEdgeAttr, outPortCell, insertObjNodeCell, "movable=false;"); + } + else { + graph.insertEdge(layerCell, null, newInEdgeAttr, srcNodeCell, insertObjNodeCell, "movable=false;"); + } + continue; + } + // Is "nodeCell" the same as the destination cell of the call edge? + else if(nodeCell.equals(callEdgeAttr.getDestinationCell())) { + mxCell dstNodeCell = callEdgeAttr.getDestinationCell(); + CallEdgeAttribute newOutEdgeAttr = new CallEdgeAttribute(insertToDstEdge, insertObjNodeCell, dstNodeCell); + + // If the target + if(graph.getModel().getValue(targetEdge) != null) + graph.getModel().remove(targetEdge); + + graph.insertEdge(layerCell, null, newOutEdgeAttr, insertObjNodeCell, dstNodeCell, "movable=false;"); + + continue; + } + } + } + finally { + graph.getModel().endUpdate(); + } + } + + + /************************************************************* + * [ *private ] + /************************************************************* + * + */ + private mxGraph constructGraph(mxGraph graph, ControlFlowGraph controlFlowGraph) { + showOnlyLayer(PUSH_FLOW_LAYER, PULL_FLOW_LAYER); + + graph.getModel().beginUpdate(); + try { + // Creating Control-Flow and separeted Push/Pull which types of + Map pushResNodeCells = createCellsOfResourceMap(graph, PUSH_FLOW_LAYER, controlFlowGraph); + Map pullResNodeCells = createCellsOfResourceMap(graph, PULL_FLOW_LAYER, controlFlowGraph); + + // Creating Entry-Point Object + Map pushFlowEntryNodeCells = createCellsOfInputChannel(graph, PUSH_FLOW_LAYER, controlFlowGraph, pushResNodeCells); + + // Inserting edges of each transfer + graph = insertControlFlowEdges(graph, PUSH_FLOW_LAYER, controlFlowGraph.getPushCallGraph(), pushResNodeCells, pushFlowEntryNodeCells); + graph = insertControlFlowEdges(graph, PULL_FLOW_LAYER, controlFlowGraph.getPullCallGraph(), pullResNodeCells, null); + + } finally { + graph.getModel().endUpdate(); + } + return graph; + } + + /************************************************************* + * When changed from previous stage, it will be called in initializing. + */ + private mxGraph clearControlFlowGraphCells(mxGraph graph) { + mxCell root = (mxCell)graph.getDefaultParent(); + + graph.getModel().beginUpdate(); + try { + // removing child from end of a root cell + root.remove(root.getChildAt(PULL_FLOW_LAYER)); + root.remove(root.getChildAt(PUSH_FLOW_LAYER)); + + root.insert(new mxCell()); + root.insert(new mxCell()); + } finally { + graph.getModel().endUpdate(); + } + + graph.refresh(); + + return graph; + } + + /************************************************************* + * Creating a map of to and Creating 's vertices + * @return constructed the view of the graph + */ + private Map createCellsOfResourceMap(mxGraph graph, final int layerNumber, final ControlFlowGraph controlFlowGraph) { + Map resNodeCells = new HashMap<>(); + + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell nodeLayerCell = (mxCell)root.getChildAt(NODE_LAYER); + mxCell layerCell = (mxCell)root.getChildAt(layerNumber); + + // create resource vertices + for (ResourceNode resNode : controlFlowGraph.getDataFlowGraph().getResouceNodes()) { + + ObjectNode objNode = null; + switch(layerNumber) { + case PUSH_FLOW_LAYER: + if(controlFlowGraph.getPushCallGraph().getStatefulObjectNode(resNode) != null) + objNode = controlFlowGraph.getPushCallGraph().getStatefulObjectNode(resNode); + break; + + case PULL_FLOW_LAYER: + if(controlFlowGraph.getPullCallGraph().getStatefulObjectNode(resNode) != null) + objNode = controlFlowGraph.getPullCallGraph().getStatefulObjectNode(resNode); + break; + } + + if(objNode == null) continue; + + for(int i =0; i < nodeLayerCell.getChildCount(); i++) { + mxCell nodeCell = (mxCell)nodeLayerCell.getChildAt(i); + if( nodeCell.getValue() instanceof ResourceNodeAttribute ) { + nodeCell = (mxCell)nodeLayerCell.getChildAt(i); + } + else continue; + + // Checking if the "node" has a cell of the data-flow-layer is the same as "resNode". + ResourceNodeAttribute resNodeAttr = (ResourceNodeAttribute)nodeCell.getValue(); + if( !resNodeAttr.getResourceNode().equals(resNode) )continue; + + // Getting information from the cell in the data-flow-layer, + // After that, insert a resource as a vertex + ObjectNodeAttribute objNodeAttr = new ObjectNodeAttribute(objNode); + mxCell resNodeObjCell = (mxCell)graph.insertVertex(layerCell, null, objNodeAttr, + /* scale */nodeCell.getGeometry().getX(), nodeCell.getGeometry().getY(), + /*coordinate*/nodeCell.getGeometry().getWidth(), nodeCell.getGeometry().getHeight(), + objNodeAttr.getDefaultStyle()); + + resNodeCells.put(resNode, resNodeObjCell); + } + } + + return resNodeCells; + } + + /************************************************************* + * Createing an input channel object + */ + private Map createCellsOfInputChannel(mxGraph graph, final int layerNumber, final ControlFlowGraph controlGraph, final Map resNodeCell){ + if(layerNumber == PULL_FLOW_LAYER) return null; + + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell layerCell = (mxCell)root.getChildAt(layerNumber); + + Map ioChannelCells = new HashMap<>(); + + graph.getModel().beginUpdate(); + try { + mxGeometry outPortGeometry = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + outPortGeometry.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + outPortGeometry.setRelative(true); + + CallGraph callGraph = controlFlowGraph.getPushCallGraph(); + + // insert an I/O channel as a vertex + for (Node node : callGraph.getNodes()) { + EntryPointObjectNode entryPointObjNode = null; + if(node instanceof EntryPointObjectNode) + entryPointObjNode = (EntryPointObjectNode)node; + else continue; + + ObjectNodeAttribute entryObjAttr = new ObjectNodeAttribute(entryPointObjNode); + + mxCell channel = (mxCell)graph.insertVertex(layerCell, null, entryObjAttr, 150, 20, 30, 30); + mxCell port_out = new mxCell(null, outPortGeometry, "shape=ellipse;perimter=ellipsePerimeter"); + port_out.setVertex(true); + + graph.addCell(port_out, channel); // insert the output port of a channel + ioChannelCells.put(entryPointObjNode, channel); + } + } + finally { + graph.getModel().endUpdate(); + } + + return ioChannelCells; + } + + /************************************************************* + * When changed from previous stage, it will be called in initializing. + */ + private mxGraph insertControlFlowEdges(mxGraph graph, final int layerNumber, final CallGraph callGraph ,final Map resNodeCells, final Map entryNodeCells) { + mxCell root = (mxCell)graph.getDefaultParent(); + mxCell layerCell = (mxCell)root.getChildAt(layerNumber); + + for (Edge callGraphEdge : callGraph.getEdges()) { + if ( !(callGraphEdge instanceof CallEdge))continue; + CallEdge callEdge = (CallEdge) callGraphEdge; + + // Is checking node connecting a resource? + if(callEdge.getSource() == null || callEdge.getDestination() == null) continue; + + Node srcResNode = null; + ResourceNode dstResNode = ((StatefulObjectNode)callEdge.getDestination()).getResource(); + + mxCell srcNodeCell =null; + mxCell srcOutPortCell = null; + mxCell dstNodeCell = resNodeCells.get(dstResNode); + + if(callEdge.getSource() instanceof StatefulObjectNode) { + srcResNode = ((StatefulObjectNode)callEdge.getSource()).getResource(); + srcNodeCell =resNodeCells.get(srcResNode); + } + else if (callEdge.getSource() instanceof EntryPointObjectNode) { + srcResNode = (EntryPointObjectNode)callEdge.getSource(); + srcNodeCell = entryNodeCells.get(srcResNode); + srcOutPortCell = (mxCell)srcNodeCell.getChildAt(0); + } + else continue; + + if(srcNodeCell == null || dstNodeCell == null) continue; + + CallEdgeAttribute callEdgeAttr = new CallEdgeAttribute(callEdge, (ObjectNode)callEdge.getSource(), srcNodeCell, dstNodeCell); + + // If "srcResNode" types of "EntryPointObjectNode" (= channel) + // then parameter references to geometry of "outPort". + if(srcResNode instanceof ResourceNode) { + graph.insertEdge(layerCell, null, callEdgeAttr, srcNodeCell, dstNodeCell, "movable=false;"); + } + else if(srcResNode instanceof EntryPointObjectNode) { + graph.insertEdge(layerCell, null, callEdgeAttr, srcOutPortCell, dstNodeCell, "movable=false;"); + } + + } + return graph; + } + + /************************************************************* + * + */ + private void addObjectNodeToCallGraphl(final ObjectNode insertObjNode, final PushPullValue selectedOption) { + switch(selectedOption) { + case PUSH: + if(controlFlowGraph.getPushCallGraph().getNodes().contains(insertObjNode))return; + controlFlowGraph.getPushCallGraph().addNode(insertObjNode); + + break; + + case PULL: + case PUSHorPULL: + if(controlFlowGraph.getPullCallGraph().getNodes().contains(insertObjNode))return; + controlFlowGraph.getPullCallGraph().addNode(insertObjNode); + + break; + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStageStatus.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStageStatus.java new file mode 100644 index 0000000..9cf8f99 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/ControlFlowDelegationStageStatus.java @@ -0,0 +1,10 @@ +package application.editor.stages; + +/************************************************************* + * + * @author k-fujii + */ +public enum ControlFlowDelegationStageStatus { + SELECTING_AN_EDGE, + SHOWING_DELEGATABLE_NODES, +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowCellEditor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowCellEditor.java new file mode 100644 index 0000000..f05c14c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowCellEditor.java @@ -0,0 +1,149 @@ +package application.editor.stages; + +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 application.editor.Editor; +import application.editor.FlowCellEditor; +import models.algebra.Expression; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.DataTransferChannelGenerator; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.visualModel.FormulaChannelGenerator; +import parser.Parser; +import parser.Parser.TokenStream; +import parser.exceptions.ExpectedRightBracket; + +/************************************************************* + * + */ +public class DataFlowCellEditor extends FlowCellEditor { + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + * @param stage + * @param graphComponent + */ + public DataFlowCellEditor(DataFlowModelingStage stage, mxGraphComponent graphComponent) { + super(stage, graphComponent); + } + + /************************************************************* + * + * @param cellObj + * @param eventObj + */ + @Override + public void startEditing(Object cellObj, EventObject eventObj) { + if (editingCell != null) { + stopEditing(true); + } + + if (!graphComponent.getGraph().getModel().isEdge(cellObj)) { + DataTransferChannelGenerator ch = (DataTransferChannelGenerator) stage.getModel().getChannelGenerator((String) ((mxCell) cellObj).getValue()); + if (ch == null) { + ch = (DataTransferChannelGenerator) stage.getModel().getIOChannelGenerator((String) ((mxCell) cellObj).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, // 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, stage.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) { + ((DataFlowModelingStage)stage).setChannelCode(ch, textArea.getText()); + } + } + return; + } + } + + /************************************************************* + * + * @param cancel + */ + @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..100de3d --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java @@ -0,0 +1,451 @@ +package application.editor.stages; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.mxEventObject; +import com.mxgraph.util.mxPoint; +import com.mxgraph.view.mxGraph; + +import algorithms.Validation; +import application.editor.Editor; +import application.editor.Editor.SrcDstAttribute; +import application.editor.FlowCellEditor; +import application.editor.Stage; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataTransferChannelGenerator; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.ResourceNodeAttribute; +import models.visualModel.FormulaChannelGenerator; +import parser.Parser; +import parser.Parser.TokenStream; +import parser.exceptions.ExpectedAssignment; +import parser.exceptions.ExpectedChannel; +import parser.exceptions.ExpectedChannelName; +import parser.exceptions.ExpectedEquals; +import parser.exceptions.ExpectedInOrOutOrRefKeyword; +import parser.exceptions.ExpectedLeftCurlyBracket; +import parser.exceptions.ExpectedRHSExpression; +import parser.exceptions.ExpectedRightBracket; +import parser.exceptions.ExpectedStateTransition; +import parser.exceptions.WrongLHSExpression; +import parser.exceptions.WrongRHSExpression; + +/************************************************************* + * + * @author n-nitta, k-fujii + */ +public class DataFlowModelingStage extends Stage { + public int PORT_DIAMETER = 8; + public int PORT_RADIUS = PORT_DIAMETER / 2; + + /************************************************************* + * [ *constructor] + /************************************************************* + * + */ + public DataFlowModelingStage(mxGraph graph) { + super(graph); + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + @Override + public boolean canChangeFrom(Stage prevStage) { + return true; + } + + /************************************************************* + * + */ + @Override + public void init(Stage prevStage) { + showOnlyLayer(DATA_FLOW_LAYER); + } + + /************************************************************* + * + */ + @Override + public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { + return new DataFlowCellEditor(this, graphComponent); + } + + @Override + public mxIEventListener createChangeEventListener(Editor editor) { + return 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}); + } + } + } + }; + } + + /************************************************************* + * + */ + public void clear() { + model = null; + ((mxGraphModel) graph.getModel()).clear(); + + // Construct layers. + mxCell root = (mxCell) graph.getDefaultParent(); + graph.getModel().beginUpdate(); + try { + root.insert(new mxCell()); // NODE_LAYER, DATA_FLOW_LAYER + root.insert(new mxCell()); // CONTROL_FLOW_LAYER + root.insert(new mxCell()); // PUSH_FLOW_LAYER + root.insert(new mxCell()); // PULL_FLOW_LAYER + + showOnlyLayer(NODE_LAYER, DATA_FLOW_LAYER); + } + finally { + graph.getModel().endUpdate(); + } + graph.refresh(); + } + + /************************************************************* + * + */ + public DataTransferModel getModel() { + if (model == null) { + setModel(new DataTransferModel()); + } + return model; + } + + /************************************************************* + * + */ + public void setModel(DataTransferModel model) { + clear(); + // Set the model. + this.model = model; + + // Update the mxGraph. + graph = constructGraph(graph, model); + } + + /************************************************************* + * + */ + public boolean isValid() { + if (model == null) return false; + if (!Validation.checkUpdateConflict(model)) return false; + return true; + } + + /************************************************************* + * Construct a mxGraph from DataFlowModel + * @param model + * @param dataFlowGraph + * @return constructed mxGraph + */ + public mxGraph constructGraph(mxGraph graph, DataTransferModel model) { + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell nodeLayer = (mxCell) root.getChildAt(NODE_LAYER); + mxCell dataFlowLayer = (mxCell) root.getChildAt(DATA_FLOW_LAYER); + + 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); + + mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); + geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); + geo2.setRelative(true); + + Map channelsIn = new HashMap<>(); + Map channelsOut = new HashMap<>(); + Map resources = new HashMap<>(); + + // create channel vertices + for (ChannelGenerator c: model.getChannelGenerators()) { + DataTransferChannelGenerator channelGen = (DataTransferChannelGenerator) c; + if (channelsIn.get(channelGen) == null || channelsOut.get(channelGen) == null) { + Object channel = graph.insertVertex(dataFlowLayer, 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 (IdentifierTemplate res: model.getIdentifierTemplates()) { + // insert a resource as a vertex + ResourceNodeAttribute resNodeAttr = new ResourceNodeAttribute(model.getDataFlowGraph().getResouceNode(res)); + Object resource = graph.insertVertex( + dataFlowLayer, null, resNodeAttr, + /*coordinate*/20, 20, + /* scale */80, 30, + resNodeAttr.getDefaultStyle()); + resources.put(res, resource); + } + + // add input, output and reference edges + for (ChannelGenerator ch: model.getChannelGenerators()) { + DataTransferChannelGenerator channelGen = (DataTransferChannelGenerator) ch; + // input edge + for (IdentifierTemplate srcRes: channelGen.getInputIdentifierTemplates()) { + graph.insertEdge(dataFlowLayer, null, new SrcDstAttribute(srcRes, channelGen), resources.get(srcRes), channelsIn.get(channelGen), "movable=false;strokeColor=#FF0000"); + } + // output edge + for (IdentifierTemplate dstRes: channelGen.getOutputIdentifierTemplates()) { + graph.insertEdge(dataFlowLayer, null, new SrcDstAttribute(channelGen, dstRes), channelsOut.get(channelGen), resources.get(dstRes), "movable=false;strokeColor=#FF0000"); + } + // reference edges + for (IdentifierTemplate refRes: channelGen.getReferenceIdentifierTemplates()) { + graph.insertEdge(dataFlowLayer, null, null, resources.get(refRes), channelsIn.get(channelGen), "dashed=true;movable=false;strokeColor=#FF0000"); + } + } + + for (ChannelGenerator ioChannelGen: model.getIOChannelGenerators()) { + if (channelsOut.get(ioChannelGen) == null) { + Object channel = graph.insertVertex(nodeLayer, 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 + channelsOut.put((DataTransferChannelGenerator) ioChannelGen, port_out); + + for (IdentifierTemplate outRes: ((DataTransferChannelGenerator) ioChannelGen).getOutputIdentifierTemplates()) { + graph.insertEdge(dataFlowLayer, null, null, port_out, resources.get(outRes), "movable=false;strokeColor=#FF0000"); + } + + } + } + } finally { + graph.getModel().endUpdate(); + } + + return graph; + } + + /************************************************************* + * + */ + public void addIdentifierTemplate(IdentifierTemplate res) { + getModel().addIdentifierTemplate(res); + graph.getModel().beginUpdate(); + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell layer = (mxCell) root.getChildAt(NODE_LAYER); + try { + graph.insertVertex(layer, null, res.getResourceName(), 20, 20, 80, 30, + "shape=ellipse;perimeter=ellipsePerimeter"); // insert a resource as a vertex + } finally { + graph.getModel().endUpdate(); + } + } + + /************************************************************* + * + */ + public void addChannelGenerator(DataTransferChannelGenerator channelGen) { + getModel().addChannelGenerator(channelGen); + graph.getModel().beginUpdate(); + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell layer = (mxCell) root.getChildAt(DATA_FLOW_LAYER); + 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(layer, 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(DataTransferChannelGenerator ioChannelGen) { + getModel().addIOChannelGenerator(ioChannelGen); + graph.getModel().beginUpdate(); + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell layer = (mxCell) root.getChildAt(NODE_LAYER); + 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(layer, 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); + graph.getModel().beginUpdate(); + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell layer = (mxCell) root.getChildAt(DATA_FLOW_LAYER); + 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(layer, 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(); + 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); + ((DataTransferChannelGenerator ) dstCh).addChannelMemberAsInput(srcCm); + edge.setValue(new SrcDstAttribute(srcRes, dstCh)); + return true; + } + } + IdentifierTemplate dstRes = model.getIdentifierTemplate((String) dst.getValue()); + if (dstRes == null) return false; + // channel to resource edge + ChannelMember dstCm = new ChannelMember(dstRes); + ((DataTransferChannelGenerator) srcCh).addChannelMemberAsOutput(dstCm); + edge.setValue(new 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.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()); + } + + /************************************************************* + * + */ + public void setChannelCode(DataTransferChannelGenerator ch, String code) { + ch.setSourceText(code); + TokenStream stream = new TokenStream(); + Parser parser = new Parser(stream); + + for (String line: code.split("\n")) { + stream.addLine(line); + } + try { + DataTransferChannelGenerator ch2 = parser.parseChannel(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; + } + } + } + } catch (ExpectedRightBracket | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket + | ExpectedInOrOutOrRefKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression + | WrongLHSExpression | WrongRHSExpression | ExpectedAssignment 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..49325a3 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionCellEditor.java @@ -0,0 +1,165 @@ +package application.editor.stages; + +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.util.mxConstants; +import com.mxgraph.util.mxUtils; +import com.mxgraph.view.mxCellState; + +import application.editor.FlowCellEditor; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; + +/************************************************************* + * + */ +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; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * @param stage + * @param graphComponent + */ + public PushPullSelectionCellEditor(PushPullSelectionStage stage, mxGraphComponent graphComponent) { + super(stage, graphComponent); + } + + /************************************************************* + * + * @param cellObj + * @param eventObj + */ + @Override + public void startEditing(Object cellObj, EventObject eventObj) { + if (editingCell != null) { + stopEditing(true); + } + + if (graphComponent.getGraph().getModel().isEdge(cellObj)) { + mxCellState state = graphComponent.getGraph().getView().getState(cellObj); + if (state != null && state.getLabel() != null && !state.getLabel().equals("")) { + editingCell = cellObj; + trigger = eventObj; + + double scale = Math.max(minimumEditorScale, graphComponent.getGraph().getView().getScale()); + Object value = graphComponent.getGraph().getModel().getValue(cellObj); + 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(); + } + } + } + } + + /************************************************************* + * + * @param cancel + */ + @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/stages/PushPullSelectionStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java new file mode 100644 index 0000000..dedf31d --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java @@ -0,0 +1,131 @@ +package application.editor.stages; + +import java.util.ArrayList; +import java.util.List; + +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGraphModel; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxEventObject; +import com.mxgraph.util.mxEventSource.mxIEventListener; +import com.mxgraph.view.mxGraph; + +import algorithms.DataTransferModelAnalyzer; +import application.editor.Editor.SrcDstAttribute; +import application.editor.Editor; +import application.editor.FlowCellEditor; +import application.editor.InEdgeAttribute; +import application.editor.OutEdgeAttribute; +import application.editor.Stage; +import models.Edge; +import models.dataFlowModel.DataFlowEdge; +import models.dataFlowModel.DataFlowGraph; +import models.dataFlowModel.DataTransferChannelGenerator; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.ResourceNode; + +public class PushPullSelectionStage extends Stage { + protected DataFlowGraph dataFlowGraph = null; + + public PushPullSelectionStage(mxGraph graph) { + super(graph); + } + + @Override + public boolean canChangeFrom(Stage prevStage) { + if (prevStage instanceof DataFlowModelingStage) { + if (!((DataFlowModelingStage) prevStage).isValid()) return false; + return true; + } + if (prevStage instanceof ControlFlowDelegationStage) return true; + return false; + } + + @Override + public void init(Stage prevStage) { + if (prevStage instanceof DataFlowModelingStage) { + model = ((DataFlowModelingStage) prevStage).getModel(); + dataFlowGraph = analyzeDataTransferModel(graph, model); + showOnlyLayer(DATA_FLOW_LAYER); + } + + if(prevStage instanceof ControlFlowDelegationStage) { + showOnlyLayer(DATA_FLOW_LAYER); + } + } + + @Override + public FlowCellEditor createCellEditor(mxGraphComponent graphComponent) { + return new PushPullSelectionCellEditor(this, graphComponent); + } + + @Override + public mxIEventListener createChangeEventListener(Editor editor) { + return 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) { + // cancel connect + graph.removeCells(new mxCell[] {cell}); + } + } + }; + } + + public DataFlowGraph getDataFlowGraph() { + return dataFlowGraph; + } + + public DataFlowGraph analyzeDataTransferModel(mxGraph graph, DataTransferModel model) { + DataFlowGraph flowGraph = DataTransferModelAnalyzer.createDataFlowGraphWithStateStoringAttribute(model); + DataFlowGraph dataFlowGraph = DataTransferModelAnalyzer.annotateWithSelectableDataTransferAttiribute(flowGraph); + updateEdgeAttiributes(graph, dataFlowGraph); + return dataFlowGraph; + } + + private void updateEdgeAttiributes(mxGraph graph, DataFlowGraph dataFlowGraph) { + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell layer = (mxCell) root.getChildAt(DATA_FLOW_LAYER); + + graph.getModel().beginUpdate(); + try { + // update attributes of input and output edges + for (Edge e : dataFlowGraph.getEdges()) { + if (e instanceof DataFlowEdge) { + DataFlowEdge dataFlow = (DataFlowEdge) e; + DataTransferChannelGenerator channelGen = dataFlow.getChannelGenerator(); + ResourceNode srcRes = (ResourceNode) dataFlow.getSource(); + ResourceNode dstRes = (ResourceNode) dataFlow.getDestination(); + for (Object edge: graph.getChildEdges(layer)) { + mxCell edgeCell = (mxCell) edge; + if (edgeCell.getValue() instanceof SrcDstAttribute) { + SrcDstAttribute edgeAttr = (SrcDstAttribute) edgeCell.getValue(); + if (edgeAttr.getSrouce() == srcRes.getIdentifierTemplate() && edgeAttr.getDestination() == channelGen) { + // input edge + edgeCell.setValue(new InEdgeAttribute((PushPullAttribute) dataFlow.getAttribute(), srcRes)); + break; + } else if (edgeAttr.getSrouce() == channelGen && edgeAttr.getDestination() == dstRes.getIdentifierTemplate()) { + // output edge + edgeCell.setValue(new OutEdgeAttribute(edgeAttr, dstRes)); + break; + } + } + } + } + } + } finally { + graph.getModel().endUpdate(); + } + graph.refresh(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java b/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java new file mode 100644 index 0000000..0389845 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/layouts/DAGLayout.java @@ -0,0 +1,169 @@ +package application.layouts; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.mxgraph.layout.mxGraphLayout; +import com.mxgraph.model.mxCell; +import com.mxgraph.model.mxGeometry; +import com.mxgraph.model.mxICell; +import com.mxgraph.model.mxIGraphModel; +import com.mxgraph.util.mxRectangle; +import com.mxgraph.view.mxCellState; +import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; + +import models.controlFlowModel.ObjectNodeAttribute; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.ResourceNodeAttribute; + +/************************************************************* + * DAG-Layout sorting algorithm. + */ +public class DAGLayout extends mxGraphLayout { + + /************************************************************* + * [ *constructor] + /************************************************************* + * + * @param cell + */ + public DAGLayout(mxGraph cell) { + super(cell); + } + + /************************************************************* + * [ *public ] + /************************************************************* + * Executing a layout sorting algorithm. + */ + @Override + public void execute(Object parent) { + mxIGraphModel model = graph.getModel(); + + model.beginUpdate(); + try { + List> map = new ArrayList>(); + List moved = new ArrayList<>(); + + for (int i = 0; i < model.getChildCount(parent); i++) { + + mxCell cell = (mxCell) model.getChildAt(parent, i); + + if (model.isVertex(cell)) { + mxGraphView view = graph.getView(); + mxCellState state = view.getState(cell); + + if (!"ellipse".equals(state.getStyle().get("shape")) && (cell.getEdgeCount() == 1) && !"true".equals(state.getStyle().get("dashed"))) { + List newline = new ArrayList(); + map.add(newline); + lines(map, cell); + } + } + } + + // ���בւ� + sort(map, 0, false); + + // layout + int count; + int skip = 0; + mxGraphView view = graph.getView(); + for (int i = 0; i < map.size(); i++) { + count = 0; + for (int j = 0; j < map.get(i).size(); j++) { + mxGeometry geom = (mxGeometry) map.get(i).get(j).getGeometry().clone(); + mxCellState state = view.getState(map.get(i).get(j)); + + + if (checkmoved(moved, map.get(i).get(j))) { + if ("ellipse".equals(state.getStyle().get("shape"))){ + geom.setX(50 + j*200); + } else { + geom.setX(100 + j*200); + } + geom.setY(100 + (i-skip)*100); + model.setGeometry(map.get(i).get(j), geom); + moved.add(map.get(i).get(j).getId()); + } else if (geom.getX() < 100 + j*150) { + if ("ellipse".equals(state.getStyle().get("shape"))){ + geom.setX(50 + j*200); + } else { + geom.setX(100 + j*200); + } + geom.setY(100 + (i-skip)*100); + model.setGeometry(map.get(i).get(j), geom); + } else { + count++; + } + } + if (count >= map.get(i).size())skip++; + } + + } finally { + model.endUpdate(); + } + } + + + public void lines(List> mapping, mxCell next) { + mapping.get(mapping.size()-1).add(next); + int tagcount = 0; + mxCell edge; + mxGraphView view = graph.getView(); + for (int i = 0; i < next.getEdgeCount(); i++) { + edge = (mxCell) next.getEdgeAt(i); + mxCellState state = view.getState(edge); + if (next != (mxCell) edge.getTarget() && ((mxCell) edge.getTarget() != null) && !"true".equals(state.getStyle().get("dashed"))) { + tagcount++; + if (tagcount > 1) { + List newline = new ArrayList(mapping.get(mapping.size()-1)); + while (newline.get(newline.size()-1).getId() != next.getId()) { + newline.remove(newline.size()-1); + } + mapping.add(newline); + lines(mapping, (mxCell) edge.getTarget()); + + } else { + lines(mapping, (mxCell) edge.getTarget()); + } + } + } + } + + public boolean checkmoved(List list, mxCell cell) { + for (int i = 0; i < list.size(); i++) { + if (list.get(i).equals(cell.getId()))return false; + } + return true; + } + + public void sort(List> map, int n, boolean check) { + int msize = -1; + int mnum = -1; + if (check) { + for (int i = n; i < map.size(); i++) { + if (map.get(i).size() > msize && (map.get(n-1).get(0).getId().equals(map.get(i).get(0).getId()))) { + mnum = i; + } + } + } else { + for (int i = n; i < map.size(); i++) { + if (map.get(i).size() > msize) { + mnum = i; + } + } + } + if (mnum >= 0) { + Collections.swap(map, n, mnum); + sort(map, n+1, true); + } else if(n < map.size()) { + sort(map, n+1, false); + } + } + + +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java b/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java new file mode 100644 index 0000000..ca47c26 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java @@ -0,0 +1,152 @@ +package application.views; + +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.ButtonGroup; +import javax.swing.JDialog; +import javax.swing.JToggleButton; + +import application.ApplicationWindow; +import application.editor.Editor; +import application.editor.IStageChangeListener; +import application.editor.Stage; +import application.editor.stages.ControlFlowDelegationStage; +import application.editor.stages.DataFlowModelingStage; +import application.editor.stages.PushPullSelectionStage; + +public class NavigationWindow extends JDialog implements IStageChangeListener { + private String title = "Navigation"; + private Editor editor; + private JToggleButton dataFlowModelingButton; + private JToggleButton pushPullSelectionButton; + private JToggleButton controlFlowDelegationButton; + private boolean forbidReentry = false; + + public NavigationWindow(ApplicationWindow owner, Editor editor) { + super(owner); + setTitle(title); + setDefaultCloseOperation(HIDE_ON_CLOSE); + this.editor = editor; + Container panel = getContentPane(); + panel.setLayout(new java.awt.GridLayout(3, 1)); + dataFlowModelingButton = new JToggleButton("Data-Flow Modeling"); + pushPullSelectionButton = new JToggleButton("PUSH/PULL Selection"); + controlFlowDelegationButton = new JToggleButton("Control-Flow Delegation"); + dataFlowModelingButton.addActionListener(new DataFlowModelingButtonListener()); + pushPullSelectionButton.addActionListener(new PushPullSelectionButtonListener()); + controlFlowDelegationButton.addActionListener(new ControlFlowDelegationButtonListener()); + ButtonGroup group = new ButtonGroup(); + group.add(dataFlowModelingButton); + group.add(pushPullSelectionButton); + group.add(controlFlowDelegationButton); + panel.add(dataFlowModelingButton); + panel.add(pushPullSelectionButton); + panel.add(controlFlowDelegationButton); + controlFlowDelegationButton.setEnabled(false); + pushPullSelectionButton.setEnabled(false); + dataFlowModelingButton.setSelected(true); + pack(); + setResizable(false); + } + + @Override + public void stageChanged(Stage newStage) { + if (forbidReentry) return; + if (newStage instanceof DataFlowModelingStage) { + dataFlowModelingButton.setSelected(true); + if (editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)) { + pushPullSelectionButton.setEnabled(true); + } else { + pushPullSelectionButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_CONTROL_FLOW_DELEGATION)) { + controlFlowDelegationButton.setEnabled(true); + } else { + controlFlowDelegationButton.setEnabled(false); + } + } else if (newStage instanceof PushPullSelectionStage) { + pushPullSelectionButton.setSelected(true); + if (editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)) { + dataFlowModelingButton.setEnabled(true); + } else { + dataFlowModelingButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_CONTROL_FLOW_DELEGATION)) { + controlFlowDelegationButton.setEnabled(true); + } else { + controlFlowDelegationButton.setEnabled(false); + } + } else if (newStage instanceof ControlFlowDelegationStage) { + controlFlowDelegationButton.setSelected(true); + if (editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)) { + dataFlowModelingButton.setEnabled(true); + } else { + dataFlowModelingButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)) { + pushPullSelectionButton.setEnabled(true); + } else { + pushPullSelectionButton.setEnabled(false); + } + } + } + + private class DataFlowModelingButtonListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + forbidReentry = true; + editor.changeStage(Editor.STAGE_DATA_FLOW_MODELING); + forbidReentry = false; + if (editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)) { + pushPullSelectionButton.setEnabled(true); + } else { + pushPullSelectionButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_CONTROL_FLOW_DELEGATION)) { + controlFlowDelegationButton.setEnabled(true); + } else { + controlFlowDelegationButton.setEnabled(false); + } + } + } + + private class PushPullSelectionButtonListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + forbidReentry = true; + editor.changeStage(Editor.STAGE_PUSH_PULL_SELECTION); + forbidReentry = false; + if (editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)) { + dataFlowModelingButton.setEnabled(true); + } else { + dataFlowModelingButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_CONTROL_FLOW_DELEGATION)) { + controlFlowDelegationButton.setEnabled(true); + } else { + controlFlowDelegationButton.setEnabled(false); + } + } + } + + private class ControlFlowDelegationButtonListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + forbidReentry = true; + editor.changeStage(Editor.STAGE_CONTROL_FLOW_DELEGATION); + forbidReentry = false; + if (editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)) { + dataFlowModelingButton.setEnabled(true); + } else { + dataFlowModelingButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)) { + pushPullSelectionButton.setEnabled(true); + } else { + pushPullSelectionButton.setEnabled(false); + } + } + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/FlowLayerValue.java b/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/FlowLayerValue.java new file mode 100644 index 0000000..0c9317c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/FlowLayerValue.java @@ -0,0 +1,10 @@ +package application.views.controlFlowDelegation; + +/************************************************************* + * + */ +public enum FlowLayerValue { + DATA_FLOW, + PUSH_FLOW, + PULL_FLOW +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/ShowFlowWindow.java b/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/ShowFlowWindow.java new file mode 100644 index 0000000..34c1d6a --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/views/controlFlowDelegation/ShowFlowWindow.java @@ -0,0 +1,111 @@ +package application.views.controlFlowDelegation; + +import java.awt.Container; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.ButtonGroup; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JRadioButton; + +import application.ApplicationWindow; +import application.editor.Editor; +import application.editor.IStageChangeListener; +import application.editor.Stage; +import application.editor.stages.ControlFlowDelegationStage; + +/************************************************************* + * the window has a button group for swichting layers in the control-flow-modeling. + */ +public class ShowFlowWindow extends JDialog implements IStageChangeListener { + private String title = "ShowFlowWindow"; + private JCheckBox dataFlowCheckBox = null; + private JCheckBox pushFlowCheckBox = null; + private JCheckBox pullFlowCheckBox = null; + + private ControlFlowDelegationStage stage = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public ShowFlowWindow(final ApplicationWindow owner) { + super(owner); + + setTitle(title); + setDefaultCloseOperation(HIDE_ON_CLOSE); + + stage = Editor.STAGE_CONTROL_FLOW_DELEGATION; + + // initialize buttons + dataFlowCheckBox = new JCheckBox("Data-Flow", false); + pushFlowCheckBox = new JCheckBox("Push-Flow", true); + pullFlowCheckBox = new JCheckBox("Pull-Flow", true); + + // each add handler + dataFlowCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + stage.setEnabledForLayer(Stage.DATA_FLOW_LAYER, dataFlowCheckBox.isSelected()); + }}); + + pushFlowCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + stage.setEnabledForLayer(Stage.PUSH_FLOW_LAYER, pushFlowCheckBox.isSelected()); + }}); + + pullFlowCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + stage.setEnabledForLayer(Stage.PULL_FLOW_LAYER, pullFlowCheckBox.isSelected()); + }}); + + dataFlowCheckBox.setEnabled(false); + pushFlowCheckBox.setEnabled(false); + pullFlowCheckBox.setEnabled(false); + + // initialize panel + Container panel = getContentPane(); + panel.setLayout(new GridLayout(/*low*/3, /*col*/1)); + panel.add(dataFlowCheckBox); + panel.add(pushFlowCheckBox); + panel.add(pullFlowCheckBox); + + pack(); + setResizable(false); + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + @Override + public void stageChanged(Stage newStage) { + if((newStage instanceof ControlFlowDelegationStage)) { + + dataFlowCheckBox.setEnabled(true); + pushFlowCheckBox.setEnabled(true); + pullFlowCheckBox.setEnabled(true); + + newStage.setEnabledForLayer(Stage.PUSH_FLOW_LAYER, pushFlowCheckBox.isSelected()); + newStage.setEnabledForLayer(Stage.PULL_FLOW_LAYER, pullFlowCheckBox.isSelected()); + } + else { + dataFlowCheckBox.setEnabled(false); + pushFlowCheckBox.setEnabled(false); + pullFlowCheckBox.setEnabled(false); + + newStage.setEnabledForLayer(Stage.PUSH_FLOW_LAYER, false); + newStage.setEnabledForLayer(Stage.PULL_FLOW_LAYER, false); + } + } +} + diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java index fc4e104..fad7629 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java @@ -21,7 +21,7 @@ this(methodName, false); } - public MethodDeclaration(String methodName,Type returnType) { + public MethodDeclaration(String methodName, Type returnType) { this(methodName, false); this.returnType = returnType; } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/TypeDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/TypeDeclaration.java index 1dc5cf3..0406d59 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/TypeDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/TypeDeclaration.java @@ -34,6 +34,10 @@ methods.add(method); } + public void removeMethod(MethodDeclaration method) { + methods.remove(method); + } + public List getFields() { return fields; } @@ -41,6 +45,12 @@ public List getMethods() { return methods; } + + public MethodDeclaration createConstructor() { + MethodDeclaration constructor = new MethodDeclaration(typeName, true); + addMethod(constructor); + return constructor; + } @Override public Annotation getAnnotation(String name) { diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java new file mode 100644 index 0000000..9783715 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java @@ -0,0 +1,644 @@ +package generators; + +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 code.ast.Block; +import code.ast.CompilationUnit; +import code.ast.FieldDeclaration; +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import code.ast.VariableDeclaration; +import models.Edge; +import models.Node; +import models.algebra.Expression; +import models.algebra.InvalidMessage; +import models.algebra.ParameterizedIdentifierIsFutureWork; +import models.algebra.Term; +import models.algebra.Type; +import models.algebra.UnificationFailed; +import models.algebra.ValueUndefined; +import models.algebra.Variable; +import models.controlFlowModel.EntryPointObjectNode; +import models.controlFlowModel.ObjectNode; +import models.controlFlowModel.StatefulObjectNode; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataFlowEdge; +import models.dataFlowModel.DataTransferChannelGenerator; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.IFlowGraph; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork; +import models.dataFlowModel.ResourceNode; +import models.dataFlowModel.StoreAttribute; +import models.dataFlowModel.DataTransferChannelGenerator.IResourceStateAccessor; + +/** + * Common generator for prototypes + * + * @author Nitta + * + */ +public class CodeGenerator { + public static final String fieldOfResourceState = "value"; + public static final String getterOfResourceState = "getValue"; + public static final String updateMethodName = "update"; + private static String mainTypeName = null; + + public static String getMainTypeName() { + return mainTypeName; + } + + public static void setMainTypeName(String mainTypeName) { + CodeGenerator.mainTypeName = mainTypeName; + } + + public static void resetMainTypeName() { + CodeGenerator.mainTypeName = null; + } + + /** + * Generate source codes in specified language from data-flow/control-flow graph. + * + * @param model architecture model + * @param flowGraph data-flow or control-flow graph + * @param langSpec specified language + * @return source codes + */ + static public ArrayList doGenerate(DataTransferModel model, IFlowGraph flowGraph, ILanguageSpecific langSpec) { + ArrayList codes = new ArrayList<>(); + ArrayList components = determineComponentOrder(flowGraph); + + // Add the main component. + if (mainTypeName == null) { + mainTypeName = langSpec.getMainComponentName(); + } + TypeDeclaration mainComponent = langSpec.newTypeDeclaration(mainTypeName); + MethodDeclaration mainConstructor = mainComponent.createConstructor(); + CompilationUnit mainCU = langSpec.newCompilationUnit(mainComponent); + codes.add(mainCU); + + // For each of other components. + for (Node componentNode: components) { + // Declare this component. + String componentName = null; + if (componentNode instanceof ResourceNode) { + componentName = langSpec.toComponentName(((ResourceNode) componentNode).getIdentifierTemplate().getResourceName()); + } else if (componentNode instanceof ObjectNode) { + componentName = langSpec.toComponentName(((ObjectNode) componentNode).getName()); + } + TypeDeclaration component = langSpec.newTypeDeclaration(componentName); + + // Declare the constructor and the fields to refer to other resources (to the callee components). + MethodDeclaration constructor = null; + List depends = new ArrayList<>(); + if (componentNode instanceof ResourceNode) { + // For data-flow graph + constructor = declareConstructorAndFieldsToReferToResources((ResourceNode) componentNode, component, depends, langSpec); + } else if (componentNode instanceof ObjectNode) { + // For control-flow graph + constructor = declareConstructorAndFieldsToCalleeComponents((ObjectNode) componentNode, component, depends, langSpec); + } + + // Update the main component for this component. + updateMainComponent(mainComponent, mainConstructor, componentNode, depends, langSpec); + + if (componentNode instanceof ResourceNode || componentNode instanceof StatefulObjectNode) { + // For this resource. + ResourceNode resourceNode = null; + if (componentNode instanceof ResourceNode) { + // For data-flow graph + resourceNode = (ResourceNode) componentNode; + } else if (componentNode instanceof StatefulObjectNode) { + // For control-flow graph + resourceNode = ((StatefulObjectNode) componentNode).getResource(); + } + IdentifierTemplate resId = resourceNode.getIdentifierTemplate(); + Type resStateType = resId.getResourceStateType(); + + // Declare the field in this resource to store the state. + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + FieldDeclaration stateField = langSpec.newFieldDeclaration(resStateType, fieldOfResourceState, langSpec.getFieldInitializer(resStateType, resId.getInitialValue())); + component.addField(stateField); + } + + // Declare the getter method in this resource to obtain the state. + MethodDeclaration getter = declareGetterMethod(resourceNode, component, resStateType, langSpec); + + // Declare the accessor method in the main component to call the getter method. + declareAccessorInMainComponent(mainComponent, resId, langSpec); + + // Declare the fields to refer to reference resources. + declareFieldsToReferenceResources(model, resourceNode, component, constructor, depends, langSpec); + + // Declare cache fields and update methods in this resource. + List updates = declareCacheFieldsAndUpdateMethods(resourceNode, component, langSpec); + + // Declare input methods in this component and the main component. + List inputs = declareInputMethodsInThisAndMainComponents(resourceNode, component, mainComponent, model, langSpec); + } + if (constructor.getParameters() == null) { + component.removeMethod(constructor); + } + + // Add compilation unit for this component. + CompilationUnit cu = langSpec.newCompilationUnit(component); + codes.add(cu); + } + + return codes; + } + + private static ArrayList determineComponentOrder(IFlowGraph graph) { + ArrayList objects = new ArrayList<>(); + Set visited = new HashSet<>(); + Set allNodes = graph.getAllNodes(); + for (Node n: allNodes) { + if (!(n instanceof EntryPointObjectNode)) { + topologicalSort(allNodes, n, visited, objects); + } + } + return objects; + } + + private static void topologicalSort(Set allNodes, Node curNode, Set visited, List orderedList) { + if (visited.contains(curNode)) return; + visited.add(curNode); + // a caller is before the callee + for (Edge e: curNode.getInEdges()) { + if (!(e.getSource() instanceof EntryPointObjectNode)) { + topologicalSort(allNodes, e.getSource(), visited, orderedList); + } + } + // For reference resources. + ResourceNode cn = null; + if (curNode instanceof ResourceNode) { + cn = (ResourceNode) curNode; + } else if (curNode instanceof StatefulObjectNode) { + cn = ((StatefulObjectNode) curNode).getResource(); + } + if (cn != null) { + for (Node n: allNodes) { + ResourceNode rn = null; + if (n instanceof ResourceNode) { + rn = (ResourceNode) n; + } else if (n instanceof StatefulObjectNode) { + rn = ((StatefulObjectNode) n).getResource(); + } + if (rn != null) { + for (Edge e: rn.getOutEdges()) { + DataTransferChannelGenerator ch = ((DataFlowEdge) e).getChannelGenerator(); + for (ChannelMember m: ch.getReferenceChannelMembers()) { + if (m.getIdentifierTemplate() == cn.getIdentifierTemplate()) { + topologicalSort(allNodes, n, visited, orderedList); + } + } + } + } + } + } + orderedList.add(0, curNode); + } + + private static void updateMainComponent(TypeDeclaration mainType, MethodDeclaration mainConstructor, Node componentNode, List depends, ILanguageSpecific langSpec) { + // Declare the field to refer to each object in the main type. + String nodeName = null; + if (componentNode instanceof ResourceNode) { + nodeName = ((ResourceNode) componentNode).getIdentifierTemplate().getResourceName(); + } else if (componentNode instanceof ObjectNode) { + nodeName = ((ObjectNode) componentNode).getName(); + } + String componentName = langSpec.toComponentName(nodeName); + // Declare a field to refer each object. + if (langSpec.declareField()) { + FieldDeclaration refField = langSpec.newFieldDeclaration(new Type(componentName, componentName), nodeName); + mainType.addField(refField); + } + // Add a statement to instantiate each object to the main constructor. + List parameters = new ArrayList<>(); + for (IdentifierTemplate id: depends) { + // For the callee objects (the destination resource of push transfer or the source resource of pull transfer). + parameters.add(id.getResourceName()); + } + // For the refs, ToDo. + Block mainConstructorBody = mainConstructor.getBody(); + if (mainConstructorBody == null) { + mainConstructorBody = new Block(); + mainConstructor.setBody(mainConstructorBody); + } + mainConstructorBody.addStatement(langSpec.getFieldAccessor(nodeName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(componentName, parameters) + langSpec.getStatementDelimiter()); + } + + private static MethodDeclaration declareConstructorAndFieldsToReferToResources(ResourceNode resourceNode, TypeDeclaration component, + List depends, ILanguageSpecific langSpec) { + // Declare a constructor in each component. + MethodDeclaration constructor = component.createConstructor(); + Block block = new Block(); + constructor.setBody(block); + + // Declare fields in each component. (for data-flow graph) + for (Edge e: resourceNode.getOutEdges()) { + if (((PushPullAttribute) ((DataFlowEdge) e).getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + // for PUSH transfer + addReference(component, constructor, e.getDestination(), langSpec); + IdentifierTemplate dstId = ((ResourceNode) e.getDestination()).getIdentifierTemplate(); + if (!depends.contains(dstId)) depends.add(dstId); + } + } + for (Edge e: resourceNode.getInEdges()) { + if (((PushPullAttribute) ((DataFlowEdge) e).getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { + // for PULL transfer + addReference(component, constructor, e.getSource(), langSpec); + IdentifierTemplate srcId = ((ResourceNode) e.getSource()).getIdentifierTemplate(); + if (!depends.contains(srcId)) depends.add(srcId); + } + } + return constructor; + } + + private static MethodDeclaration declareConstructorAndFieldsToCalleeComponents(ObjectNode componentNode, TypeDeclaration component, + List depends, ILanguageSpecific langSpec) { + // Declare a constructor in each component. + MethodDeclaration constructor = component.createConstructor(); + Block block = new Block(); + constructor.setBody(block); + + // Declare fields in each component. (for control-flow graph) + for (Edge e: componentNode.getOutEdges()) { + ObjectNode dstNode = (ObjectNode) e.getDestination(); + addReference(component, constructor, dstNode, langSpec); + if (dstNode instanceof StatefulObjectNode) { + IdentifierTemplate dstId = ((StatefulObjectNode) dstNode).getResource().getIdentifierTemplate(); + if (!depends.contains(dstId)) depends.add(dstId); + } + } + return constructor; + } + + private static void addReference(TypeDeclaration component, MethodDeclaration constructor, Node dstNode, ILanguageSpecific langSpec) { + String dstNodeName = null; + if (dstNode instanceof ResourceNode) { + dstNodeName = ((ResourceNode) dstNode).getIdentifierTemplate().getResourceName(); + } else if (dstNode instanceof ObjectNode) { + dstNodeName = ((ObjectNode) dstNode).getName(); + } + String dstComponentName = langSpec.toComponentName(dstNodeName); + if (langSpec.declareField()) { + // Declare a field to refer to another component. + component.addField(langSpec.newFieldDeclaration(new Type(dstComponentName, dstComponentName), dstNodeName)); + } + // Initialize the field to refer to another component. + constructor.addParameter(langSpec.newVariableDeclaration(new Type(dstComponentName, dstComponentName), dstNodeName)); + constructor.getBody().addStatement(langSpec.getFieldAccessor(dstNodeName) + langSpec.getAssignment() + dstNodeName + langSpec.getStatementDelimiter()); + } + + private static MethodDeclaration declareGetterMethod(ResourceNode resourceNode, TypeDeclaration component, Type resStateType, ILanguageSpecific langSpec) { + // Declare the getter method of the resource state. + MethodDeclaration getter = langSpec.newMethodDeclaration(getterOfResourceState, resStateType); + component.addMethod(getter); + + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + // returns the state field when all incoming data-flow edges are PUSH-style. + if (langSpec.isValueType(resStateType)) { + getter.addStatement(langSpec.getReturnStatement(langSpec.getFieldAccessor(fieldOfResourceState)) + langSpec.getStatementDelimiter()); // return value; + } else { + // copy the current state to be returned as a 'value' + String implTypeName = resStateType.getImplementationTypeName(); +// String interfaceTypeName = resourceType.getInterfaceTypeName(); +// String concreteTypeName; +// if (interfaceTypeName.contains("<")) { +// String typeName = implTypeName.substring(0, implTypeName.indexOf("<")); +//// String generics = interfaceTypeName.substring(interfaceTypeName.indexOf("<") + 1, interfaceTypeName.lastIndexOf(">")); +// concreteTypeName = typeName + "<>"; +// } else { +// concreteTypeName = implTypeName; +// } + List parameters = new ArrayList<>(); + parameters.add(langSpec.getFieldAccessor(fieldOfResourceState)); + getter.addStatement(langSpec.getReturnStatement(langSpec.getConstructorInvocation(implTypeName, parameters)) + langSpec.getStatementDelimiter()); // return new Resource(value); + } + } else { + // invocations to other getter methods when at least one incoming data-flow edges is PULL-style. + boolean isContainedPush = false; + DataTransferChannelGenerator ch = null; + HashMap inputIdentifierToStateAccessor = new HashMap<>(); + for (Edge eIn: resourceNode.getInEdges()) { + DataFlowEdge dIn = (DataFlowEdge) eIn; + if (((PushPullAttribute) dIn.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + // PUSH transfer + isContainedPush = true; + inputIdentifierToStateAccessor.put(((ResourceNode) dIn.getSource()).getIdentifierTemplate(), langSpec.getPushAccessor()); + } else { + // PULL transfer + inputIdentifierToStateAccessor.put(((ResourceNode) dIn.getSource()).getIdentifierTemplate(), langSpec.getPullAccessor()); + ch = dIn.getChannelGenerator(); + } + } +// // for reference channel members, ToDo. +// for (ChannelMember c: d.getChannelGenerator().getReferenceChannelMembers()) { +// inputIdentifierToStateAccessor.put(c.getIdentifierTemplate(), langSpec.getPullAccessor()); // by pull data transfer +// } + + // generate a return statement. + try { + for (ChannelMember out: ch.getOutputChannelMembers()) { + if (out.getIdentifierTemplate() == resourceNode.getIdentifierTemplate()) { + String[] sideEffects = new String[] {""}; + if (!isContainedPush) { + // All incoming edges are in PULL-style. + String curState = ch.deriveUpdateExpressionOf(out, langSpec.getPullAccessor()).toImplementation(sideEffects); + getter.addStatement(sideEffects[0] + langSpec.getReturnStatement(curState) + langSpec.getStatementDelimiter()); + } else { + // At least one incoming edge is in PUSH-style. + String curState = ch.deriveUpdateExpressionOf(out, langSpec.getPullAccessor(), inputIdentifierToStateAccessor).toImplementation(sideEffects); + getter.addStatement(sideEffects[0] + langSpec.getReturnStatement(curState) + langSpec.getStatementDelimiter()); + } + break; + } + } + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { + e.printStackTrace(); + } + } + + return getter; + } + + private static void declareAccessorInMainComponent(TypeDeclaration mainComponent, IdentifierTemplate accessResId, ILanguageSpecific langSpec) { + MethodDeclaration getter = new MethodDeclaration("get" + langSpec.toComponentName(accessResId.getResourceName()), accessResId.getResourceStateType()); + Block block = new Block(); + block.addStatement(langSpec.getReturnStatement(langSpec.getMethodInvocation(accessResId.getResourceName(), getterOfResourceState)) + langSpec.getStatementDelimiter()); + getter.setBody(block); + mainComponent.addMethod(getter); + } + + private static void declareFieldsToReferenceResources(DataTransferModel model, ResourceNode resourceNode, TypeDeclaration component, MethodDeclaration constructor, + List depends, ILanguageSpecific langSpec) { + Set refs = new HashSet<>(); + for (ChannelGenerator ch : model.getChannelGenerators()) { + DataTransferChannelGenerator c = (DataTransferChannelGenerator) ch; + if (c.getInputIdentifierTemplates().contains(resourceNode.getIdentifierTemplate())) { + for (IdentifierTemplate id: c.getReferenceIdentifierTemplates()) { + if (!refs.contains(id) && !depends.contains(id)) { + refs.add(id); + String refResName = langSpec.toComponentName(id.getResourceName()); + component.addField(langSpec.newFieldDeclaration(new Type(refResName, refResName), id.getResourceName())); + constructor.addParameter(langSpec.newVariableDeclaration(new Type(refResName, refResName), id.getResourceName())); + constructor.getBody().addStatement(langSpec.getFieldAccessor(id.getResourceName()) + langSpec.getAssignment() + id.getResourceName() + langSpec.getStatementDelimiter()); + } + } + } + } + } + + private static List declareCacheFieldsAndUpdateMethods(ResourceNode resourceNode, TypeDeclaration component, ILanguageSpecific langSpec) { + // Declare cash fields and update methods in the component. + String resComponentName = langSpec.toComponentName(resourceNode.getIdentifierTemplate().getResourceName()); + List updateMethods = new ArrayList<>(); + for (Edge e: resourceNode.getInEdges()) { + DataFlowEdge re = (DataFlowEdge) e; + IdentifierTemplate srcRes = ((ResourceNode) re.getSource()).getIdentifierTemplate(); + String srcResName = srcRes.getResourceName(); + String srcResComponentName = langSpec.toComponentName(srcResName); + if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + // for push data transfer + + // Declare an update method in the type of the destination resource. + ArrayList vars = new ArrayList<>(); + vars.add(langSpec.newVariableDeclaration(srcRes.getResourceStateType(), srcRes.getResourceName())); + // For the refs, ToDo. +// DataTransferChannelGenerator c = (DataTransferChannelGenerator) re.getChannelGenerator(); +// for (IdentifierTemplate ref: c.getReferenceIdentifierTemplates()) { +// if (ref != rn.getIdentifierTemplate()) { +// vars.add(langSpec.newVariableDeclaration(ref.getResourceStateType(), ref.getResourceName())); +// } +// } + MethodDeclaration update = langSpec.newMethodDeclaration(updateMethodName + srcResComponentName, false, null, vars); + component.addMethod(update); + updateMethods.add(update); + + // Add a statement to update the state field + if (((StoreAttribute) resourceNode.getAttribute()).isStored()) { + try { + for (ChannelMember out: re.getChannelGenerator().getOutputChannelMembers()) { + if (out.getIdentifierTemplate() == resourceNode.getIdentifierTemplate()) { + Expression updateExp = re.getChannelGenerator().deriveUpdateExpressionOf(out, langSpec.getPushAccessor()); + String[] sideEffects = new String[] {""}; + String curState = updateExp.toImplementation(sideEffects); + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + } else { + updateStatement = sideEffects[0] + langSpec.getFieldAccessor(fieldOfResourceState) + langSpec.getAssignment() + curState + langSpec.getStatementDelimiter(); // this.value = ... + } + if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { + update.addFirstStatement(updateStatement); + } + break; + } + } + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e1) { + e1.printStackTrace(); + } + } + + // Declare the field to cache the state of the source resource in the type of the destination resource. + if (resourceNode.getIndegree() > 1) { + // If incoming edges are multiple + if (langSpec.declareField()) { + // Declare the cache field. + FieldDeclaration cacheField = langSpec.newFieldDeclaration( + srcRes.getResourceStateType(), + srcRes.getResourceName(), + langSpec.getFieldInitializer(srcRes.getResourceStateType(), srcRes.getInitialValue())); + component.addField(cacheField); + + } + // Update the cache field. + String cashStatement = langSpec.getFieldAccessor(srcResName) + langSpec.getAssignment() + srcResName + langSpec.getStatementDelimiter(); + if (update.getBody() == null || !update.getBody().getStatements().contains(cashStatement)) { + update.addFirstStatement(cashStatement); + } + } + + // Add an invocation to another update method (for a chain of update method invocations). + for (Edge eOut: resourceNode.getOutEdges()) { + DataFlowEdge dOut = (DataFlowEdge) eOut; + if (((PushPullAttribute) dOut.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + // PUSH transfer + Map> referredResources = new HashMap<>(); + List params = new ArrayList<>(); + params.add(langSpec.getFieldAccessor(fieldOfResourceState)); + Set referredSet = referredResources.get(update); + for (ChannelMember rc: re.getChannelGenerator().getReferenceChannelMembers()) { + // to get the value of reference member. + IdentifierTemplate ref = rc.getIdentifierTemplate(); + if (referredSet == null) { + referredSet = new HashSet<>(); + referredResources.put(update, referredSet); + } + if (ref != resourceNode.getIdentifierTemplate()) { + String refVarName = ref.getResourceName(); + if (!referredSet.contains(ref)) { + referredSet.add(ref); + Expression refGetter = langSpec.getPullAccessor().getCurrentStateAccessorFor(ref, ((ResourceNode) dOut.getSource()).getIdentifierTemplate()); + String[] sideEffects = new String[] {""}; + String refExp = refGetter.toImplementation(sideEffects); + String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); + update.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); + } + params.add(refVarName); + } + } + update.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(((ResourceNode) dOut.getDestination()).getIdentifierTemplate().getResourceName()), + updateMethodName + resComponentName, + params) + langSpec.getStatementDelimiter()); // this.dst.updateSrc(value, refParams); + } + } + } + } + return updateMethods; + } + + private static List declareInputMethodsInThisAndMainComponents(ResourceNode resourceNode, TypeDeclaration component, + TypeDeclaration mainComponent, DataTransferModel model, ILanguageSpecific langSpec) { + // Declare input methods. + String resName = resourceNode.getIdentifierTemplate().getResourceName(); + String resComponentName = langSpec.toComponentName(resName); + List inputMethods = new ArrayList<>(); + for (ChannelGenerator ch : model.getIOChannelGenerators()) { + for (ChannelMember out : ((DataTransferChannelGenerator) ch).getOutputChannelMembers()) { + if (out.getIdentifierTemplate().equals(resourceNode.getIdentifierTemplate())) { + Expression message = out.getStateTransition().getMessageExpression(); + MethodDeclaration input = null; + MethodDeclaration mainInput = null; + if (message instanceof Term) { + // Declare an input method in this component. + ArrayList params = new ArrayList<>(); + for (Variable var: message.getVariables().values()) { + params.add(langSpec.newVariableDeclaration(var.getType(), var.getName())); + } + input = langSpec.newMethodDeclaration(((Term) message).getSymbol().getImplName(), false, null, params); + component.addMethod(input); + inputMethods.add(input); + + // Declare the accessor in the main component to call the input method. + String str = ((Term) message).getSymbol().getImplName(); + mainInput = getMethod(mainComponent, str); + if (mainInput == null) { + mainInput = langSpec.newMethodDeclaration(str, false, null, params); + mainComponent.addMethod(mainInput); + } else { + // Add type to a parameter without type. + for (VariableDeclaration param: mainInput.getParameters()) { + if (param.getType() == null) { + for (VariableDeclaration p: params) { + if (param.getName().equals(p.getName()) && p.getType() != null) { + param.setType(p.getType()); + } + } + } + } + } + } else if (message instanceof Variable) { + // Declare an input method in this component. + input = langSpec.newMethodDeclaration(((Variable) message).getName(), null); + component.addMethod(input); + inputMethods.add(input); + String str = ((Variable) message).getName(); + + // Declare the accessor in the main component to call the input method. + mainInput = getMethod(mainComponent, str); + if (mainInput == null) { + mainInput = langSpec.newMethodDeclaration(str, null); + mainComponent.addMethod(mainInput); + } + } + + // Add an invocation to the accessor method. + if (mainInput != null) { + List args = new ArrayList<>(); + if (message instanceof Term) { + for (Variable var: message.getVariables().values()) { + args.add(var.getName()); + } + } + mainInput.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(resName), input.getName(), args) + langSpec.getStatementDelimiter()); + } + + if (input != null) { + // Add a statement to update the state field to the input method. + try { + String[] sideEffects = new String[] {""}; + Expression updateExp; + updateExp = ((DataTransferChannelGenerator) ch).deriveUpdateExpressionOf(out, langSpec.getPullAccessor()); + String newState = updateExp.toImplementation(sideEffects); + String updateStatement; + if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { + updateStatement = sideEffects[0]; + } else { + updateStatement = sideEffects[0] + langSpec.getFieldAccessor(fieldOfResourceState) + langSpec.getAssignment() + newState + langSpec.getStatementDelimiter(); + } + input.addFirstStatement(updateStatement); + } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork + | InvalidMessage | UnificationFailed | ValueUndefined e) { + e.printStackTrace(); + } + + // Add an invocation to an update method (for a chain of update method invocations). + for (Edge eOut: resourceNode.getOutEdges()) { + DataFlowEdge dOut = (DataFlowEdge) eOut; + if (((PushPullAttribute) dOut.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { + // PUSH transfer + Map> referredResources = new HashMap<>(); + List params = new ArrayList<>(); + params.add(langSpec.getFieldAccessor(fieldOfResourceState)); + Set referredSet = referredResources.get(input); + for (ChannelMember rc: ((DataTransferChannelGenerator) ch).getReferenceChannelMembers()) { + // to get the value of reference member. + IdentifierTemplate ref = rc.getIdentifierTemplate(); + if (referredSet == null) { + referredSet = new HashSet<>(); + referredResources.put(input, referredSet); + } + if (ref != resourceNode.getIdentifierTemplate()) { + String refVarName = ref.getResourceName(); + if (!referredSet.contains(ref)) { + referredSet.add(ref); + Expression refGetter = langSpec.getPullAccessor().getCurrentStateAccessorFor(ref, ((ResourceNode) dOut.getSource()).getIdentifierTemplate()); + String[] sideEffects = new String[] {""}; + String refExp = refGetter.toImplementation(sideEffects); + String refTypeName = ref.getResourceStateType().getInterfaceTypeName(); + input.addFirstStatement(sideEffects[0] + langSpec.getVariableDeclaration(refTypeName, refVarName) + langSpec.getAssignment() + refExp + langSpec.getStatementDelimiter()); + } + params.add(refVarName); + } + } + input.addStatement(langSpec.getMethodInvocation(langSpec.getFieldAccessor(((ResourceNode) dOut.getDestination()).getIdentifierTemplate().getResourceName()), + updateMethodName + resComponentName, + params) + langSpec.getStatementDelimiter()); // this.dst.updateSrc(value, refParams); + } + } + } + } + } + } + return inputMethods; + } + + private static MethodDeclaration getMethod(TypeDeclaration component, String methodName) { + for (MethodDeclaration m: component.getMethods()) { + if (m.getName().equals(methodName)) return m; + } + return null; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/generators/ILanguageSpecific.java b/AlgebraicDataflowArchitectureModel/src/generators/ILanguageSpecific.java new file mode 100644 index 0000000..3b4f817 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/generators/ILanguageSpecific.java @@ -0,0 +1,38 @@ +package generators; + +import java.util.ArrayList; +import java.util.List; + +import code.ast.CompilationUnit; +import code.ast.FieldDeclaration; +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import code.ast.VariableDeclaration; +import models.algebra.Expression; +import models.algebra.Type; +import models.dataFlowModel.DataTransferChannelGenerator.IResourceStateAccessor; + +public interface ILanguageSpecific { + CompilationUnit newCompilationUnit(TypeDeclaration component); + TypeDeclaration newTypeDeclaration(String typeName); + VariableDeclaration newVariableDeclaration(Type type, String varName); + MethodDeclaration newMethodDeclaration(String methodName, Type returnType); + MethodDeclaration newMethodDeclaration(String methodName, boolean isConstructor, Type returnType, ArrayList parameters); + FieldDeclaration newFieldDeclaration(Type fieldType, String fieldName); + FieldDeclaration newFieldDeclaration(Type fieldType, String fieldName, String fieldInitializer); + String getVariableDeclaration(String typeName, String varName); + String getFieldInitializer(Type type, Expression initialValue); + boolean declareField(); + String getFieldAccessor(String fieldName); + String getMethodInvocation(String receivertName, String methodName); + String getMethodInvocation(String receivertName, String methodName, List parameters); + String getConstructorInvocation(String componentName, List parameters); + String getReturnStatement(String returnValue); + String toComponentName(String name); + String getMainComponentName(); + String getAssignment(); + String getStatementDelimiter(); + boolean isValueType(Type resStateType); + IResourceStateAccessor getPushAccessor(); + IResourceStateAccessor getPullAccessor(); +} diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java index 74ed6a8..5af38f1 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java @@ -76,8 +76,7 @@ // For each resource. for (ResourceNode rn: resources) { boolean f = false; - String resourceName = rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() - + rn.getIdentifierTemplate().getResourceName().substring(1); + String resourceName = toTypeName(rn.getIdentifierTemplate().getResourceName()); TypeDeclaration type = new TypeDeclaration(resourceName); // Declare the field to refer to each resource in the main type. @@ -86,7 +85,7 @@ for (Edge e : rn.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) e; IdentifierTemplate dstRes = ((ResourceNode) re.getDestination()).getIdentifierTemplate(); - String resName = dstRes.getResourceName().substring(0, 1).toUpperCase() + dstRes.getResourceName().substring(1); + String resName = toTypeName(dstRes.getResourceName()); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { depends.add(dstRes); fieldInitializer += resName.toLowerCase() + ","; @@ -96,17 +95,16 @@ for (Edge e : rn.getInEdges()) { DataFlowEdge re = (DataFlowEdge) e; IdentifierTemplate srcRes = ((ResourceNode) re.getSource()).getIdentifierTemplate(); - String resName = srcRes.getResourceName().substring(0, 1).toUpperCase() + srcRes.getResourceName().substring(1); + String resName = toTypeName(srcRes.getResourceName()); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { depends.add(srcRes); fieldInitializer += resName.toLowerCase() + ","; f = true; } else { if (rn.getIndegree() > 1) { - // Declare a field to cash the state of the source resource in the type of the destination resource. - IdentifierTemplate cashResId = ((ResourceNode) re.getSource()).getIdentifierTemplate(); - type.addField(new FieldDeclaration( - cashResId.getResourceStateType(), ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName(), getInitializer(cashResId))); + // Declare a field to cache the state of the source resource in the type of the destination resource. + IdentifierTemplate cacheResId = ((ResourceNode) re.getSource()).getIdentifierTemplate(); + type.addField(new FieldDeclaration(cacheResId.getResourceStateType(), cacheResId.getResourceName(), getInitializer(cacheResId))); } } } @@ -128,12 +126,14 @@ fieldInitializer += ")"; FieldDeclaration field = new FieldDeclaration(new Type(resourceName, resourceName), rn.getIdentifierTemplate().getResourceName()); mainType.addField(field); - Block manConstructorBody = mainConstructor.getBody(); - if (manConstructorBody == null) { - manConstructorBody = new Block(); - mainConstructor.setBody(manConstructorBody); + + // Add a statement to instantiate each object to the main constructor. + Block mainConstructorBody = mainConstructor.getBody(); + if (mainConstructorBody == null) { + mainConstructorBody = new Block(); + mainConstructor.setBody(mainConstructorBody); } - manConstructorBody.addStatement(rn.getIdentifierTemplate().getResourceName() + " = " + fieldInitializer + ";"); + mainConstructorBody.addStatement(rn.getIdentifierTemplate().getResourceName() + " = " + fieldInitializer + ";"); // Declare a constructor, fields and update methods in the type of each resource. MethodDeclaration constructor = new MethodDeclaration(resourceName, true); @@ -142,7 +142,7 @@ for (Edge e : rn.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) e; IdentifierTemplate dstRes = ((ResourceNode) re.getDestination()).getIdentifierTemplate(); - String dstResName = dstRes.getResourceName().substring(0, 1).toUpperCase() + dstRes.getResourceName().substring(1); + String dstResName = toTypeName(dstRes.getResourceName()); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) { // Declare a field to refer to the destination resource of push transfer. depends.add(dstRes); @@ -154,7 +154,7 @@ for (Edge e : rn.getInEdges()) { DataFlowEdge re = (DataFlowEdge) e; IdentifierTemplate srcRes = ((ResourceNode) re.getSource()).getIdentifierTemplate(); - String srcResName = srcRes.getResourceName().substring(0, 1).toUpperCase() + srcRes.getResourceName().substring(1); + String srcResName = toTypeName(srcRes.getResourceName()); if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) { // Declare a field to refer to the source resource of pull transfer. depends.add(srcRes); @@ -183,7 +183,7 @@ if (!refs.contains(id) && !depends.contains(id)) { refs.add(id); String refResName = id.getResourceName(); - refResName = refResName.substring(0, 1).toUpperCase() + refResName.substring(1); + refResName = toTypeName(refResName); type.addField(new FieldDeclaration(new Type(refResName, refResName), id.getResourceName())); constructor.addParameter(new VariableDeclaration(new Type(refResName, refResName), id.getResourceName())); block.addStatement("this." + id.getResourceName() + " = " + id.getResourceName() + ";"); @@ -200,16 +200,16 @@ for (ChannelMember cm : ((DataTransferChannelGenerator) cg).getOutputChannelMembers()) { if (cm.getIdentifierTemplate().equals(rn.getIdentifierTemplate())) { Expression message = cm.getStateTransition().getMessageExpression(); - if (message.getClass() == Term.class) { + if (message instanceof Term) { ArrayList params = new ArrayList<>(); for (Variable var: message.getVariables().values()) { params.add(new VariableDeclaration(var.getType(), var.getName())); } MethodDeclaration input = new MethodDeclaration( - ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(), + ((Term) message).getSymbol().getImplName(), false, typeVoid, params); type.addMethod(input); - String str = ((Term) cm.getStateTransition().getMessageExpression()).getSymbol().getImplName(); + String str = ((Term) message).getSymbol().getImplName(); input = getMethod(mainType, str); if (input == null) { input = new MethodDeclaration(str, false, typeVoid, params); @@ -226,15 +226,13 @@ } } } - } else if (message.getClass() == Variable.class) { - MethodDeclaration input = new MethodDeclaration( - ((Variable) cm.getStateTransition().getMessageExpression()).getName(), - false, typeVoid, null); + } else if (message instanceof Variable) { + MethodDeclaration input = new MethodDeclaration(((Variable) message).getName(), typeVoid); type.addMethod(input); - String str = ((Variable) cm.getStateTransition().getMessageExpression()).getName(); + String str = ((Variable) message).getName(); input = getMethod(mainType, str); if (input == null) { - input = new MethodDeclaration(str, false, typeVoid, null); + input = new MethodDeclaration(str, typeVoid); mainType.addMethod(input); } } @@ -278,7 +276,7 @@ for(FieldDeclaration field : type.getFields()) { MethodDeclaration getter = new MethodDeclaration( - "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1), + "get" + toTypeName(field.getName()), new Type("Double","T")); getter.setBody(new Block()); getter.getBody().addStatement("return " + field.getName() + ";"); @@ -297,8 +295,7 @@ for (Node n : graph.getNodes()) { ResourceNode rn = (ResourceNode) n; MethodDeclaration getter = new MethodDeclaration( - "get" + rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() - + rn.getIdentifierTemplate().getResourceName().substring(1), + "get" + toTypeName(rn.getIdentifierTemplate().getResourceName()), rn.getIdentifierTemplate().getResourceStateType()); getter.setBody(new Block()); getter.getBody().addStatement( @@ -306,7 +303,7 @@ mainType.addMethod(getter); } - + // ????? HashSet tmps = new HashSet<>(); HashSet cont = new HashSet<>(); for (MethodDeclaration method : mainType.getMethods()) { @@ -317,23 +314,26 @@ } for (MethodDeclaration method : mainType.getMethods()) { if (cont.contains(method.getName())) { - method.setName(method.getName() + method.getParameters().get(0).getName().substring(0, 1).toUpperCase() - + method.getParameters().get(0).getName().substring(1)); + method.setName(method.getName() + toTypeName(method.getParameters().get(0).getName())); } } return codes; } - private static String getInitializer(IdentifierTemplate resId) { + private static String toTypeName(String resName) { + return resName.substring(0, 1).toUpperCase() + resName.substring(1); + } + + static private String getInitializer(IdentifierTemplate resId) { Type stateType = resId.getResourceStateType(); String initializer = null; if (resId.getInitialValue() != null) { initializer = resId.getInitialValue().toImplementation(new String[] {""}); } else { if (DataConstraintModel.typeList.isAncestorOf(stateType)) { - initializer = "new " + resId.getResourceStateType().getImplementationTypeName() + "()"; + initializer = "new " + stateType.getImplementationTypeName() + "()"; } else if (DataConstraintModel.typeMap.isAncestorOf(stateType)) { - initializer = "new " + resId.getResourceStateType().getImplementationTypeName() + "()"; + initializer = "new " + stateType.getImplementationTypeName() + "()"; } } return initializer; diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java index ec17706..a6f7dd8 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java @@ -79,7 +79,7 @@ } } if (dst.getIndegree() > 1) { - // update a cash of src side resource (when incoming edges are multiple) + // update a cache of src side resource (when incoming edges are multiple) String cashStatement = "this." + srcResourceName + " = " + srcResourceName + ";"; if (update.getBody() == null || !update.getBody().getStatements().contains(cashStatement)) { update.addFirstStatement(cashStatement); diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JavaSpecific.java b/AlgebraicDataflowArchitectureModel/src/generators/JavaSpecific.java new file mode 100644 index 0000000..ac4715c --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/generators/JavaSpecific.java @@ -0,0 +1,224 @@ +package generators; + +import java.util.ArrayList; +import java.util.List; + +import code.ast.CompilationUnit; +import code.ast.FieldDeclaration; +import code.ast.ImportDeclaration; +import code.ast.MethodDeclaration; +import code.ast.TypeDeclaration; +import code.ast.VariableDeclaration; +import models.algebra.Expression; +import models.algebra.Field; +import models.algebra.Parameter; +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.Type; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataTransferChannelGenerator.IResourceStateAccessor; + +public class JavaSpecific implements ILanguageSpecific { + public static final Type typeVoid = new Type("Void", "void"); + + @Override + public CompilationUnit newCompilationUnit(TypeDeclaration component) { + CompilationUnit cu = new CompilationUnit(component); + cu.addImport(new ImportDeclaration("java.util.*")); + return cu; + } + + @Override + public TypeDeclaration newTypeDeclaration(String typeName) { + return new TypeDeclaration(typeName); + } + + @Override + public VariableDeclaration newVariableDeclaration(Type type, String varName) { + return new VariableDeclaration(type, varName); + } + + @Override + public MethodDeclaration newMethodDeclaration(String methodName, Type returnType) { + if (returnType == null) { + returnType = typeVoid; + } + return new MethodDeclaration(methodName, returnType); + } + + @Override + public MethodDeclaration newMethodDeclaration(String methodName, boolean isConstructor, Type returnType, ArrayList parameters) { + if (returnType == null) { + returnType = typeVoid; + } + return new MethodDeclaration(methodName, isConstructor, returnType, parameters); + } + + @Override + public FieldDeclaration newFieldDeclaration(Type fieldType, String fieldName) { + return new FieldDeclaration(fieldType, fieldName); + } + + @Override + public FieldDeclaration newFieldDeclaration(Type fieldType, String fieldName, String fieldInitializer) { + return new FieldDeclaration(fieldType, fieldName, fieldInitializer); + } + + + @Override + public String getVariableDeclaration(String typeName, String varName) { + return typeName + " " + varName; + } + + @Override + public String getFieldInitializer(Type type, Expression initialValue) { + String initializer = null; + if (initialValue != null) { + initializer = initialValue.toImplementation(new String[] {""}); + } else { + if (DataConstraintModel.typeList.isAncestorOf(type)) { + initializer = "new " + type.getImplementationTypeName() + "()"; + } else if (DataConstraintModel.typeMap.isAncestorOf(type)) { + initializer = "new " + type.getImplementationTypeName() + "()"; + } + } + return initializer; + } + + @Override + public boolean declareField() { + return true; + } + + @Override + public String getFieldAccessor(String fieldName) { + return "this." + fieldName; + } + + @Override + public String getMethodInvocation(String receiverName, String methodName) { + return receiverName + "." + methodName + "()"; + } + + @Override + public String getMethodInvocation(String receiverName, String methodName, List parameters) { + if (parameters == null) return getMethodInvocation(receiverName, methodName); + String invocation = receiverName + "." + methodName + "("; + if (parameters.size() > 0) { + for (int i = 0; i < parameters.size(); i++) { + if (i < parameters.size() - 1) { + invocation += parameters.get(i) + ", "; + } else { + invocation += parameters.get(i); + } + } + } + invocation += ")"; + return invocation; + } + + @Override + public String getConstructorInvocation(String componentName, List parameters) { + String invocation = "new " + componentName + "("; + if (parameters.size() > 0) { + for (int i = 0; i < parameters.size(); i++) { + if (i < parameters.size() - 1) { + invocation += parameters.get(i) + ", "; + } else { + invocation += parameters.get(i); + } + } + } + invocation += ")"; + return invocation; + } + + @Override + public String getReturnStatement(String returnValue) { + return "return " + returnValue; + } + + @Override + public String toComponentName(String name) { + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + + @Override + public String getMainComponentName() { + return "Main"; + } + + @Override + public String getAssignment() { + return " = "; + } + + @Override + public String getStatementDelimiter() { + return ";"; + } + + @Override + public boolean isValueType(Type type) { + if (type == DataConstraintModel.typeInt + || type == DataConstraintModel.typeLong + || type == DataConstraintModel.typeFloat + || type == DataConstraintModel.typeDouble + || type == DataConstraintModel.typeBoolean) { + return true; + } + return false; + } + + @Override + public IResourceStateAccessor getPushAccessor() { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + if (target.equals(from)) { + return new Field(CodeGenerator.fieldOfResourceState, + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + return new Parameter(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + + @Override + public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + return new Parameter(target.getResourceName(), + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + }; + } + + @Override + public IResourceStateAccessor getPullAccessor() { + return new IResourceStateAccessor() { + @Override + public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + if (target.equals(from)) { + return new Field(CodeGenerator.fieldOfResourceState, + target.getResourceStateType() != null ? target.getResourceStateType() + : DataConstraintModel.typeInt); + } + // for reference channel member + Term getter = new Term(new Symbol(CodeGenerator.getterOfResourceState, 1, Symbol.Type.METHOD)); + getter.addChild(new Field(target.getResourceName(), target.getResourceStateType())); + return getter; + } + + @Override + public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { + Term getter = new Term(new Symbol(CodeGenerator.getterOfResourceState, 1, Symbol.Type.METHOD)); + getter.addChild(new Field(target.getResourceName(), target.getResourceStateType())); + return getter; + } + }; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractEditorAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractEditorAction.java deleted file mode 100644 index c473f18..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractEditorAction.java +++ /dev/null @@ -1,23 +0,0 @@ -package graphicalrefactor.actions; - -import javax.swing.AbstractAction; -import javax.swing.Icon; - -import com.mxgraph.view.mxGraph; - -import graphicalrefactor.editor.Editor; - -public abstract class AbstractEditorAction extends AbstractAction { - - protected Editor editor; - - public AbstractEditorAction(String name, Editor editor) { - super(name); - this.editor = editor; - } - - public void setEditor(Editor editor) { - this.editor = editor; - } - -} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractSystemAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractSystemAction.java deleted file mode 100644 index e3f827d..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractSystemAction.java +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 13c4a07..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/AbstractViewerAction.java +++ /dev/null @@ -1,17 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import javax.swing.AbstractAction; - -import com.mxgraph.swing.mxGraphComponent; - -public abstract class AbstractViewerAction extends AbstractAction { - - protected mxGraphComponent graphComponent = null; - - public AbstractViewerAction(String name, mxGraphComponent graphComponent) { - super(name); - this.graphComponent = graphComponent; - } -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/CircleLayoutAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/CircleLayoutAction.java deleted file mode 100644 index 07f3b7b..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/CircleLayoutAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import graphicalrefactor.editor.Editor; - -public class CircleLayoutAction extends AbstractEditorAction { - - public CircleLayoutAction(Editor editor) { - super("Circle Layout", editor); - } - - @Override - public void actionPerformed(ActionEvent e) { - editor.setCircleLayout(); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java deleted file mode 100644 index db8bb5d..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DAGLayoutAction.java +++ /dev/null @@ -1,17 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; -import graphicalrefactor.editor.Editor; - -public class DAGLayoutAction extends AbstractEditorAction { - - public DAGLayoutAction(Editor editor) { - super("DAG Layout", editor); - } - - @Override - public void actionPerformed(ActionEvent e) { - editor.setDAGLayout(); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DeleteAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DeleteAction.java deleted file mode 100644 index 1ac8a47..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/DeleteAction.java +++ /dev/null @@ -1,23 +0,0 @@ -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/ExitAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/ExitAction.java deleted file mode 100644 index c18a6c5..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/ExitAction.java +++ /dev/null @@ -1,22 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import javax.swing.AbstractAction; - -public class ExitAction extends AbstractAction { - /** - * - */ - private static final long serialVersionUID = -8733766417378036850L; - - public ExitAction() { - super("Exit"); - } - - @Override - public void actionPerformed(ActionEvent e) { - System.exit(0); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java deleted file mode 100644 index 60ca2f1..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java +++ /dev/null @@ -1,89 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; - -import javax.swing.JFileChooser; - -import algorithms.*; -import code.ast.*; -import generators.DataTransferMethodAnalyzer; -import generators.JavaCodeGenerator; -import generators.JavaMethodBodyGenerator; -import graphicalrefactor.editor.Editor; -import models.dataConstraintModel.IdentifierTemplate; -import models.dataFlowModel.DataTransferModel; -import models.dataFlowModel.ModelExtension; -import models.dataFlowModel.DataFlowGraph; - -public class JavaPrototypeGenerateAction extends AbstractEditorAction { - /** - * - */ - private static final long serialVersionUID = -3694103632055735068L; - - private String lastDir = null; - - public JavaPrototypeGenerateAction(Editor editor) { - super("Generate Plain Java Prototype", editor); - } - - @Override - public void actionPerformed(ActionEvent e) { - DataFlowGraph graph = editor.getDataFlowGraph(); - if (graph != null) { - DataTransferModel model = editor.getModel(); - ModelExtension.extendModel(model); - TypeInference.infer(model); - DataTransferMethodAnalyzer.decideToStoreResourceStates(graph); - String fileName = editor.getCurFileName(); - if (fileName == null) fileName = "Main"; - String mainTypeName = fileName.split("\\.")[0]; - boolean exist = false; - for (IdentifierTemplate id: model.getIdentifierTemplates()) { - String resourceName = id.getResourceName().substring(0, 1).toUpperCase() + id.getResourceName().substring(1); - if (mainTypeName.equals(resourceName)) { - exist = true; - } - } - if (!exist) { - JavaCodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. - } else { - JavaCodeGenerator.resetMainTypeName(); // use the default main type's name. - } - editor.setCodes(JavaMethodBodyGenerator.doGenerate(graph, model, JavaCodeGenerator.doGenerate(graph, model))); - ModelExtension.recoverModel(model); - for (CompilationUnit file : editor.getCodes()) { - System.out.println(file); - } - - String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); - JFileChooser fc = new JFileChooser(wd); - fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - int rc = fc.showSaveDialog(null); - if (rc == JFileChooser.APPROVE_OPTION) { - lastDir = fc.getSelectedFile().getPath(); - for (CompilationUnit cu : editor.getCodes()) { - save(fc.getSelectedFile(), cu); - } - } - } - } - - private void save(File dir, CompilationUnit cu) { - File javaFile = new File(dir.getPath(), cu.getFileName()); - try { - BufferedWriter writer = new BufferedWriter(new FileWriter(javaFile)); - writer.write(cu.toString()); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java deleted file mode 100644 index 083c690..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java +++ /dev/null @@ -1,90 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; - -import javax.swing.JFileChooser; - -import algorithms.*; -import code.ast.*; -import generators.DataTransferMethodAnalyzer; -import generators.JerseyCodeGenerator; -import generators.JerseyMethodBodyGenerator; -import graphicalrefactor.editor.Editor; -import models.algebra.Type; -import models.dataConstraintModel.IdentifierTemplate; -import models.dataFlowModel.DataTransferModel; -import models.dataFlowModel.ModelExtension; -import models.dataFlowModel.DataFlowGraph; - -public class JerseyPrototypeGenerateAction extends AbstractEditorAction { - /** - * - */ - private static final long serialVersionUID = 1117065654665887436L; - - private String lastDir = null; - - public JerseyPrototypeGenerateAction(Editor editor) { - super("Generate JAX-RS Prototype", editor); - } - - @Override - public void actionPerformed(ActionEvent e) { - DataFlowGraph graph = editor.getDataFlowGraph(); - if (graph != null) { - DataTransferModel model = editor.getModel(); - ModelExtension.extendModel(model); - TypeInference.infer(model); - DataTransferMethodAnalyzer.decideToStoreResourceStates(graph); - String fileName = editor.getCurFileName(); - if (fileName == null) fileName = "Main"; - String mainTypeName = fileName.split("\\.")[0]; - boolean exist = false; - for (IdentifierTemplate id: model.getIdentifierTemplates()) { - String resourceName = id.getResourceName().substring(0, 1).toUpperCase() + id.getResourceName().substring(1); - if (mainTypeName.equals(resourceName)) { - exist = true; - } - } - if (!exist) { - JerseyCodeGenerator.setMainTypeName(mainTypeName); // use model's file name as the main type's name. - } else { - JerseyCodeGenerator.resetMainTypeName(); // use the default main type's name. - } - editor.setCodes(JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model))); - ModelExtension.recoverModel(model); - for (CompilationUnit file : editor.getCodes()) { - System.out.println(file); - } - - String wd = (lastDir != null) ? lastDir : System.getProperty("user.dir"); - JFileChooser fc = new JFileChooser(wd); - fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - int rc = fc.showSaveDialog(null); - if (rc == JFileChooser.APPROVE_OPTION) { - lastDir = fc.getSelectedFile().getPath(); - for (CompilationUnit cu : editor.getCodes()) { - save(fc.getSelectedFile(), cu); - } - } - } - } - - private void save(File dir, CompilationUnit cu) { - File javaFile = new File(dir.getPath(), cu.getFileName()); - try { - BufferedWriter writer = new BufferedWriter(new FileWriter(javaFile)); - writer.write(cu.toString()); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewChannelAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewChannelAction.java deleted file mode 100644 index 9328f5f..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewChannelAction.java +++ /dev/null @@ -1,28 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import javax.swing.JOptionPane; - -import graphicalrefactor.editor.Editor; -import models.dataFlowModel.DataTransferChannelGenerator; - -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 DataTransferChannelGenerator(channelName)); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewFormulaChannelAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewFormulaChannelAction.java deleted file mode 100644 index 7fb9299..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewFormulaChannelAction.java +++ /dev/null @@ -1,62 +0,0 @@ -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 deleted file mode 100644 index 6b3bf66..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewIOChannelAction.java +++ /dev/null @@ -1,29 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import javax.swing.JOptionPane; - - -import graphicalrefactor.editor.Editor; -import models.dataFlowModel.DataTransferChannelGenerator; - -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 DataTransferChannelGenerator(channelName)); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewModelAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewModelAction.java deleted file mode 100644 index c79d868..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewModelAction.java +++ /dev/null @@ -1,24 +0,0 @@ -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 deleted file mode 100644 index 600daf7..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/NewResourceAction.java +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 2fcfe73..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/OpenAction.java +++ /dev/null @@ -1,62 +0,0 @@ -package graphicalrefactor.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 graphicalrefactor.editor.Editor; -import graphicalrefactor.views.GraphicalRefactor; - -public class OpenAction extends AbstractSystemAction { - /** - * - */ - private static final long serialVersionUID = -8290761032629599683L; - - private String lastDir = null; - - 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() { - - 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, "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 deleted file mode 100644 index 62f0609..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAction.java +++ /dev/null @@ -1,26 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import graphicalrefactor.editor.Editor; -import graphicalrefactor.views.GraphicalRefactor; - -public class SaveAction extends AbstractSystemAction { - /** - * - */ - private static final long serialVersionUID = 5660460585305281982L; - - public SaveAction(GraphicalRefactor frame) { - super("Save", frame); - } - - @Override - public void actionPerformed(ActionEvent e) { - 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 deleted file mode 100644 index d8ce78e..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/SaveAsAction.java +++ /dev/null @@ -1,79 +0,0 @@ -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"); - - // choose a file extension from a dialog. - if (rc == JFileChooser.APPROVE_OPTION) { - - // if extension filter is filled, then attaching extension by choosing filter. - // but if it's not filled, then using default extension name. - String extension = ""; - if(fc.getFileFilter() instanceof FileNameExtensionFilter) { - FileNameExtensionFilter selectedFilter = (FileNameExtensionFilter)fc.getFileFilter(); - extension = "." + selectedFilter.getExtensions()[0].toString(); - } - - lastDir = fc.getSelectedFile().getParent(); - - String fileName = fc.getSelectedFile().getAbsolutePath() + extension; - - // checking file duplicates - if(! (fc.getSelectedFile().exists())) editor.setCurFilePath(fileName); - - // overwriting file - editor.save(); - frame.setTitle(GraphicalRefactor.title + " - " + fc.getSelectedFile().getAbsolutePath()); - } - } - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/TreeLayoutAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/TreeLayoutAction.java deleted file mode 100644 index 1ce409f..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/TreeLayoutAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import graphicalrefactor.editor.Editor; - -public class TreeLayoutAction extends AbstractEditorAction { - - public TreeLayoutAction(Editor editor) { - super("Tree Layout", editor); - } - - @Override - public void actionPerformed(ActionEvent e) { - editor.setTreeLayout(); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/ZoomInAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/ZoomInAction.java deleted file mode 100644 index e2d1549..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/ZoomInAction.java +++ /dev/null @@ -1,28 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import javax.swing.AbstractAction; -import javax.swing.JOptionPane; - -import com.mxgraph.swing.mxGraphComponent; -import com.mxgraph.util.mxResources; - -import graphicalrefactor.editor.Editor; - -public class ZoomInAction extends AbstractViewerAction { - /** - * - */ - private static final long serialVersionUID = 6758532166946195926L; - - public ZoomInAction(mxGraphComponent graphComponent) { - super("Zoom In", graphComponent); - } - - @Override - public void actionPerformed(ActionEvent e) { - graphComponent.zoomIn(); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/ZoomOutAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/ZoomOutAction.java deleted file mode 100644 index 7518f38..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/ZoomOutAction.java +++ /dev/null @@ -1,26 +0,0 @@ -package graphicalrefactor.actions; - -import java.awt.event.ActionEvent; - -import javax.swing.AbstractAction; - -import com.mxgraph.swing.mxGraphComponent; - -import graphicalrefactor.editor.Editor; - -public class ZoomOutAction extends AbstractViewerAction { - /** - * - */ - private static final long serialVersionUID = 8657530769383486605L; - - public ZoomOutAction(mxGraphComponent graphComponent) { - super("Zoom Out", graphComponent); - } - - @Override - public void actionPerformed(ActionEvent e) { - graphComponent.zoomOut(); - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java deleted file mode 100644 index bc27ce5..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/editor/Editor.java +++ /dev/null @@ -1,667 +0,0 @@ -package graphicalrefactor.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.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -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.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.DataTransferModelAnalyzer; -import algorithms.Validation; -import code.ast.CompilationUnit; -import graphicalrefactor.layouts.*; -import models.Edge; -import models.EdgeAttribute; -import models.Node; -import models.dataConstraintModel.ChannelGenerator; -import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.IdentifierTemplate; -import models.dataFlowModel.DataTransferModel; -import models.dataFlowModel.DataTransferChannelGenerator; -import models.dataFlowModel.PushPullAttribute; -import models.dataFlowModel.DataFlowEdge; -import models.dataFlowModel.DataFlowGraph; -import models.dataFlowModel.ResourceNode; -import models.visualModel.FormulaChannelGenerator; -import parser.Parser; -import parser.Parser.TokenStream; -import parser.exceptions.ExpectedAssignment; -import parser.exceptions.ExpectedChannel; -import parser.exceptions.ExpectedChannelName; -import parser.exceptions.ExpectedEquals; -import parser.exceptions.ExpectedFormulaChannel; -import parser.exceptions.ExpectedGeometry; -import parser.exceptions.ExpectedInOrOutOrRefKeyword; -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.WrongLHSExpression; -import parser.exceptions.WrongRHSExpression; -import parser.ParserDTRAM; - -public class Editor { - final int PORT_DIAMETER = 8; - final int PORT_RADIUS = PORT_DIAMETER / 2; - - protected String curFileName = null; - protected String curFilePath = null; - protected ArrayList codes = null; - - protected DataTransferModel model = null; - protected mxGraph graph = null; - - protected DataFlowGraph dataFlowGraph = null; - - - public Editor(mxGraph graph) { - this.graph = graph; - } - - public mxGraph getGraph() { - return graph; - } - - public void setGraph(mxGraph graph) { - this.graph = graph; - } - - public DataTransferModel getModel() { - if (model == null) { - model = new DataTransferModel(); - } - return model; - } - - public DataFlowGraph getDataFlowGraph() { - if (dataFlowGraph == null) { - analyzeDataTransferModel(getModel()); - } - return dataFlowGraph; - } - - public DataFlowGraph analyzeDataTransferModel(DataTransferModel model) { - DataFlowGraph flowGraph = DataTransferModelAnalyzer.createDataFlowGraphWithStateStoringAttribute(model); - dataFlowGraph = DataTransferModelAnalyzer.annotateWithSelectableDataTransferAttiribute(flowGraph); - updateEdgeAttiributes(dataFlowGraph); - return dataFlowGraph; - } - - public void resetDataFlowGraph() { - dataFlowGraph = null; - } - - public void setDataFlowGraph(DataFlowGraph dataFlowGraph) { - this.dataFlowGraph = dataFlowGraph; - } - - public ArrayList getCodes() { - return codes; - } - - public void setCodes(ArrayList codes) { - this.codes = codes; - } - - public String getCurFileName() { - 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(); - dataFlowGraph = null; - curFilePath = null; - curFileName = null; - codes = null; - } - - /** - * 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 { - - String extension =""; - if(file != null && file.exists()) { - // get a file's name - String name = file.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 { - model = parserDTRAM.doParseModel(); - graph = constructGraph(model); - parserDTRAM.doParseGeometry(graph); - curFilePath = file.getAbsolutePath(); - curFileName = file.getName(); - if (!Validation.checkUpdateConflict(model)) return null; - analyzeDataTransferModel(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 DataTransferModel openModel(File file) { - try { - - Parser parser = new Parser(new BufferedReader(new FileReader(file))); - - try { - model = parser.doParse(); - curFilePath = file.getAbsolutePath(); - curFileName = file.getName(); - if (!Validation.checkUpdateConflict(model)) return null; - graph = constructGraph(model); - analyzeDataTransferModel(model); - return model; - } catch (ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefKeyword - | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression - | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment e) { - e.printStackTrace(); - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return null; - } - - /**-------------------------------------------------------------------------------- - * 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(); - - // 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(); - } - } - } - - 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(); - } - } - } - - /**-------------------------------------------------------------------------------- - * 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"; - - fileString += "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())) { - fileString += "\tnode fc " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; - } else if(ch instanceof ChannelGenerator && state.getLabel().equals(ch.getChannelName())) { - fileString +="\tnode c " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h+"\n"; - } - } - - for (IdentifierTemplate res: model.getIdentifierTemplates()){ - if(res instanceof IdentifierTemplate && state.getLabel().equals(res.getResourceName())) - fileString += "\tnode r " + state.getLabel() + ":" + x + "," + y + "," + w + "," + h + "\n"; - } - - for (ChannelGenerator ioC: model.getIOChannelGenerators()) { - if(ioC instanceof ChannelGenerator && 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) { - ((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); - - mxGeometry geo2 = new mxGeometry(1.0, 0.5, PORT_DIAMETER, PORT_DIAMETER); - geo2.setOffset(new mxPoint(-PORT_RADIUS, -PORT_RADIUS)); - geo2.setRelative(true); - - Map channelsIn = new HashMap<>(); - Map channelsOut = new HashMap<>(); - Map resources = new HashMap<>(); - - // create channel vertices - for (ChannelGenerator c: model.getChannelGenerators()) { - DataTransferChannelGenerator channelGen = (DataTransferChannelGenerator) 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 (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 (ChannelGenerator ch: model.getChannelGenerators()) { - DataTransferChannelGenerator channelGen = (DataTransferChannelGenerator) 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 - 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 - channelsOut.put((DataTransferChannelGenerator) ioChannelGen, port_out); - for (IdentifierTemplate outRes: ((DataTransferChannelGenerator) ioChannelGen).getOutputIdentifierTemplates()) { - graph.insertEdge(parent, null, null, port_out, resources.get(outRes), "movable=false"); - } - } - } - } finally { - graph.getModel().endUpdate(); - } - setTreeLayout(); - - return graph; - } - - public void setDAGLayout() { - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - DAGLayout ctl = new DAGLayout(graph); - ctl.execute(parent); - } finally { - graph.getModel().endUpdate(); - } - } - - 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; - DataTransferChannelGenerator channelGen = dataFlow.getChannelGenerator(); - ResourceNode srcRes = (ResourceNode) dataFlow.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(dataFlow.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.setEdgeRouting(false); - ctl.execute(parent); - } finally { - graph.getModel().endUpdate(); - } - } - - public void setCircleLayout() { - Object parent = graph.getDefaultParent(); - graph.getModel().beginUpdate(); - try { - mxCircleLayout ctl = new mxCircleLayout(graph); - ctl.execute(parent); - } finally { - graph.getModel().endUpdate(); - } - } - - public void addIdentifierTemplate(IdentifierTemplate res) { - getModel().addIdentifierTemplate(res); - resetDataFlowGraph(); - 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(DataTransferChannelGenerator channelGen) { - getModel().addChannelGenerator(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); - - 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(DataTransferChannelGenerator ioChannelGen) { - getModel().addIOChannelGenerator(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); - - 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); - 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); - - 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) { - DataTransferModel 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); - ((DataTransferChannelGenerator ) dstCh).addChannelMemberAsInput(srcCm); - edge.setValue(new SrcDstAttribute(srcRes, dstCh)); - resetDataFlowGraph(); - return true; - } - } - IdentifierTemplate dstRes = model.getIdentifierTemplate((String) dst.getValue()); - if (dstRes == null) return false; - // channel to resource edge - ChannelMember dstCm = new ChannelMember(dstRes); - ((DataTransferChannelGenerator) srcCh).addChannelMemberAsOutput(dstCm); - edge.setValue(new SrcDstAttribute(srcCh, dstRes)); - resetDataFlowGraph(); - 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()); - resetDataFlowGraph(); - } - - public void setChannelCode(DataTransferChannelGenerator 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 { - DataTransferChannelGenerator ch2 = parser.parseChannel(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; - } - } - } - resetDataFlowGraph(); - } 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/layouts/DAGLayout.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/layouts/DAGLayout.java deleted file mode 100644 index 2665efe..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/layouts/DAGLayout.java +++ /dev/null @@ -1,150 +0,0 @@ -package graphicalrefactor.layouts; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import com.mxgraph.layout.mxGraphLayout; -import com.mxgraph.model.mxCell; -import com.mxgraph.model.mxGeometry; -import com.mxgraph.model.mxICell; -import com.mxgraph.model.mxIGraphModel; -import com.mxgraph.util.mxRectangle; -import com.mxgraph.view.mxCellState; -import com.mxgraph.view.mxGraph; -import com.mxgraph.view.mxGraphView; - -import models.dataConstraintModel.ChannelGenerator; -import models.dataConstraintModel.IdentifierTemplate; - -public class DAGLayout extends mxGraphLayout { - - public DAGLayout(mxGraph arg0) { - super(arg0); - } - - public void execute(Object parent) { - mxIGraphModel model = graph.getModel(); - - model.beginUpdate(); - try { - List> map = new ArrayList>(); - List moved = new ArrayList<>(); - - for (int i = 0; i < model.getChildCount(parent); i++) { - - mxCell cell = (mxCell) model.getChildAt(parent, i); - - if (model.isVertex(cell)) { - mxGraphView view = graph.getView(); - mxCellState state = view.getState(cell); - - if (!"ellipse".equals(state.getStyle().get("shape")) && (cell.getEdgeCount() == 1) && !"true".equals(state.getStyle().get("dashed"))) { - List newline = new ArrayList(); - map.add(newline); - lines(map, cell); - } - } - } - - // ���בւ� - sort(map, 0, false); - - // layout - int count; - int skip = 0; - mxGraphView view = graph.getView(); - for (int i = 0; i < map.size(); i++) { - count = 0; - for (int j = 0; j < map.get(i).size(); j++) { - mxGeometry geom = (mxGeometry) map.get(i).get(j).getGeometry().clone(); - mxCellState state = view.getState(map.get(i).get(j)); - if (checkmoved(moved, map.get(i).get(j))) { - if ("ellipse".equals(state.getStyle().get("shape"))){ - geom.setX(50 + j*200); - } else { - geom.setX(100 + j*200); - } - geom.setY(100 + (i-skip)*100); - model.setGeometry(map.get(i).get(j), geom); - moved.add(map.get(i).get(j).getId()); - } else if (geom.getX() < 100 + j*150) { - if ("ellipse".equals(state.getStyle().get("shape"))){ - geom.setX(50 + j*200); - } else { - geom.setX(100 + j*200); - } - geom.setY(100 + (i-skip)*100); - model.setGeometry(map.get(i).get(j), geom); - } else { - count++; - } - } - if (count >= map.get(i).size())skip++; - } - - } finally { - model.endUpdate(); - } - } - - - public void lines(List> mapping, mxCell next) { - mapping.get(mapping.size()-1).add(next); - int tagcount = 0; - mxCell edge; - mxGraphView view = graph.getView(); - for (int i = 0; i < next.getEdgeCount(); i++) { - edge = (mxCell) next.getEdgeAt(i); - mxCellState state = view.getState(edge); - if (next != (mxCell) edge.getTarget() && ((mxCell) edge.getTarget() != null) && !"true".equals(state.getStyle().get("dashed"))) { - tagcount++; - if (tagcount > 1) { - List newline = new ArrayList(mapping.get(mapping.size()-1)); - while (newline.get(newline.size()-1).getId() != next.getId()) { - newline.remove(newline.size()-1); - } - mapping.add(newline); - lines(mapping, (mxCell) edge.getTarget()); - - } else { - lines(mapping, (mxCell) edge.getTarget()); - } - } - } - } - - public boolean checkmoved(List list, mxCell cell) { - for (int i = 0; i < list.size(); i++) { - if (list.get(i).equals(cell.getId()))return false; - } - return true; - } - - public void sort(List> map, int n, boolean check) { - int msize = -1; - int mnum = -1; - if (check) { - for (int i = n; i < map.size(); i++) { - if (map.get(i).size() > msize && (map.get(n-1).get(0).getId().equals(map.get(i).get(0).getId()))) { - mnum = i; - } - } - } else { - for (int i = n; i < map.size(); i++) { - if (map.get(i).size() > msize) { - mnum = i; - } - } - } - if (mnum >= 0) { - Collections.swap(map, n, mnum); - sort(map, n+1, true); - } else if(n < map.size()) { - sort(map, n+1, false); - } - } - - -} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactor.java deleted file mode 100644 index ab035a5..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactor.java +++ /dev/null @@ -1,98 +0,0 @@ -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; - private GraphicalRefactorMenuBar menuBar; - private mxGraphComponent graphComponent; - - public GraphicalRefactor() { - setTitle(title); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - 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; - } - }; - - 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); - } - - public mxGraph getGraph() { - return graph; - } - - public mxGraphComponent getGraphComponent() { - return graphComponent; - } - - public Editor getEditor() { - return editor; - } - - public void setEditor(Editor editor) { - this.editor = editor; - } - -} diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorCellEditor.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorCellEditor.java deleted file mode 100644 index 606c7e4..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorCellEditor.java +++ /dev/null @@ -1,249 +0,0 @@ -package graphicalrefactor.views; - -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 graphicalrefactor.editor.Editor; -import models.algebra.Expression; -import models.dataFlowModel.DataTransferModel; -import models.dataFlowModel.DataTransferChannelGenerator; -import models.dataFlowModel.PushPullAttribute; -import models.dataFlowModel.PushPullValue; -import models.visualModel.FormulaChannelGenerator; -import parser.Parser; -import parser.Parser.TokenStream; -import parser.exceptions.ExpectedRightBracket; - -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)) { - DataTransferModel model = editor.getModel(); - DataTransferChannelGenerator ch = (DataTransferChannelGenerator) model.getChannelGenerator((String) ((mxCell) cell).getValue()); - if (ch == null) { - ch = (DataTransferChannelGenerator) 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, // 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()); - ((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 deleted file mode 100644 index 7c0d477..0000000 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/views/GraphicalRefactorMenuBar.java +++ /dev/null @@ -1,93 +0,0 @@ -package graphicalrefactor.views; - -import javax.swing.JMenu; -import javax.swing.JMenuBar; - -import graphicalrefactor.actions.CircleLayoutAction; -import graphicalrefactor.actions.DAGLayoutAction; -import graphicalrefactor.actions.DeleteAction; -import graphicalrefactor.actions.ExitAction; -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.OpenAction; -import graphicalrefactor.actions.SaveAction; -import graphicalrefactor.actions.SaveAsAction; -import graphicalrefactor.actions.TreeLayoutAction; -import graphicalrefactor.actions.ZoomInAction; -import graphicalrefactor.actions.ZoomOutAction; -import graphicalrefactor.editor.Editor; - -public class GraphicalRefactorMenuBar extends JMenuBar { - private static final long serialVersionUID = 4811536194182272888L; - - private GraphicalRefactor graphicalModelRefactor = 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; - - 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(newMenu); - menu.add(new OpenAction(graphicalModelRefactor)); - menu.addSeparator(); - 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())); - menu.add(circleLayoutAction = new CircleLayoutAction(graphicalModelRefactor.getEditor())); - - menu = add(new JMenu("View")); - menu.add(new ZoomInAction(graphicalModelRefactor.getGraphComponent())); - menu.add(new ZoomOutAction(graphicalModelRefactor.getGraphComponent())); - - menu = add(new JMenu("Generate")); - menu.add(javaPrototypeGenerateAction = new JavaPrototypeGenerateAction(graphicalModelRefactor.getEditor())); - menu.add(jerseyPrototypeGenerateAction = new JerseyPrototypeGenerateAction(graphicalModelRefactor.getEditor())); - } - - public Editor getEditor() { - return graphicalModelRefactor.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/models/DirectedGraph.java b/AlgebraicDataflowArchitectureModel/src/models/DirectedGraph.java index 3b9d1d3..42b7208 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/DirectedGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/models/DirectedGraph.java @@ -64,4 +64,8 @@ edge.getSource().removeOutEdge(edge); edge.getDestination().removeInEdge(edge); } + + protected void simpleAddEdge(Edge edge) { + edges.add(edge); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/Edge.java b/AlgebraicDataflowArchitectureModel/src/models/Edge.java index 9ea2037..71ab977 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/Edge.java +++ b/AlgebraicDataflowArchitectureModel/src/models/Edge.java @@ -1,6 +1,8 @@ package models; -public class Edge { +import java.io.Serializable; + +public class Edge implements Serializable { protected Node source; protected Node destination; private EdgeAttribute attribute; diff --git a/AlgebraicDataflowArchitectureModel/src/models/Node.java b/AlgebraicDataflowArchitectureModel/src/models/Node.java index 3fa1e28..589cc4f 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/Node.java +++ b/AlgebraicDataflowArchitectureModel/src/models/Node.java @@ -1,11 +1,14 @@ package models; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.Set; -public class Node implements Cloneable { - private Set inEdges = null; - private Set outEdges = null; +public class Node implements Cloneable, Serializable { + protected Collection inEdges = null; + protected Collection outEdges = null; private NodeAttribute attribute; public Node() { @@ -13,19 +16,19 @@ outEdges = new HashSet<>(); } - public Set getInEdges() { + public Collection getInEdges() { return inEdges; } - public void setInEdges(Set inEdges) { + public void setInEdges(Collection inEdges) { this.inEdges = inEdges; } - public Set getOutEdges() { + public Collection getOutEdges() { return outEdges; } - public void setOutEdges(Set outEdges) { + public void setOutEdges(Collection outEdges) { this.outEdges = outEdges; } @@ -61,16 +64,16 @@ return outEdges.size(); } - public Set getPredecessors() { - Set predecessors = new HashSet(); + public Collection getPredecessors() { + Collection predecessors = new ArrayList(); for (Edge edge: inEdges) { predecessors.add(edge.getSource()); } return predecessors; } - public Set getSuccessors() { - Set successors = new HashSet(); + public Collection getSuccessors() { + Collection successors = new ArrayList(); for (Edge edge: outEdges) { successors.add(edge.getDestination()); } diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdge.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdge.java new file mode 100644 index 0000000..e19986e --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdge.java @@ -0,0 +1,17 @@ +package models.controlFlowModel; + +import models.Edge; +import models.dataFlowModel.PushPullValue; + +public class CallEdge extends Edge { + private PushPullValue selectedOption = PushPullValue.PUSHorPULL; + + public CallEdge(ObjectNode src, ObjectNode dst, PushPullValue selectedOption) { + super(src, dst); + this.selectedOption = selectedOption; + } + + public PushPullValue getSelectedOption() { + return this.selectedOption; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdgeAttribute.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdgeAttribute.java new file mode 100644 index 0000000..2658597 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallEdgeAttribute.java @@ -0,0 +1,98 @@ +package models.controlFlowModel; + +import com.mxgraph.model.mxCell; + +import models.EdgeAttribute; +import models.dataFlowModel.PushPullValue; + +/************************************************************* + * Information of connection status of the call edge among nodes type of "Object-Node". + */ +public class CallEdgeAttribute extends EdgeAttribute { + private CallEdge callEdge = null; + private ObjectNode orginalSrcObjNode = null; + private mxCell srcCell = null; + private mxCell dstCell = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public CallEdgeAttribute(CallEdge callEdge, ObjectNode originalSrcObjNode, final mxCell srcCell, final mxCell dstCell) { + this.callEdge = callEdge; + this.callEdge.setAttribute(this); + + this.orginalSrcObjNode = originalSrcObjNode; + + this.srcCell = srcCell; + this.dstCell = dstCell; + } + + /************************************************************* + * + */ + public CallEdgeAttribute(CallEdge callEdge, final mxCell srcCell, final mxCell dstCell) { + this.callEdge = callEdge; + this.callEdge.setAttribute(this); + + this.srcCell = srcCell; + this.dstCell = dstCell; + } + + + /************************************************************* + * [ *public ] + /************************************************************* + * [ getter ] + /*************************************************************/ + public CallEdge getCallEdge() { + return callEdge; + } + + public ObjectNode getOriginalSourceObjectNode() { + return orginalSrcObjNode; + } + + public PushPullValue getSelectedOption() { + return callEdge.getSelectedOption(); + } + + public ObjectNode getSourceObjectNode() { + if( !(callEdge.getSource() instanceof ObjectNode) ) throw new ClassCastException("sourceNode isn't type of "); + return (ObjectNode)callEdge.getSource(); + } + + public ObjectNode getDestinationObjectNode() { + if( !(callEdge.getDestination() instanceof ObjectNode) ) throw new ClassCastException("destinationNode isn't type of "); + return (ObjectNode)callEdge.getDestination(); + } + + public mxCell getSourceCell() { + return srcCell; + } + + public mxCell getDestinationCell() { + return dstCell; + } + + public void setDestinationCell(final mxCell dstCell) { + this.dstCell = dstCell; + } + + /************************************************************* + * + */ + @Override + public String toString() { + String value = ""; + + if(2 <= callEdge.getSource().getOutEdges( ).size()) { + int order = (((ObjectNode)callEdge.getSource()).getOutEdgeCallOrder(callEdge)+ 1); + value += "[" + order + "]"; + } + + return value; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java new file mode 100644 index 0000000..fbd3356 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/CallGraph.java @@ -0,0 +1,53 @@ +package models.controlFlowModel; + +import java.util.HashMap; +import java.util.Map; + +import models.DirectedGraph; +import models.Node; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResourceNode; + +public class CallGraph extends DirectedGraph { + protected Map statefulObjMap = null; + + public CallGraph() { + statefulObjMap = new HashMap<>(); + } + + public void addNode(Node node) { + super.addNode(node); + if (node instanceof ResourceNode) { + ResourceNode resNode = (ResourceNode) node; + StatefulObjectNode objNode = statefulObjMap.get(resNode); + if (objNode == null) { + objNode = new StatefulObjectNode(resNode); + statefulObjMap.put(resNode, objNode); + } + } else if (node instanceof StatefulObjectNode) { + StatefulObjectNode objNode = (StatefulObjectNode) node; + if (statefulObjMap.get(objNode.getResource()) == null) { + statefulObjMap.put(objNode.getResource(), objNode); + } + } + } + + public void addEdge(ResourceNode srcResNode, ResourceNode dstResNode, PushPullValue selectedOption) { + addNode(srcResNode); + addNode(dstResNode); + addEdge(new CallEdge(getStatefulObjectNode(srcResNode), getStatefulObjectNode(dstResNode), selectedOption)); + } + + public void insertEdge(ObjectNode srcObjNode, ObjectNode dstObjNode, PushPullValue selectedOption, int n) { + CallEdge edge = new CallEdge(srcObjNode, dstObjNode, selectedOption); + simpleAddEdge(edge); + addNode(srcObjNode); + addNode(dstObjNode); + srcObjNode.insertOutEdge(edge, n); + dstObjNode.addInEdge(edge); + } + + public StatefulObjectNode getStatefulObjectNode(ResourceNode resNode) { + return statefulObjMap.get(resNode); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java new file mode 100644 index 0000000..2d0b5de --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowDelegator.java @@ -0,0 +1,173 @@ +package models.controlFlowModel; + +import java.util.ArrayList; +import java.util.List; + +import models.Edge; + +/************************************************************* + * it has Delegation of Control-Flow algorithm. + */ +public class ControlFlowDelegator { + + private ControlFlowGraph controlFlowGraph = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public ControlFlowDelegator(final ControlFlowGraph controlFlowGraph) { + this.controlFlowGraph = controlFlowGraph; + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + *@param callEdge + */ + public List searchDelegatableNodes(final CallEdge callEdge){ + List nodes = new ArrayList<>(); + + // 1. adding parentNode + ObjectNode delegatingNode = (ObjectNode) callEdge.getDestination(); + ObjectNode parentNode = (ObjectNode) callEdge.getSource(); + + if(parentNode == null || delegatingNode == null) + throw new NullPointerException("parentNode is null."); + if( !(parentNode instanceof ObjectNode && delegatingNode instanceof ObjectNode)) + throw new ClassCastException("callEdge.getSource() is not ObjectNode"); + + // if the relation of "delegatingNode" to "parentNode" is 1 : 1 ? + // then return an empty list. + if( isRootNode(parentNode) && ! hasChildrenNode(parentNode) ) return nodes; + + // 2. collecting for each transfer method has nodes in the common area. + collectCommonTransferNodes(nodes, parentNode, delegatingNode); + + // 3. if the transfer method is PUSH-style, + // then serach delegatable area. + collectParentNodesInPushTransfer(nodes, delegatingNode, parentNode); + + // switch objects by transfer type + return nodes; + } + + /************************************************************* + * + */ + public void delegateCallEdge(CallEdge delegatingEdge, final ObjectNode dstObjNode) { + ObjectNode srcObjNode = (ObjectNode)delegatingEdge.getDestination(); + if(srcObjNode == null) throw new ClassCastException(); + + delegatingEdge.getSource().removeOutEdge(delegatingEdge); + srcObjNode.removeInEdge(delegatingEdge); + + // Reconnecting the edge to the new source object. + delegatingEdge.setDestination(srcObjNode); + delegatingEdge.setSource(dstObjNode); + + srcObjNode.addInEdge(delegatingEdge); + dstObjNode.addOutEdge(delegatingEdge); + } + + /************************************************************* + * [* private ] + /************************************************************* + * [ search ] + /************************************************************* + * Collecting nodes in the "nodes" parameter for each transfer method has nodes in the common area. + * @param nodes + * @param curObjNode + * @param delegatingObjNode + * @param selectedOption + */ + private void collectCommonTransferNodes(List nodes, ObjectNode curObjNode, final ObjectNode delegatingObjNode){ + if( !hasChildrenNode(curObjNode)) return; + + for(Edge e : curObjNode.getOutEdges()) { + ObjectNode foundNode = (ObjectNode)e.getDestination(); + + if( foundNode.equals(delegatingObjNode)) continue; + + nodes.add(foundNode); + collectCommonTransferNodes(nodes, foundNode, delegatingObjNode); + } + } + + /************************************************************* + * Collecting nodes in the "nodes" parameter for node of the area of PUSH-style transfer method. + * @param result in "nodes" parameter. + * @param curObjNode + */ + private void collectParentNodesInPushTransfer(List nodes, ObjectNode curObjNode, final ObjectNode parentDelegatingNode) { + if( isRootNode(curObjNode) ) return; + if( isInEdgesConversingToNode(curObjNode) ) return; + + ObjectNode parentObjNode = (ObjectNode)curObjNode.getInEdge(0).getSource(); + if(parentObjNode == null) return; + + if( !parentDelegatingNode.equals(parentObjNode) ) + nodes.add(parentObjNode); + + int inEdgeCallOrder = parentObjNode.getOutEdgeCallOrder(curObjNode.getInEdge(0)); + for(Edge edge : parentObjNode.getOutEdges()) { + if( !(edge instanceof CallEdge)) continue; + + int callOrder = parentObjNode.getOutEdgeCallOrder((CallEdge)edge); + if(inEdgeCallOrder < callOrder) collectChildNodesInPushTransfer(nodes, (CallEdge)edge); + } + + collectParentNodesInPushTransfer(nodes, parentObjNode, parentDelegatingNode); + } + + /************************************************************* + * + * @param node + */ + private void collectChildNodesInPushTransfer(List nodes, CallEdge callEdge) { + ObjectNode dstObjNode = (ObjectNode)callEdge.getDestination(); + if(dstObjNode == null) return; + + nodes.add(dstObjNode); + + if(!hasChildrenNode(dstObjNode)) return; + + for(Edge e : dstObjNode.getOutEdges()) { + CallEdge edge = (CallEdge)e; + if(edge == null) continue; + + ObjectNode foundNode = (ObjectNode)e.getDestination(); + if(foundNode == null) continue; + if(nodes.contains(foundNode))continue; + + collectChildNodesInPushTransfer(nodes, edge); + } + } + + /************************************************************* + * + * @param node + */ + private boolean isRootNode(final ObjectNode node) { + return node.getInEdges().isEmpty(); + } + + /************************************************************* + * + * @param node + */ + private boolean hasChildrenNode(final ObjectNode node) { + if(node.getOutEdges().size() < 1) return false; + return true; + } + + /************************************************************* + * + * @param node + */ + private boolean isInEdgesConversingToNode(final ObjectNode node) { + return ( 1 < node.getInEdges().size() ); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java new file mode 100644 index 0000000..5d4b77e --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ControlFlowGraph.java @@ -0,0 +1,117 @@ +package models.controlFlowModel; + +import java.util.HashSet; +import java.util.Set; + +import models.Edge; +import models.Node; +import models.algebra.Expression; +import models.algebra.Term; +import models.algebra.Variable; +import models.dataConstraintModel.ChannelGenerator; +import models.dataConstraintModel.ChannelMember; +import models.dataFlowModel.DataFlowEdge; +import models.dataFlowModel.DataFlowGraph; +import models.dataFlowModel.DataTransferChannelGenerator; +import models.dataFlowModel.DataTransferModel; +import models.dataFlowModel.IFlowGraph; +import models.dataFlowModel.PushPullAttribute; +import models.dataFlowModel.PushPullValue; +import models.dataFlowModel.ResourceNode; + +public class ControlFlowGraph implements IFlowGraph { + private DataFlowGraph dataFlowGraph; + private CallGraph pushCallGraph; + private CallGraph pullCallGraph; + + public ControlFlowGraph(DataFlowGraph dataFlowGraph, DataTransferModel model) { + this.dataFlowGraph = dataFlowGraph; + this.pushCallGraph = new CallGraph(); + this.pullCallGraph = new CallGraph(); + for (Edge e: dataFlowGraph.getEdges()) { + PushPullAttribute pushPull = ((PushPullAttribute) ((DataFlowEdge) e).getAttribute()); + ResourceNode srcNode = (ResourceNode) e.getSource(); + ResourceNode dstNode = (ResourceNode) e.getDestination(); + if (pushPull.getOptions().get(0) == PushPullValue.PUSH) { + // same direction as the data flow + pushCallGraph.addEdge(srcNode, dstNode, PushPullValue.PUSH); + } else { + // reverse direction to the data flow + pullCallGraph.addEdge(dstNode, srcNode, PushPullValue.PULL); + } + } + for (ChannelGenerator ch: model.getIOChannelGenerators()) { + DataTransferChannelGenerator cio = (DataTransferChannelGenerator) ch; + EntryPointObjectNode srcNode = new EntryPointObjectNode(cio); + for (ChannelMember cm: cio.getChannelMembers()) { + if (srcNode.getName() == null) { + Expression exp = cm.getStateTransition().getMessageExpression(); + if (exp instanceof Term) { + srcNode.setName(((Term) exp).getSymbol().getName()); + } else if (exp instanceof Variable) { + srcNode.setName(((Variable) exp).getName()); + } + } + ResourceNode dstResNode = dataFlowGraph.getResouceNode(cm.getIdentifierTemplate()); + StatefulObjectNode dstNode = pushCallGraph.getStatefulObjectNode(dstResNode); + if (dstNode == null) { + pushCallGraph.addNode(dstResNode); + dstNode = pushCallGraph.getStatefulObjectNode(dstResNode); + } + // from an I/O channel to a resource + pushCallGraph.insertEdge(srcNode, dstNode, PushPullValue.PUSH, 0); + } + } + } + + public ControlFlowGraph(DataFlowGraph dataFlowGraph, PushPullValue priority) { + this.dataFlowGraph = dataFlowGraph; + this.pushCallGraph = new CallGraph(); + this.pullCallGraph = new CallGraph(); + if (priority == PushPullValue.PUSH) { + // push-first + for (Edge e: dataFlowGraph.getEdges()) { + ResourceNode srcNode = (ResourceNode) e.getSource(); + ResourceNode dstNode = (ResourceNode) e.getDestination(); + // same direction as the data flow + pushCallGraph.addEdge(srcNode, dstNode, PushPullValue.PUSH); + } + } else { + // pull-first + for (Edge e: dataFlowGraph.getEdges()) { + ResourceNode srcNode = (ResourceNode) e.getSource(); + ResourceNode dstNode = (ResourceNode) e.getDestination(); + PushPullAttribute pushPull = ((PushPullAttribute) ((DataFlowEdge) e).getAttribute()); + if (pushPull.getOptions().contains(PushPullValue.PULL)) { + // Pull style is selectable + // reverse direction to the data flow + pullCallGraph.addEdge(dstNode, srcNode, PushPullValue.PULL); + } else { + // Pull style is not selectable + // same direction as the data flow + pushCallGraph.addEdge(srcNode, dstNode, PushPullValue.PUSH); + } + } + } + } + + public DataFlowGraph getDataFlowGraph() { + return dataFlowGraph; + } + + public CallGraph getPushCallGraph() { + return pushCallGraph; + } + + public CallGraph getPullCallGraph() { + return pullCallGraph; + } + + @Override + public Set getAllNodes() { + Set allNodes = new HashSet<>(); + allNodes.addAll(pushCallGraph.getNodes()); + allNodes.addAll(pullCallGraph.getNodes()); + return allNodes; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java new file mode 100644 index 0000000..f200312 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/EntryPointObjectNode.java @@ -0,0 +1,40 @@ +package models.controlFlowModel; + +import models.dataFlowModel.DataTransferChannelGenerator; + +/************************************************************* + * An object is mapped to I/O channel. + * ToDo: Fecthing name from in Data-Flow-Graph + */ +public class EntryPointObjectNode extends ObjectNode { + DataTransferChannelGenerator ioChannelGenerator = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public EntryPointObjectNode(DataTransferChannelGenerator ioChannelGenerator) { + super(null); + this.ioChannelGenerator = ioChannelGenerator; + } + + public EntryPointObjectNode(String name, DataTransferChannelGenerator ioChannelGenerator) { + super(name); + this.ioChannelGenerator = ioChannelGenerator; + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + public DataTransferChannelGenerator getIoChannelGenerator() { + return ioChannelGenerator; + } + + public void setIoChannelGenerator(DataTransferChannelGenerator ioChannelGenerator) { + this.ioChannelGenerator = ioChannelGenerator; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java new file mode 100644 index 0000000..9303eb3 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNode.java @@ -0,0 +1,90 @@ +package models.controlFlowModel; + +import java.util.ArrayList; +import java.util.List; + +import models.Edge; +import models.Node; + +/************************************************************* +* +*/ +public class ObjectNode extends Node { + protected String name = ""; + + /************************************************************* + * [ *constructor] + /************************************************************* + */ + public ObjectNode(String name) { + inEdges = new ArrayList<>(); + outEdges = new ArrayList<>(); + + this.name = name; + } + + /************************************************************* + * [ *public ] + /************************************************************* + * + */ + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public CallEdge getInEdge(int i) { + return (CallEdge) ((List) inEdges).get(i); + } + + public CallEdge getOutEdge(int i) { + return (CallEdge) ((List) outEdges).get(i); + } + + public CallEdge findEdgeInInEdges(final CallEdge edge) { + for(Edge e : inEdges) { + if( e instanceof CallEdge) return (CallEdge)e; + } + return null; + } + + public void insertOutEdge(CallEdge edge, int n) { + ((List) outEdges).add(n, edge); + } + + public CallEdge findEdgeInOutEdges(final CallEdge edge) { + for(Edge e : outEdges) { + if( e instanceof CallEdge) return (CallEdge)e; + } + return null; + } + + public int getChildrenNum() { + return outEdges.size(); + } + + public int getOutEdgeCallOrder(final CallEdge callEdge) { + for(int i = 0; i < outEdges.size(); i++) { + if(callEdge.equals(getOutEdge(i))) return i; + } + return -1; + } + + public ObjectNode getChildren(int i) { + return (ObjectNode) ((List) outEdges).get(i).getDestination(); + } + + /************************************************************* + * + */ + public void sortOutEdgesByCallOrder(final int curOrder, final int callOrder) { + ArrayList edges = ((ArrayList)outEdges); + Edge edge = ((List)outEdges).get(curOrder); + + edges.remove(curOrder); + edges.add(callOrder-1, edge); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNodeAttribute.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNodeAttribute.java new file mode 100644 index 0000000..da80d92 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/ObjectNodeAttribute.java @@ -0,0 +1,112 @@ +package models.controlFlowModel; + +import models.NodeAttribute; + +/************************************************************* + * + * @author k-fujii + * + */ +public class ObjectNodeAttribute extends NodeAttribute { + private ObjectNode objectNode = null; + private String shapeStyle = ""; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public ObjectNodeAttribute(final ObjectNode objectNode) { + this.objectNode = objectNode; + this.objectNode.setAttribute(this); + + // Setting a shape style of cell + if(objectNode instanceof StatefulObjectNode) { + shapeStyle = "shape=ellipse;perimeter=ellipsePerimeter;"; + } + else if(objectNode instanceof EntryPointObjectNode) { + shapeStyle = "shape=rectangle;perimeter=rectanglePerimeter;"; + } + else { + shapeStyle = "shape=hexagon;perimeter=hexagonPerimeter;"; + } + + // Setting a name of cell + if(objectNode.name != null) return; + if(objectNode.name.isEmpty()) return; + + if( objectNode instanceof StatefulObjectNode ) { + objectNode.name = objectNode.getName(); + } + else if(objectNode instanceof EntryPointObjectNode){ + objectNode.name = "entryPoint"; + } + } + + /************************************************************* + * [ *public ] + /************************************************************* + * [ getter ] + /************************************************************* + * + * @return + */ + public ObjectNode getObjectNode() { + return objectNode; + } + + /************************************************************* + * + */ + public String getDefaultStyle() { + String style = ";"; + + return objectNode instanceof StatefulObjectNode + ? shapeStyle + style + : shapeStyle + style; + } + + /************************************************************* + * + */ + public String getEnableStyle() { + String style = "fillColor=#7fffd4;"; + style += "strokeColor=#66cdaa;"; + style += "strokeWidth=2;"; + + return objectNode instanceof StatefulObjectNode + ? shapeStyle + style + : shapeStyle + style; + } + + /************************************************************* + * + */ + public String getDisableStyle() { + String style = "fillColor=#999999"; + + return objectNode instanceof StatefulObjectNode + ? shapeStyle + style + : shapeStyle + style; + } + + /************************************************************* + * + */ + public String getDelegatingStyle() { + String style = "strokeWidth=4;"; + style += "strokeColor=#4169e;"; + + return shapeStyle + style; + } + + /************************************************************* + * showing label of mxCell + */ + @Override + public String toString() { + return objectNode instanceof StatefulObjectNode + ? ((StatefulObjectNode) objectNode).getResource().getIdentifierTemplate().getResourceName() + : objectNode.getName(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/StatefulObjectNode.java b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/StatefulObjectNode.java new file mode 100644 index 0000000..184774d --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/controlFlowModel/StatefulObjectNode.java @@ -0,0 +1,17 @@ +package models.controlFlowModel; + +import models.dataFlowModel.ResourceNode; + +public class StatefulObjectNode extends ObjectNode { + private ResourceNode resource; + + public StatefulObjectNode(ResourceNode resource) { + super(resource.getIdentifierTemplate().getResourceName()); + this.resource = resource; + } + + public ResourceNode getResource() { + return resource; + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataFlowGraph.java index 5df4229..f315047 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataFlowGraph.java @@ -1,12 +1,15 @@ package models.dataFlowModel; +import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Set; import models.DirectedGraph; +import models.Node; import models.dataConstraintModel.IdentifierTemplate; -public class DataFlowGraph extends DirectedGraph { +public class DataFlowGraph extends DirectedGraph implements IFlowGraph { protected Map nodeMap = null; public DataFlowGraph() { @@ -37,4 +40,18 @@ } addEdge(new DataFlowEdge(srcNode, dstNode, dfChannelGen)); } + + public Collection getResouceNodes(){ + return nodeMap.values(); + } + + public ResourceNode getResouceNode(IdentifierTemplate identifierTemplate) { + if(nodeMap.get(identifierTemplate) == null) throw new NullPointerException(identifierTemplate.getResourceName() + "was not found."); + return nodeMap.get(identifierTemplate); + } + + @Override + public Set getAllNodes() { + return super.getNodes(); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/IFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/IFlowGraph.java new file mode 100644 index 0000000..141c81f --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/IFlowGraph.java @@ -0,0 +1,9 @@ +package models.dataFlowModel; + +import java.util.Set; + +import models.Node; + +public interface IFlowGraph { + abstract public Set getAllNodes(); +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ResourceNodeAttribute.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ResourceNodeAttribute.java new file mode 100644 index 0000000..d03c305 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ResourceNodeAttribute.java @@ -0,0 +1,63 @@ +package models.dataFlowModel; + +import models.NodeAttribute; + +/************************************************************* + * + * @author k-fujii + * + */ +public class ResourceNodeAttribute extends NodeAttribute { + private ResourceNode resourceNode = null; + + /************************************************************* + * [ *constructor ] + /************************************************************* + * + */ + public ResourceNodeAttribute(ResourceNode resNode) { + this.resourceNode = resNode; + this.resourceNode.setAttribute(this); + } + + /************************************************************* + * [ *public ] + /************************************************************* + * [ getter ] + /************************************************************* + * + * @return + */ + public ResourceNode getResourceNode() { + return resourceNode; + } + + /************************************************************* + * + */ + public String getResourceName() { + return resourceNode.getIdentifierTemplate().getResourceName(); + } + + /************************************************************* + * + * @return + */ + public String getDefaultStyle() { + String style =""; + style += "shape=ellipse;"; + style += "perimeter=ellipsePerimeter"; + + return style; + } + + + /************************************************************* + * + * @return + */ + @Override + public String toString() { + return resourceNode.getIdentifierTemplate().getResourceName(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java b/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java index 830bd5f..54d0bf1 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/ParserDTRAM.java @@ -10,6 +10,7 @@ import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxGraphView; +import application.editor.Stage; import models.dataFlowModel.DataTransferModel; import parser.exceptions.ExpectedAssignment; import parser.exceptions.ExpectedChannel; @@ -148,11 +149,28 @@ 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++) { + mxCell root = (mxCell) graph.getDefaultParent(); + mxCell nodeLayer = (mxCell) root.getChildAt(Stage.NODE_LAYER); + mxCell dataFlowLayer = (mxCell) root.getChildAt(Stage.DATA_FLOW_LAYER); + for (int i = 0; i < graph.getModel().getChildCount(nodeLayer); i++) { - Object cell = graph.getModel().getChildAt(root, i); + Object cell = graph.getModel().getChildAt(nodeLayer, i); + if (!graph.getModel().isVertex(cell)) continue; + + mxGeometry geom = (mxGeometry) ((mxCell) cell).getGeometry().clone(); + mxGraphView view = graph.getView(); + mxCellState state = view.getState(cell); + + if (!name.equals(state.getLabel())) continue; + + geom.setX(xC); + geom.setY(yC); + graphModel.setGeometry(cell, geom); + } + for (int i = 0; i < graph.getModel().getChildCount(dataFlowLayer); i++) { + + Object cell = graph.getModel().getChildAt(dataFlowLayer, i); if (!graph.getModel().isVertex(cell)) continue; mxGeometry geom = (mxGeometry) ((mxCell) cell).getGeometry().clone(); diff --git a/AlgebraicDataflowArchitectureModel/src/tests/controlFlowModel/ControlFlowDelegatorTest.java b/AlgebraicDataflowArchitectureModel/src/tests/controlFlowModel/ControlFlowDelegatorTest.java new file mode 100644 index 0000000..c29e7fe --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/tests/controlFlowModel/ControlFlowDelegatorTest.java @@ -0,0 +1,26 @@ +package tests.controlFlowModel; + +import org.junit.Test; + +import models.dataConstraintModel.IdentifierTemplate; +import models.dataFlowModel.DataTransferModel; + +import static org.junit.Assert.*; + + +/**-------------------------------------------------------------------------------- + * + */ +public class ControlFlowDelegatorTest { + @Test + public void test() { + // Construct a data-flow architecture model. + DataTransferModel model = new DataTransferModel(); + IdentifierTemplate customer_off = new IdentifierTemplate("customers.{x1}.off", 1); // an identifier template to specify a customer's office resource + IdentifierTemplate company_add = new IdentifierTemplate("companies.{x2}.add", 1); // an identifier template to specify a companie's address resource + IdentifierTemplate customer_add = new IdentifierTemplate("customers.{x1}.add", 1); // an identifier template to specify a customer's address resource + + + + } +}