/** * */ package edu.brown.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JCheckBox; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.voltdb.catalog.Database; import org.voltdb.catalog.Procedure; import edu.brown.designer.Designer; import edu.brown.designer.DesignerEdge; import edu.brown.designer.DesignerHints; import edu.brown.designer.DesignerInfo; import edu.brown.designer.DesignerVertex; import edu.brown.graphs.AbstractDirectedGraph; import edu.brown.graphs.IGraph; import edu.brown.gui.common.GraphVisualizationPanel; import edu.brown.gui.designer.EdgeInfoPanel; import edu.brown.gui.designer.PartitionPlanPanel; import edu.brown.gui.designer.ProcedureInfoPanel; import edu.brown.gui.designer.VertexInfoPanel; import edu.brown.utils.ArgumentsParser; import edu.brown.utils.CollectionUtil; import edu.brown.utils.EventObservable; import edu.brown.utils.EventObserver; import edu.brown.workload.Workload; /** * @author pavlo * */ public class DesignerVisualization extends AbstractViewer { private static final long serialVersionUID = 7789644785781359023L; // ---------------------------------------------- // WINDOW OPTIONS // ---------------------------------------------- public static final Integer WINDOW_WIDTH = 1000; public static final Integer WINDOW_HEIGHT = 650; public static final Font WINDOW_FIXED_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 10); public static final Integer WINDOW_LEFT_SIZE = 325; protected final Database catalog_db; protected Designer designer; // ---------------------------------------------- // GUI ELEMENTS // ---------------------------------------------- ProcedureInfoPanel procInfoPanel; VertexInfoPanel vertexInfoPanel; EdgeInfoPanel edgeInfoPanel; JCheckBox showErrorsBox; JTabbedPane tabbedPane; Vector<GraphVisualizationPanel<DesignerVertex, DesignerEdge>> visualizers = new Vector<GraphVisualizationPanel<DesignerVertex, DesignerEdge>>(); protected DesignerVisualization.MenuHandler menuHandler = new DesignerVisualization.MenuHandler(); protected Map<Integer, JMenuItem> menuItems = new HashMap<Integer, JMenuItem>(); // ---------------------------------------------- // OBSERVERS // ---------------------------------------------- protected final EventObserver<DesignerVertex> OBSERVER_VERTEX = new EventObserver<DesignerVertex>() { public void update(EventObservable<DesignerVertex> o, DesignerVertex arg) { DesignerVisualization.this.showVertexInformation((DesignerVertex)arg); } }; protected final EventObserver<DesignerEdge> OBSERVER_EDGE = new EventObserver<DesignerEdge>() { @Override public void update(EventObservable<DesignerEdge> o, DesignerEdge t) { DesignerVisualization.this.showEdgeInformation((DesignerEdge)t); } }; /** * Constructor */ public DesignerVisualization(ArgumentsParser args) { super(args, "DB Designer Visualizer"); this.catalog_db = args.catalog_db; this.menuHandler = new DesignerVisualization.MenuHandler(); this.init(); } @Override protected void viewerInit() { this.setLayout(new BorderLayout()); this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // ---------------------------------------------- // MENU // ---------------------------------------------- JMenu menu; JMenuItem menuItem; // // File Menu // menu = new JMenu("File"); menu.getPopupMenu().setLightWeightPopupEnabled(false); menu.setMnemonic(KeyEvent.VK_F); menu.getAccessibleContext().setAccessibleDescription("File Menu"); menuBar.add(menu); menuItem = new JMenuItem("Open Schema File"); menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); menuItem.getAccessibleContext().setAccessibleDescription("Open Schema File"); menuItem.addActionListener(this.menuHandler); menuItem.putClientProperty(MenuHandler.MENU_ID, MenuHandler.MENU_SCHEMA_OPEN); this.menuItems.put(MenuHandler.MENU_SCHEMA_OPEN, menuItem); menu.add(menuItem); menu.addSeparator(); menuItem = new JMenuItem("Quit", KeyEvent.VK_Q); menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK)); menuItem.getAccessibleContext().setAccessibleDescription("Quit Program"); menuItem.addActionListener(this.menuHandler); menuItem.putClientProperty(MenuHandler.MENU_ID, MenuHandler.MENU_QUIT); this.menuItems.put(MenuHandler.MENU_QUIT, menuItem); menu.add(menuItem); // ---------------------------------------------- // LEFT-SIDE PANEL // ---------------------------------------------- JPanel leftPanel = new JPanel(new BorderLayout()); this.procInfoPanel = new ProcedureInfoPanel(this); this.procInfoPanel.setBorder(BorderFactory.createTitledBorder("Stored Procedures")); leftPanel.add(this.procInfoPanel, BorderLayout.NORTH); JPanel graphPanel = new JPanel(); graphPanel.setLayout(new BoxLayout(graphPanel, BoxLayout.Y_AXIS)); graphPanel.setBorder(BorderFactory.createTitledBorder("Graph Information")); this.vertexInfoPanel = new VertexInfoPanel(this); graphPanel.add(this.vertexInfoPanel); graphPanel.add(Box.createVerticalStrut(5)); graphPanel.add(new JSeparator()); graphPanel.add(Box.createVerticalStrut(5)); this.edgeInfoPanel = new EdgeInfoPanel(this); graphPanel.add(this.edgeInfoPanel); leftPanel.add(graphPanel, BorderLayout.CENTER); // ---------------------------------------------- // PUT IT ALL TOGETHER! // ---------------------------------------------- this.tabbedPane = new JTabbedPane(); this.tabbedPane.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { // TODO Auto-generated method stub } }); Dimension leftSize = new Dimension(WINDOW_LEFT_SIZE, WINDOW_HEIGHT); leftPanel.setSize(leftSize); leftPanel.setPreferredSize(leftSize); leftPanel.setMaximumSize(leftSize); leftPanel.setMinimumSize(leftSize); this.add(leftPanel, BorderLayout.WEST); this.add(this.tabbedPane, BorderLayout.CENTER); // // Set Defaults // for (Procedure catalog_proc : this.catalog_db.getProcedures()) { if (!catalog_proc.getSystemproc()) { this.procInfoPanel.update(catalog_proc); break; } } // FOR } public ArgumentsParser getArguments() { return (this.args); } public Designer getDesigner() { return this.designer; } public Workload getWorkload() { return this.args.workload; } public VertexInfoPanel getVertexInfoPanel() { return this.vertexInfoPanel; } public EdgeInfoPanel getEdgeInfoPanel() { return this.edgeInfoPanel; } /** * */ public void displayGraphs() { if (this.designer == null) return; Procedure catalog_proc = this.procInfoPanel.getElement(); // // We always need to display the full DependencyGraph // int selected_idx = this.tabbedPane.getSelectedIndex(); final int extra_graphs = 2; //(this.designer.getTempGraph() != null ? 3 : 2); GraphVisualizationPanel<DesignerVertex, DesignerEdge> gpanel = null; if (this.tabbedPane.getTabCount() == 0) { if (this.designer.getFinalGraph() != null) { IGraph<DesignerVertex, DesignerEdge> final_graph = this.designer.getFinalGraph(); gpanel = GraphVisualizationPanel.factory(final_graph, this.OBSERVER_VERTEX, this.OBSERVER_EDGE); this.visualizers.add(gpanel); JPanel final_panel = new JPanel(new BorderLayout()); final_panel.add(this.visualizers.lastElement(), BorderLayout.CENTER); final_panel.add(new PartitionPlanPanel(this), BorderLayout.SOUTH); this.tabbedPane.add(final_panel, "Final"); } AbstractDirectedGraph<DesignerVertex, DesignerEdge> dgraph = this.designer.getDesignerInfo().dgraph; this.visualizers.add(GraphVisualizationPanel.factory(dgraph, this.OBSERVER_VERTEX, this.OBSERVER_EDGE)); this.tabbedPane.add(this.visualizers.lastElement(), dgraph.getClass().getSimpleName()); } else { while (this.tabbedPane.getTabCount() > extra_graphs) { this.tabbedPane.remove(extra_graphs); this.visualizers.remove(extra_graphs); } // WHILE } java.util.List<IGraph<DesignerVertex, DesignerEdge>> graphs = new ArrayList<IGraph<DesignerVertex, DesignerEdge>>(); graphs.addAll(this.designer.getGraphs(catalog_proc)); if (graphs != null) { for (int ctr = 0; ctr < graphs.size(); ctr++) { IGraph<DesignerVertex, DesignerEdge> graph = graphs.get(ctr); this.visualizers.add(GraphVisualizationPanel.factory(graph, this.OBSERVER_VERTEX, this.OBSERVER_EDGE)); String name = (graph.getName() != null ? graph.getName() : graph.getClass().getSimpleName()); this.tabbedPane.add(this.visualizers.lastElement(), name); } // FOR } else { System.err.println("ERROR: The graphs for " + catalog_proc + " are null"); } if (selected_idx >= 0 && selected_idx < this.visualizers.size()) { this.tabbedPane.setSelectedIndex(selected_idx); } else { selected_idx = 0; } // // Select a random vertex and edge // IGraph<DesignerVertex, DesignerEdge> graph = (IGraph<DesignerVertex, DesignerEdge>)this.visualizers.get(selected_idx).getGraph(); for (DesignerVertex v : graph.getVertices()) { if (!graph.getIncidentEdges(v).isEmpty()) { this.visualizers.get(selected_idx).selectVertex(v); this.visualizers.get(selected_idx).selectEdge(CollectionUtil.first(graph.getIncidentEdges(v))); break; } } // FOR } public void executeDesigner() { if (this.args.workload == null) return; DesignerInfo info = new DesignerInfo(this.args); DesignerHints hints = new DesignerHints(); hints.proc_exclude.add("ResetWarehouse"); // hints.proc_whitelist.add("neworder"); // hints.proc_whitelist.add("delivery"); // hints.proc_include.add("slev"); try { this.designer = new Designer(info, hints, this.args); } catch (Exception ex) { ex.printStackTrace(); this.showErrorDialog("Unable to Execute Designer", ex.getMessage()); return; } // this.designer = new BranchAndBoundDesigner(info); new Thread() { public void run() { try { if (DesignerVisualization.this.designer.process() != null) { DesignerVisualization.this.designer.apply(); } DesignerVisualization.this.procInfoPanel.loadProcedures(DesignerVisualization.this.designer.getProcedures()); DesignerVisualization.this.displayGraphs(); } catch (Exception ex) { ex.printStackTrace(); DesignerVisualization.this.showErrorDialog("Designer Error", ex.getMessage()); } }; }.start(); return; } public GraphVisualizationPanel<DesignerVertex, DesignerEdge> getCurrentVisualizer() { return (this.visualizers.get(this.tabbedPane.getSelectedIndex())); } public void showVertexInformation(DesignerVertex vertex) { this.vertexInfoPanel.update(vertex); } public void showEdgeInformation(DesignerEdge edge) { this.edgeInfoPanel.update(edge); } /** * */ protected class MenuHandler extends AbstractMenuHandler { // // Schemas // public static final int MENU_SCHEMA_NEW = 1; public static final int MENU_SCHEMA_OPEN = 2; public static final int MENU_SCHEMA_SAVE = 3; public static final int MENU_QUIT = 4; public void actionPerformed(ActionEvent e) { JMenuItem source = (JMenuItem)(e.getSource()); // // Process the event // Integer id = (Integer)source.getClientProperty(MENU_ID); switch (id) { // -------------------------------------------------------- // OPEN SCHEMA FILE // -------------------------------------------------------- case (MENU_SCHEMA_OPEN): { break; } // -------------------------------------------------------- // QUIT // -------------------------------------------------------- case (MENU_QUIT): { DesignerVisualization.this.setVisible(false); System.exit(0); break; } // -------------------------------------------------------- // UNKNOWN // -------------------------------------------------------- default: System.err.println("Invalid Menu Action: " + source.getName()); } // SWITCH } public void itemStateChanged(ItemEvent e) { JMenuItem source = (JMenuItem)(e.getSource()); String s = "Item event detected.\n" + " Event source: " + source.getText() + " (an instance of " + source.getClass().getName() + ")\n" + " New state: " + ((e.getStateChange() == ItemEvent.SELECTED) ? "selected":"unselected") + "\n\n"; System.err.println(s); } } // END CLASS /** * @param args */ public static void main(final String[] vargs) throws Exception { final ArgumentsParser args = ArgumentsParser.load(vargs); //edu.uci.ics.jung.samples.TreeLayoutDemo.main(args); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { DesignerVisualization gui = new DesignerVisualization(args); gui.setVisible(true); gui.executeDesigner(); } // RUN }); } }