| /*========================================================================= |
| * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. |
| * This product is protected by U.S. and international copyright |
| * and intellectual property laws. Pivotal products are covered by |
| * more patents listed at http://www.pivotal.io/patents. |
| *========================================================================= |
| */ |
| package com.gemstone.sequence.gemfire; |
| |
| import com.gemstone.gemfire.internal.sequencelog.GraphType; |
| import com.gemstone.gemfire.internal.sequencelog.io.Filter; |
| import com.gemstone.gemfire.internal.sequencelog.io.GraphReader; |
| import com.gemstone.gemfire.internal.sequencelog.model.*; |
| import com.gemstone.sequence.*; |
| |
| import javax.swing.*; |
| import java.awt.event.*; |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.util.*; |
| import java.util.regex.Pattern; |
| |
| /** |
| * @author dsmith |
| */ |
| public class GemfireSequenceDisplay { |
| |
| private JLabel selectedGraphsLabel; |
| private SelectGraphDialog selectGraphDialog; |
| |
| private Map<GraphID, Map<String, Lifeline>> lineMap = new HashMap(); |
| private Map<GraphID, List<Arrow>> arrowMap = new HashMap(); |
| private SequenceDiagram sequenceDiagram; |
| private JFrame frame; |
| private SequencePanel sequencePanel; |
| |
| /** |
| * Create the GUI and show it. For thread safety, |
| * this method should be invoked from the |
| * event-dispatching thread. |
| * |
| * @param graphs |
| * @param lineMapper |
| */ |
| private void createAndShowGUI(final GraphSet graphs, LineMapper lineMapper) { |
| //Create and set up the window. |
| |
| frame = new JFrame("SequenceDiagram"); |
| frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
| |
| createMenu(); |
| createSequenceDiagram(graphs, lineMapper); |
| createSequenceMaps(graphs); |
| |
| createSelectGraphDialog(graphs); |
| |
| // for (GraphID id : graphs.getMap().keySet()) { |
| // showSubDiagram(id); |
| // |
| // } |
| |
| sequencePanel = new SequencePanel(sequenceDiagram); |
| frame.getContentPane().add(sequencePanel); |
| //Display the window. |
| frame.pack(); |
| frame.setVisible(true); |
| showGraphSelector(); |
| } |
| |
| private void createMenu() { |
| JMenuBar menuBar = new JMenuBar(); |
| |
| JMenu sequenceMenu = new JMenu("Sequence"); |
| sequenceMenu.setMnemonic(KeyEvent.VK_S); |
| sequenceMenu.getAccessibleContext().setAccessibleDescription( |
| "The only menu in this program that has menu items"); |
| menuBar.add(sequenceMenu); |
| JMenuItem selectGraphs = new JMenuItem("Choose Graphs", |
| KeyEvent.VK_G); |
| selectGraphs.setAccelerator(KeyStroke.getKeyStroke( |
| KeyEvent.VK_G, ActionEvent.ALT_MASK)); |
| selectGraphs.getAccessibleContext().setAccessibleDescription( |
| "Select what graphs to display"); |
| selectGraphs.setActionCommand("selectgraphs"); |
| selectGraphs.addActionListener(new ActionListener() { |
| |
| public void actionPerformed(ActionEvent e) { |
| showGraphSelector(); |
| } |
| }); |
| |
| sequenceMenu.add(selectGraphs); |
| frame.setJMenuBar(menuBar); |
| } |
| |
| private void createSelectGraphDialog(final GraphSet graphs) { |
| selectGraphDialog = new SelectGraphDialog(graphs); |
| selectGraphDialog.addSelectionListener(new SelectGraphDialog.SelectionListener() { |
| |
| public void selectionChanged(List<GraphID> selectedIds) { |
| updateGraphs(selectedIds); |
| } |
| }); |
| selectGraphDialog.pack(); |
| } |
| |
| private void updateGraphs(List<GraphID> selectedIds) { |
| List<GraphID> existingDiagrams =(List) sequenceDiagram.getSubDiagramsNames(); |
| for(GraphID id : selectedIds) { |
| showSubDiagram(id); |
| existingDiagrams.remove(id); |
| } |
| for(GraphID id : existingDiagrams) { |
| hideSubDiagram(id); |
| } |
| |
| sequenceDiagram.resizeMe(sequenceDiagram.getWidth(), sequenceDiagram.getHeight()); |
| sequencePanel.revalidate(); |
| sequencePanel.repaint(); |
| // sequenceDiagram.revalidate(); |
| // sequenceDiagram.repaint(); |
| } |
| |
| private void showGraphSelector() { |
| selectGraphDialog.setVisible(true); |
| } |
| |
| private void hideGraphSelector() { |
| selectGraphDialog.setVisible(false); |
| } |
| |
| // private static SequenceDiagram createSequenceDiagram() { |
| // long startTime = System.currentTimeMillis(); |
| // List<Lifeline> lines = new ArrayList<Lifeline>(); |
| // List<Arrow> arrows = new ArrayList<Arrow>(); |
| // for(int i =0 ; i < 10; i++) { |
| // List<LifelineState> states = new ArrayList<LifelineState>(); |
| // for(int j =0; j < 5; j++) { |
| // LifelineState state = new LifelineState(startTime + 20* j, startTime + 20 * j + 20); |
| // states.add(state); |
| // } |
| // Lifeline line = new Lifeline(i, states); |
| // lines.add(line); |
| // |
| // if(i > 0) { |
| // Arrow arrow = new Arrow("arrow" + i, line, lines.get(i - 1), line.getStates().get(2)); |
| // arrows.add(arrow); |
| // } |
| // } |
| // |
| // SequenceDiagram diag = new SequenceDiagram(startTime, startTime + 20 * 5, lines, arrows); |
| // return diag; |
| // } |
| |
| private void createSequenceMaps(GraphSet graphs) { |
| |
| Map<GraphID, Graph> map = graphs.getMap(); |
| for (Map.Entry<GraphID, Graph> entry : map.entrySet()) { |
| GraphID graphId = entry.getKey(); |
| Graph graph = entry.getValue(); |
| Map<String, Lifeline> lines = new LinkedHashMap<String, Lifeline>(graphs.getLocations().size()); |
| List<Arrow> arrows = new ArrayList<Arrow>(); |
| Map<Vertex, LifelineState> states = new HashMap<Vertex, LifelineState>(); |
| for (String location : graphs.getLocations()) { |
| lines.put(location, new Lifeline(graphId, location)); |
| } |
| |
| Collection<Edge> edges = graph.getEdges(); |
| for (Edge edge : edges) { |
| Vertex dest = edge.getDest(); |
| Vertex source = edge.getSource(); |
| if (dest == null) { |
| dest = source; |
| } |
| if (source == null) { |
| source = dest; |
| } |
| LifelineState destState = states.get(dest); |
| if (destState == null) { |
| final Lifeline lifeline = lines.get(dest.getName()); |
| destState = createState(lifeline, graphs, dest); |
| lifeline.addState(destState); |
| states.put(dest, destState); |
| } |
| LifelineState sourceState = states.get(source); |
| if (sourceState == null) { |
| final Lifeline lifeline = lines.get(source.getName()); |
| sourceState = createState(lifeline, graphs, source); |
| lifeline.addState(sourceState); |
| states.put(source, sourceState); |
| } |
| Arrow arrow = new Arrow(edge.getName(), sourceState, destState); |
| arrows.add(arrow); |
| destState.addInboundArrow(arrow); |
| } |
| |
| |
| lineMap.put(graphId, lines); |
| arrowMap.put(graphId, arrows); |
| } |
| } |
| |
| public void showSubDiagram(GraphID id) { |
| sequenceDiagram.addSubDiagram(id, lineMap.get(id), arrowMap.get(id)); |
| } |
| |
| public void hideSubDiagram(GraphID id) { |
| sequenceDiagram.removeSubDiagram(id); |
| } |
| |
| private SequenceDiagram createSequenceDiagram(GraphSet graphs, LineMapper lineMapper) { |
| |
| sequenceDiagram = new SequenceDiagram(graphs.getMinTime(), graphs.getMaxTime(), graphs.getLocations(), lineMapper); |
| return sequenceDiagram; |
| } |
| |
| /** |
| * @param graphId |
| * @param lifeline |
| * @param graphs |
| * @param dest |
| * @return |
| */ |
| private static LifelineState createState(Lifeline lifeline, GraphSet graphs, Vertex dest) { |
| long start = dest.getTimestamp(); |
| long end = dest.getNextVertexOnDest() == null ? graphs.getMaxTime() : dest.getNextVertexOnDest().getTimestamp(); |
| return new LifelineState(lifeline, dest.getState(), start, end); |
| } |
| |
| public static void main(String[] args) throws IOException { |
| File[] files; |
| Set<String> keyFilters = new HashSet<String>(); |
| boolean areGemfireLogs = false; |
| if (args.length > 0) { |
| ArrayList<File> fileList = new ArrayList<File>(); |
| for (int i =0; i < args.length; i++) { |
| String arg = args[i]; |
| if(arg.equals("-filterkey")) { |
| keyFilters.add(args[i+1]); |
| i++; |
| } else if(arg.equals("-logs")) { |
| areGemfireLogs = true; |
| } |
| else { |
| fileList.add(new File(args[i])); |
| } |
| |
| } |
| files = fileList.toArray(new File[0]); |
| } else { |
| System.err.println("Usage: java -jar sequence.jar (-logs) (-filterkey key)* <file>+\n\n" + |
| "\t-logs (expiremental) instead of using .graph files, parse the gemfire logs to generate the sequence display" + |
| "\t-filterkey a java regular expression to match against key names. If specified\n" + |
| "The list of key sequence diagrams will only contain matching keys"); |
| System.exit(1); |
| return; |
| } |
| |
| final GraphSet graphs; |
| |
| graphs = getGraphs(areGemfireLogs, keyFilters, files); |
| |
| final LineMapper lineMapper = getLineMapper(files); |
| final GemfireSequenceDisplay display = new GemfireSequenceDisplay(); |
| //Schedule a job for the event-dispatching thread: |
| //creating and showing this application's GUI. |
| javax.swing.SwingUtilities.invokeLater(new Runnable() { |
| public void run() { |
| display.createAndShowGUI(graphs, lineMapper); |
| } |
| }); |
| } |
| |
| private static GraphSet getGraphs(boolean useLogFiles, Set<String> keyFilters, File[] files) |
| throws IOException { |
| Filter graphFilter = new KeyFilter(keyFilters); |
| |
| |
| GraphReader reader = new GraphReader(files); |
| final GraphSet graphs; |
| if(keyFilters.isEmpty()) { |
| graphs = reader.readGraphs(useLogFiles); |
| } else { |
| graphs = reader.readGraphs(graphFilter, useLogFiles); |
| } |
| return graphs; |
| } |
| |
| /** |
| * @param files |
| * @return |
| */ |
| private static LineMapper getLineMapper(File[] files) { |
| if(HydraLineMapper.isInHydraRun(files)) { |
| return new HydraLineMapper(files); |
| } else { |
| return new DefaultLineMapper(); |
| } |
| } |
| |
| private static class KeyFilter implements Filter { |
| Set<Pattern> patterns = new HashSet<Pattern>(); |
| |
| |
| public KeyFilter(Set<String> keyFilters) { |
| for(String filterString : keyFilters) { |
| patterns.add(Pattern.compile(filterString)); |
| } |
| } |
| |
| public boolean accept(GraphType graphType, String name, String edgeName, |
| String source, String dest) { |
| if(graphType.equals(GraphType.KEY)) { |
| for(Pattern pattern : patterns) { |
| if(pattern.matcher(name).find()) { |
| return true; |
| } |
| } |
| |
| return false; |
| } else { |
| return true; |
| } |
| } |
| |
| public boolean acceptPattern(GraphType graphType, Pattern pattern, |
| String edgeName, String source, String dest) { |
| return true; |
| } |
| |
| } |
| |
| } |