Package com.eviware.soapui.support.log

Source Code of com.eviware.soapui.support.log.JLogList$ClearAction

/*
*  soapUI, copyright (C) 2004-2011 eviware.com
*
*  soapUI is free software; you can redistribute it and/or modify it under the
*  terms of version 2.1 of the GNU Lesser General Public License as published by
*  the Free Software Foundation.
*
*  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
*  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*  See the GNU Lesser General Public License for more details at gnu.org.
*/

package com.eviware.soapui.support.log;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.concurrent.Future;

import javax.swing.AbstractAction;
import javax.swing.AbstractListModel;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import org.apache.commons.collections.list.TreeList;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.support.UISupport;

/**
* Component for displaying log entries
*
* @author Ole.Matzura
*/

public class JLogList extends JPanel
{
  private long maxRows = 1000;
  private JList logList;
  private SimpleAttributeSet requestAttributes;
  private SimpleAttributeSet responseAttributes;
  private LogListModel model;
  private List<Logger> loggers = new ArrayList<Logger>();
  private InternalLogAppender internalLogAppender = new InternalLogAppender();
  private boolean tailing = true;
  private Stack<Object> linesToAdd = new Stack<Object>();
  private EnableAction enableAction;
  private JCheckBoxMenuItem enableMenuItem;
  private final String title;
  private boolean released;
  private Future<?> future;

  public JLogList( String title )
  {
    super( new BorderLayout() );
    this.title = title;

    model = new LogListModel();
    logList = new JList( model );
    logList.setToolTipText( title );
    logList.setCellRenderer( new LogAreaCellRenderer() );
    logList.setPrototypeCellValue( "Testing 123" );
    logList.setFixedCellWidth( -1 );

    JPopupMenu listPopup = new JPopupMenu();
    listPopup.add( new ClearAction() );
    enableAction = new EnableAction();
    enableMenuItem = new JCheckBoxMenuItem( enableAction );
    enableMenuItem.setSelected( true );
    listPopup.add( enableMenuItem );
    listPopup.addSeparator();
    listPopup.add( new CopyAction() );
    listPopup.add( new SetMaxRowsAction() );
    listPopup.addSeparator();
    listPopup.add( new ExportToFileAction() );

    logList.setComponentPopupMenu( listPopup );

    setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ) );
    JScrollPane scrollPane = new JScrollPane( logList );
    UISupport.addPreviewCorner( scrollPane, true );
    add( scrollPane, BorderLayout.CENTER );

    requestAttributes = new SimpleAttributeSet();
    StyleConstants.setForeground( requestAttributes, Color.BLUE );

    responseAttributes = new SimpleAttributeSet();
    StyleConstants.setForeground( responseAttributes, Color.GREEN );

    try
    {
      maxRows = Long.parseLong( SoapUI.getSettings().getString( "JLogList#" + title, "1000" ) );
    }
    catch( NumberFormatException e )
    {
    }
  }

  public void clear()
  {
    model.clear();
  }

  public JList getLogList()
  {
    return logList;
  }

  public long getMaxRows()
  {
    return maxRows;
  }

  public void setMaxRows( long maxRows )
  {
    this.maxRows = maxRows;
  }

  public synchronized void addLine( Object line )
  {
    if( !isEnabled() )
      return;

    synchronized( model.lines )
    {
      if( line instanceof LoggingEvent )
      {
        LoggingEvent ev = ( LoggingEvent )line;
        linesToAdd.push( new LoggingEventWrapper( ev ) );

        if( ev.getThrowableInformation() != null )
        {
          Throwable t = ev.getThrowableInformation().getThrowable();
          StringWriter sw = new StringWriter();
          PrintWriter pw = new PrintWriter( sw );
          t.printStackTrace( pw );
          StringTokenizer st = new StringTokenizer( sw.toString(), "\r\n" );
          while( st.hasMoreElements() )
            linesToAdd.push( "   " + st.nextElement() );
        }
      }
      else
      {
        linesToAdd.push( line );
      }
    }
    if( future == null )
    {
      released = false;
      future = SoapUI.getThreadPool().submit( model );
    }
  }

  public void setEnabled( boolean enabled )
  {
    super.setEnabled( enabled );
    logList.setEnabled( enabled );
    enableMenuItem.setSelected( enabled );
  }

  private static class LogAreaCellRenderer extends DefaultListCellRenderer
  {
    private Map<Level, Color> levelColors = new HashMap<Level, Color>();

    private LogAreaCellRenderer()
    {
      levelColors.put( Level.ERROR, new Color( 192, 0, 0 ) );
      levelColors.put( Level.INFO, new Color( 0, 92, 0 ) );
      levelColors.put( Level.WARN, Color.ORANGE.darker().darker() );
      levelColors.put( Level.DEBUG, new Color( 0, 0, 128 ) );
    }

    public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected,
        boolean cellHasFocus )
    {
      JLabel component = ( JLabel )super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );

      if( value instanceof LoggingEventWrapper )
      {
        LoggingEventWrapper eventWrapper = ( LoggingEventWrapper )value;

        if( levelColors.containsKey( eventWrapper.getLevel() ) )
          component.setForeground( levelColors.get( eventWrapper.getLevel() ) );
      }

      // Limit the length of the tool tip, to prevent long delays.
      String toolTip = component.getText();
      if( toolTip != null && toolTip.length() > 1000 )
        toolTip = toolTip.substring( 0, 1000 );
      component.setToolTipText( toolTip );

      return component;
    }
  }

  private final static class LoggingEventWrapper
  {
    private final LoggingEvent loggingEvent;
    private String str;

    public LoggingEventWrapper( LoggingEvent loggingEvent )
    {
      this.loggingEvent = loggingEvent;
    }

    public Level getLevel()
    {
      return loggingEvent.getLevel();
    }

    public String toString()
    {
      if( str == null )
      {
        StringBuilder builder = new StringBuilder();
        builder.append( new Date( loggingEvent.timeStamp ) );
        builder.append( ':' ).append( loggingEvent.getLevel() ).append( ':' ).append( loggingEvent.getMessage() );
        str = builder.toString();
      }

      return str;
    }
  }

  public void addLogger( String loggerName, boolean addAppender )
  {
    Logger logger = Logger.getLogger( loggerName );
    if( addAppender )
      logger.addAppender( internalLogAppender );

    loggers.add( logger );
  }

  public Logger[] getLoggers()
  {
    return loggers.toArray( new Logger[loggers.size()] );
  }

  public void setLevel( Level level )
  {
    for( Logger logger : loggers )
    {
      logger.setLevel( level );
    }
  }

  public Logger getLogger( String loggerName )
  {
    for( Logger logger : loggers )
    {
      if( logger.getName().equals( loggerName ) )
        return logger;
    }

    return null;
  }

  private class InternalLogAppender extends AppenderSkeleton
  {
    protected void append( LoggingEvent event )
    {
      addLine( event );
    }

    public void close()
    {
    }

    public boolean requiresLayout()
    {
      return false;
    }
  }

  public boolean monitors( String loggerName )
  {
    for( Logger logger : loggers )
    {
      if( loggerName.startsWith( logger.getName() ) )
        return true;
    }

    return false;
  }

  public void removeLogger( String loggerName )
  {
    for( Logger logger : loggers )
    {
      if( loggerName.equals( logger.getName() ) )
      {
        logger.removeAppender( internalLogAppender );
      }
    }
  }

  public boolean isTailing()
  {
    return tailing;
  }

  public void setTailing( boolean tail )
  {
    this.tailing = tail;
  }

  private class ClearAction extends AbstractAction
  {
    public ClearAction()
    {
      super( "Clear" );
    }

    public void actionPerformed( ActionEvent e )
    {
      model.clear();
    }
  }

  private class SetMaxRowsAction extends AbstractAction
  {
    public SetMaxRowsAction()
    {
      super( "Set Max Rows" );
    }

    public void actionPerformed( ActionEvent e )
    {
      String val = UISupport.prompt( "Set maximum number of log rows to keep", "Set Max Rows",
          String.valueOf( maxRows ) );
      if( val != null )
      {
        try
        {
          maxRows = Long.parseLong( val );
          SoapUI.getSettings().setString( "JLogList#" + title, val );
        }
        catch( NumberFormatException e1 )
        {
          UISupport.beep();
        }
      }
    }
  }

  private class ExportToFileAction extends AbstractAction
  {
    public ExportToFileAction()
    {
      super( "Export to File" );
    }

    public void actionPerformed( ActionEvent e )
    {
      if( model.getSize() == 0 )
      {
        UISupport.showErrorMessage( "Log is empty; nothing to export" );
        return;
      }

      File file = UISupport.getFileDialogs().saveAs( JLogList.this, "Save Log [] to File", "*.log", "*.log", null );
      if( file != null )
        saveToFile( file );
    }
  }

  private class CopyAction extends AbstractAction
  {
    public CopyAction()
    {
      super( "Copy to clipboard" );
    }

    public void actionPerformed( ActionEvent e )
    {
      Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

      StringBuffer buf = new StringBuffer();
      int[] selectedIndices = logList.getSelectedIndices();
      if( selectedIndices.length == 0 )
      {
        for( int c = 0; c < logList.getModel().getSize(); c++ )
        {
          buf.append( logList.getModel().getElementAt( c ).toString() );
          buf.append( "\r\n" );
        }
      }
      else
      {
        for( int c = 0; c < selectedIndices.length; c++ )
        {
          buf.append( logList.getModel().getElementAt( selectedIndices[c] ).toString() );
          buf.append( "\r\n" );
        }
      }

      StringSelection selection = new StringSelection( buf.toString() );
      clipboard.setContents( selection, selection );
    }
  }

  private class EnableAction extends AbstractAction
  {
    public EnableAction()
    {
      super( "Enable" );
    }

    public void actionPerformed( ActionEvent e )
    {
      JLogList.this.setEnabled( enableMenuItem.isSelected() );
    }
  }

  /**
   * Internal list model that for optimized storage and notifications
   *
   * @author Ole.Matzura
   */

  @SuppressWarnings( "unchecked" )
  private final class LogListModel extends AbstractListModel implements Runnable
  {
    private List<Object> lines = new TreeList();

    public int getSize()
    {
      synchronized( lines )
      {
        return lines.size();
      }
    }

    public Object getElementAt( int index )
    {
      synchronized( lines )
      {
        return lines.get( index );
      }
    }

    public void clear()
    {
      int sz = lines.size();
      if( sz == 0 )
        return;

      synchronized( lines )
      {
        lines.clear();
        fireIntervalRemoved( this, 0, sz - 1 );
      }
    }

    public void run()
    {
      Thread.currentThread().setName( "LogList Updater for " + title );

      try
      {
        while( !released && !linesToAdd.isEmpty() )
        {
          try
          {
            if( !linesToAdd.isEmpty() )
            {
              SwingUtilities.invokeAndWait( new Runnable()
              {
                public void run()
                {
                  try
                  {
                    synchronized( lines )
                    {
                      while( !linesToAdd.isEmpty() )
                      {
                        int sz = lines.size();
                        lines.addAll( linesToAdd );
                        linesToAdd.clear();
                        fireIntervalAdded( LogListModel.this, sz, lines.size() - sz );
                      }

                      int cnt = 0;
                      while( lines.size() > maxRows )
                      {
                        lines.remove( 0 );
                        cnt++ ;
                      }

                      if( cnt > 0 )
                        fireIntervalRemoved( LogListModel.this, 0, cnt - 1 );

                      if( tailing )
                      {
                        logList.ensureIndexIsVisible( lines.size() - 1 );
                      }
                    }
                  }
                  catch( Throwable e )
                  {
                    SoapUI.logError( e );
                  }
                }
              } );
            }

            Thread.sleep( 500 );
          }
          catch( Throwable e )
          {
            SoapUI.logError( e );
          }
        }
      }
      finally
      {
        future = null;
      }
    }
  }

  public void release()
  {
    released = true;
  }

  public void saveToFile( File file )
  {
    try
    {
      PrintWriter writer = new PrintWriter( file );
      for( int c = 0; c < model.getSize(); c++ )
      {
        writer.println( model.getElementAt( c ) );
      }

      writer.close();
    }
    catch( Exception e )
    {
      UISupport.showErrorMessage( e );
    }
  }
}
TOP

Related Classes of com.eviware.soapui.support.log.JLogList$ClearAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.