package com.algomagic.atn.vis; import att.grappa.*; import java.util.Properties; import java.util.Enumeration; import java.io.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import javax.swing.border.*; public class ATNVisualizer extends JFrame implements ATNVisualizerConstants, GrappaConstants { private Properties _properties; private GrappaPanel _grappaPanel; private Graph _graph; public ATNVisualizer( String log1, String log2 ) { initATNVisualizer( log1, log2 ); } private void initATNVisualizer( String log1, String log2 ) { loadProperties( ); addWindowListener( new WindowAdapter( ) { public void windowClosing( WindowEvent we ) { Window w = we.getWindow( ); w.setVisible( false ); w.dispose( ); System.exit( 0 ); } }); SidePanel leftSide = new SidePanel( log1, LEFT_SIDE ); SidePanel rightSide = null; Container contentPane = getContentPane( ); contentPane.setLayout( new BoxLayout( contentPane, BoxLayout.X_AXIS ) ); contentPane.add( leftSide ); if( log2 != null ) { rightSide = new SidePanel( log2, RIGHT_SIDE ); contentPane.add( rightSide ); } setTitle( _properties.getProperty( WINDOW_TITLE_PROP, WINDOW_TITLE_DEFAULT ) ); setSize( Integer.parseInt( _properties.getProperty( WINDOW_WIDTH_PROP, WINDOW_WIDTH_DEFAULT ) ), Integer.parseInt( _properties.getProperty( WINDOW_HEIGHT_PROP, WINDOW_HEIGHT_DEFAULT ) ) ); show( ); leftSide.resetDividerLocations( ); if( log2 != null ) { rightSide.resetDividerLocations( ); } } private void hideGraph( Graph g ) { Enumeration nodes = _graph.nodeElements( ); Enumeration edges = _graph.edgeElements( ); while( nodes.hasMoreElements( ) ) { Node n = (Node) nodes.nextElement( ); setInvis( n ); } while( edges.hasMoreElements( ) ) { Edge e = (Edge) edges.nextElement( ); setInvis( e ); } } private Graph loadGraph( String dotFile ) { Parser parser = null; try { parser = new Parser( new FileInputStream( dotFile ) ); parser.parse( ); } catch( Exception e ) { e.printStackTrace( ); System.exit( 1 ); } return parser.getGraph( ); } private void formatGraph( Graph g ) { try { Process formater = Runtime.getRuntime( ).exec( "dot" ); GrappaSupport.filterGraph( g, formater ); formater.destroy( ); g.repaint( ); } catch( Exception e ) { e.printStackTrace( ); } } private void redrawAndPause( int millis ) { _graph.resync( ); _graph.repaint( ); try { Thread.currentThread( ).sleep( millis ); } catch( Exception e ) { } } private void setSolid( Element e ) { e.setAttribute( FONTSTYLE_ATTR, "normal" ); e.setAttribute( STYLE_ATTR, "solid" ); } private void setBold( Element e ) { e.setAttribute( FONTSTYLE_ATTR, "bold" ); e.setAttribute( STYLE_ATTR, "bold" ); } private void setInvis( Element e ) { e.setAttribute( FONTSTYLE_ATTR, "normal" ); e.setAttribute( STYLE_ATTR, "invis" ); } private Edge getEdgeBetween( Node head, Node tail ) { Enumeration edges = _graph.edgeElements( ); while( edges.hasMoreElements( ) ) { Edge e = (Edge) edges.nextElement( ); Node t = e.getHead( ); Node h = e.getTail( ); if( h.getName( ).equals( head.getName( ) ) && t.getName( ).equals( tail.getName( ) ) ) { return e; } } return null; } private void loadProperties( ) { String propsFileName = System.getProperty( CONFIG_FILE_PROP, CONFIG_FILE_DEFAULT ); File file = new File( propsFileName ); if( file.exists( ) ) { _properties = new Properties( ); try { _properties.load( new FileInputStream( file ) ); } catch( FileNotFoundException fnfe ) { _properties = getDefaultProperties( ); } catch( IOException ioe ) { _properties = getDefaultProperties( ); } } else { _properties = getDefaultProperties( ); } } private Properties getDefaultProperties( ) { Properties p = new Properties( ); p.setProperty( WINDOW_TITLE_PROP, WINDOW_TITLE_DEFAULT ); p.setProperty( WINDOW_HEIGHT_PROP, WINDOW_HEIGHT_DEFAULT ); p.setProperty( WINDOW_WIDTH_PROP, WINDOW_WIDTH_DEFAULT ); return p; } public static void main( String[] args ) { ATNVisualizer atnVis = null; if( args.length == 1 ) { atnVis = new ATNVisualizer( args[0], null ); } else if ( args.length == 2 ) { atnVis = new ATNVisualizer( args[0], args[1] ); } else { System.err.println( "usage: ATNVisualizer []" ); System.exit( 1 ); } } private class SidePanel extends JPanel { GrappaPanel _grappaPanel; Graph _graph; JPanel _listPanel; JPanel _messagePanel; JPanel _graphPanel; JCheckBox _scaleButton; JSplitPane _top; JSplitPane _complete; int _side; boolean _graphScaleToFit; Dimension _unScaledDim; public SidePanel( String transcriptFile, int side ) { super( ); _side = side; _listPanel = new JPanel( new BorderLayout( ) ); _messagePanel = new JPanel( new BorderLayout( ) ); _graphPanel = new JPanel( new BorderLayout( ) ); _messagePanel.setMaximumSize( new Dimension( 2000, 100 ) ); // _graphPanel.addComponentListener( new ComponentAdapter( ) { // public void componentResized( ComponentEvent e ) { // if( _graphScaleToFit == true ) { // setGraphToFit( e.getComponent( ).getSize( ) ); // } // } // }); // _scaleButton = new JCheckBox( "scale graph to fit" ); // _scaleButton.setSelected( true ); // _scaleButton.addItemListener( new ItemListener( ) { // public void itemStateChanged( ItemEvent e ) { // if( e.getStateChange( ) == ItemEvent.DESELECTED ) { // setGraphScaleToFit( false ); // } else { // setGraphScaleToFit( true ); // } // } // }); setPanelBorder( _listPanel, "Creds and Policies" ); setPanelBorder( _messagePanel, "Output Log" ); setPanelBorder( _graphPanel, "Trust Negotiation Graph" ); if( _side == LEFT_SIDE ) { _top = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, _listPanel, _graphPanel ); } else { _top = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, _graphPanel, _listPanel); _top.setResizeWeight( 1.0 ); } _complete = new JSplitPane( JSplitPane.VERTICAL_SPLIT, _top, _messagePanel ); _complete.setResizeWeight( 1.0 ); _complete.addComponentListener( new ComponentAdapter( ) { public void componentResized( ComponentEvent e ) { System.out.println( "resized: " + e.getComponent( ).getSize( ) ); } public void componentMoved( ComponentEvent e ) { System.out.println( "moved: " + e.getComponent( ).getSize( ) ); } }); _graph = loadGraph( transcriptFile ); formatGraph( _graph ); _grappaPanel = new GrappaPanel( _graph ); _grappaPanel.setScaleToFit( false ); JScrollPane jsp = new JScrollPane( ); jsp.getViewport( ).setScrollMode( JViewport.BACKINGSTORE_SCROLL_MODE ); jsp.getViewport( ).setBackground( Color.white ); jsp.setViewportView( _grappaPanel ); _graphPanel.add( jsp, BorderLayout.CENTER ); setLayout( new BorderLayout( ) ); add( _complete, BorderLayout.CENTER ); _top.setOneTouchExpandable( true ); _complete.setOneTouchExpandable( true ); } public void resetDividerLocations( ) { if( _side == LEFT_SIDE ) { _top.setDividerLocation( 0.25 ); } else { _top.setDividerLocation( 0.75 ); } _complete.setDividerLocation( 0.75 ); } public void setGraphScaleToFit( boolean b ) { _graphScaleToFit = b; if( b == false ) { setGraphToFit( _unScaledDim ); } else { setGraphToFit( _graphPanel.getSize( ) ); } } public void setGraphToFit( Dimension d ) { d.setSize( d.getWidth( ) - 50, d.getHeight( ) - 50 ); _grappaPanel.setScaleToSize( d ); _graph.resync( ); _graph.repaint( ); } } private void setPanelBorder( JComponent comp, String label ) { Border empty = BorderFactory.createEmptyBorder( 0, 0, 0, 0 ); Border etched = BorderFactory.createEtchedBorder( ); TitledBorder title = BorderFactory.createTitledBorder( etched, label ); title.setTitleJustification( TitledBorder.RIGHT ); Border compound = BorderFactory.createCompoundBorder( title, empty ); comp.setBorder( compound ); } private void printGraph( Graph g ) { Enumeration nodes = g.nodeElements( ); Enumeration edges = g.edgeElements( ); while( nodes.hasMoreElements( ) ) { System.out.println( "----------------------------------------------------------------------" ); Node n = (Node) nodes.nextElement( ); n.printAllAttributes = true; System.out.println( n.getName( ) ); Enumeration e = n.getAttributePairs( ); while( e.hasMoreElements( ) ) { System.out.println( e.nextElement( ) ); } } while( edges.hasMoreElements( ) ) { System.out.println( "----------------------------------------------------------------------" ); Edge e = (Edge) edges.nextElement( ); e.printAllAttributes = true; System.out.println( e.getName( ) ); Enumeration en = e.getAttributePairs( ); while( en.hasMoreElements( ) ) { System.out.println( en.nextElement( ) ); } } System.out.println( "======================================================================" ); g.printSubgraph( new PrintWriter( System.err, true ) ); } public void animate( ) { Node a,b,c,d,e,f,g; a = _graph.findNodeByName( "A" ); b = _graph.findNodeByName( "B" ); c = _graph.findNodeByName( "C" ); d = _graph.findNodeByName( "D" ); e = _graph.findNodeByName( "E" ); f = _graph.findNodeByName( "F" ); g = _graph.findNodeByName( "G" ); Edge ab, bc, cd, ce, ef, fg; ab = getEdgeBetween( a,b ); bc = getEdgeBetween( b,c ); cd = getEdgeBetween( c,d ); ce = getEdgeBetween( c,e ); ef = getEdgeBetween( e,f ); fg = getEdgeBetween( f,g ); while (true) { // ---------------------------------------------------------------------- setBold( a ); redrawAndPause( 1000 ); setBold( b ); setBold( ab ); redrawAndPause( 1000 ); // ---------------------------------------------------------------------- setSolid( a ); setSolid( b ); setSolid( ab ); // ---------------------------------------------------------------------- redrawAndPause( 1000 ); setBold( c ); setBold( bc ); redrawAndPause( 1000 ); setBold( e ); setBold( ce ); redrawAndPause( 1000 ); setBold( f ); setBold( ef ); redrawAndPause( 1000 ); // ---------------------------------------------------------------------- setSolid( c ); setSolid( bc ); setSolid( e ); setSolid( ce ); setSolid( f ); setSolid( ef ); redrawAndPause( 1000 ); // ---------------------------------------------------------------------- setBold( g ); setBold( fg ); redrawAndPause( 1000 ); // ---------------------------------------------------------------------- setSolid( g ); setSolid( fg ); redrawAndPause( 1000 ); // ---------------------------------------------------------------------- setBold( d ); setBold( cd ); redrawAndPause( 1000 ); // ---------------------------------------------------------------------- setSolid( d ); setSolid( cd ); redrawAndPause( 2000 ); // ---------------------------------------------------------------------- hideGraph( _graph ); redrawAndPause( 1000 ); } } }