Package net.sourceforge.squirrel_sql.client.gui

Source Code of net.sourceforge.squirrel_sql.client.gui.ViewLogsSheet$Refresher

package net.sourceforge.squirrel_sql.client.gui;

/*
* Copyright (C) 2002-2006 Colin Bell
* colbell@users.sourceforge.net
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import net.sourceforge.squirrel_sql.client.IApplication;
import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DialogWidget;
import net.sourceforge.squirrel_sql.client.preferences.SquirrelPreferences;
import net.sourceforge.squirrel_sql.client.util.ApplicationFiles;
import net.sourceforge.squirrel_sql.fw.gui.CursorChanger;
import net.sourceforge.squirrel_sql.fw.gui.DirectoryListComboBox;
import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
import net.sourceforge.squirrel_sql.fw.gui.TextPopupMenu;
import net.sourceforge.squirrel_sql.fw.gui.ToolBar;
import net.sourceforge.squirrel_sql.fw.util.StringManager;
import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
import net.sourceforge.squirrel_sql.fw.util.Utilities;
import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;

/**
* This sheet shows the SQuirreL log files.
*
* @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
*/
public class ViewLogsSheet extends DialogWidget
{
  /** Internationalized strings for this class. */
  private static final StringManager s_stringMgr =
    StringManagerFactory.getStringManager(ViewLogsSheet.class);

  /** Logger for this class. */
  private static final ILogger s_log = LoggerController.createLogger(ViewLogsSheet.class);

  /** Singleton instance of this class. */
  private static ViewLogsSheet s_instance;

  /** Application API. */
  private final IApplication _app;

  /** Preferences */
  private final SquirrelPreferences _prefs;

  /** Combo box containing all the log files. */
  private final LogsComboBox _logDirCmb = new LogsComboBox();

  /** Text area containing the log contents. */
  private final JTextArea _logContentsTxt = new JTextArea(20, 50);

  /** Button that refreshes the log contents. */
  private final JButton _refreshBtn = new JButton(s_stringMgr.getString("ViewLogsSheet.refresh"));

  private final JCheckBox _errorChkbox = new JCheckBox("Errors");

  private final JCheckBox _debugChkbox = new JCheckBox("Debug");

  private final JCheckBox _infoChkbox = new JCheckBox("Info");

  /** Directory containing the log files. */
  private final File _logDir;

  /** If <TT>true</TT> user is closing this window. */
  private boolean _closing = false;

  /** If <TT>true</TT> log is being refreshed. */
  private boolean _refreshing = false;

  /**
   * Ctor specifying the application API.
   *
   * @param app
   *           Application API.
   * @throws IllegalArgumentException
   *            Thrown if a <TT>null</TT> <TT>IApplication passed.
   */
  private ViewLogsSheet(IApplication app)
  {
    super(s_stringMgr.getString("ViewLogsSheet.title"), true, true, true, true, app);
    if (app == null) { throw new IllegalArgumentException("IApplication == null"); }

    _app = app;
    _prefs = _app.getSquirrelPreferences();
    _logDir = new ApplicationFiles().getExecutionLogFile().getParentFile();
    createUserInterface();
  }

  /**
   * Show this window
   *
   * @param app
   *           Application API.
   * @throws IllegalArgumentException
   *            Thrown if a <TT>null</TT> <TT>IApplication</TT> object passed.
   */
  public static synchronized void showSheet(IApplication app)
  {
    if (s_instance == null)
    {
      s_instance = new ViewLogsSheet(app);
      app.getMainFrame().addWidget(s_instance);
      centerWithinDesktop(s_instance);
    }

    final boolean wasVisible = s_instance.isVisible();
    if (!wasVisible)
    {
      s_instance.setVisible(true);
    }
    s_instance.moveToFront();
    if (!wasVisible && !s_instance._refreshing)
    {
      s_instance.startRefreshingLog();
    }
  }

  /**
   * Nulls the singleton instance of this class in a thread-safe way.
   */
  public static synchronized void disposeInstance()
  {
    s_instance = null;
  }

  @Override
  public void dispose()
  {
    // Stop refresh if it is running.
    _closing = true;

    ViewLogsSheet.disposeInstance();

    super.dispose();
  }

  /**
   * Close this sheet.
   */
  private void performClose()
  {
    dispose();
  }

  /**
   * Start a thread to refrsh the log.
   */
  private synchronized void startRefreshingLog()
  {
    if (!_refreshing)
    {
      _app.getThreadPool().addTask(new Refresher());
    }
  }

  /**
   * Enables the log combo box and refresh button using the Swing event thread.
   */
  private void enableComponents(final boolean enabled)
  {
    GUIUtils.processOnSwingEventThread(new Runnable()
    {
      public void run()
      {
        _refreshBtn.setEnabled(enabled);
        _logDirCmb.setEnabled(enabled);
      }
    });
  }

  /**
   * Refresh the log.
   */
  private void refreshLog()
  {
    enableComponents(false);
    final CursorChanger cursorChg = new CursorChanger(getAwtContainer());
    cursorChg.show();
    try
    {
      try
      {
        SwingUtilities.invokeAndWait(new Runnable()
        {
          public void run()
          {
            _logContentsTxt.setText("");
          }
        });
      }
      catch (final Exception ex)
      {
        // i18n[ViewLogsSheet.error.clearlogcontents=Error clearing the log contents]
        s_log.error(s_stringMgr.getString("ViewLogsSheet.error.clearlogcontents"), ex);
      }
      final File logFile = (File) _logDirCmb.getSelectedItem();
      if (logFile != null)
      {
        try
        {
          if (logFile.exists() && logFile.canRead())
          {
            final BufferedReader rdr = new BufferedReader(new FileReader(logFile));
            try
            {
              String line = null;
              StringBuilder chunk = new StringBuilder(16384);
              while ((line = rdr.readLine()) != null)
              {
                if (_closing) { return; }

                if (chunk.length() > 16000)
                {
                  final String finalLine = chunk.toString();
                  SwingUtilities.invokeAndWait(new Runnable()
                  {
                    public void run()
                    {
                      if (!_closing)
                      {
                        _logContentsTxt.append(finalLine);
                      }
                    }
                  });
                  chunk = new StringBuilder(16384);
                }
                else
                {
                  if (shouldAppendLineToChunk(line))
                  {
                    chunk.append(line).append('\n');
                  }
                }
              }

              if (_closing) { return; }

              final String finalLine = chunk.toString();
              SwingUtilities.invokeAndWait(new Runnable()
              {
                public void run()
                {
                  if (!_closing)
                  {
                    _logContentsTxt.append(finalLine);
                  }
                }
              });
            }
            finally
            {
              rdr.close();
            }
          }
        }
        catch (final Exception ex)
        {
          // i18n[ViewLogsSheet.error.processinglogfile=Error occured processing log file]
          final String msg = s_stringMgr.getString("ViewLogsSheet.error.processinglogfile");
          s_log.error(msg, ex);
        }
      }
      else
      {
        if (s_log.isDebugEnabled()) {
          // i18n[ViewLogsSheet.info.nulllogfile=Null log file name]
          s_log.debug(s_stringMgr.getString("ViewLogsSheet.info.nulllogfile"));
        }
      }

      if (_closing) { return; }

      // Position to the start of the last line in log.
      try
      {
        final int pos = Math.max(0, _logContentsTxt.getText().length() - 1);
        final int line = _logContentsTxt.getLineOfOffset(pos);
        final int finalpos = _logContentsTxt.getLineStartOffset(line);
        SwingUtilities.invokeAndWait(new Runnable()
        {
          public void run()
          {
            _logContentsTxt.setCaretPosition(finalpos);
          }
        });
      }
      catch (final Exception ex)
      {
        // i18n[ViewLogsSheet.error.setcaret=Error positioning caret in log text component]
        s_log.error(s_stringMgr.getString("ViewLogsSheet.error.setcaret"), ex);
      }
    }
    finally
    {
      enableComponents(true);
      _refreshing = false;
      cursorChg.restore();
    }
  }

  /**
   * 199828 [Foo Thread] message
   *
   * @param line
   * @return
   */
  private boolean shouldAppendLineToChunk(String line)
  {
    boolean result = false;
    if (line == null || line.length() == 0) { return false; }
    if (_errorChkbox.isSelected() && _debugChkbox.isSelected() && _infoChkbox.isSelected()) { return true; }
    final int threadNameEndIdx = line.indexOf("]");
    if (threadNameEndIdx > -1)
    {
      char levelChar = ' ';
      if (line.length() >= threadNameEndIdx + 2)
      {
        levelChar = line.charAt(threadNameEndIdx + 2);
      }
      if (_errorChkbox.isSelected() && levelChar == 'E')
      {
        result = true;
      }
      if (_debugChkbox.isSelected() && levelChar == 'D')
      {
        result = true;
      }
      if (_infoChkbox.isSelected() && levelChar == 'I')
      {
        result = true;
      }
      if (levelChar != 'E' && levelChar != 'D' && levelChar != 'I')
      {
        result = true;
      }
    }
    else
    {
      result = true;
    }
    return result;
  }

  /**
   * Create user interface.
   */
  private void createUserInterface()
  {
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    makeToolWindow(true);
    final Container contentPane = getContentPane();
    contentPane.setLayout(new BorderLayout());
    contentPane.add(createToolBar(), BorderLayout.NORTH);
    contentPane.add(createMainPanel(), BorderLayout.CENTER);
    contentPane.add(createButtonsPanel(), BorderLayout.SOUTH);
    pack();

    final AbstractAction closeAction = new AbstractAction()
    {
      private static final long serialVersionUID = 1L;

      public void actionPerformed(ActionEvent actionEvent)
      {
        performClose();
      }
    };
    final KeyStroke escapeStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
    getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(escapeStroke,
      "CloseAction");
    getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeStroke, "CloseAction");
    getRootPane().getInputMap(JComponent.WHEN_FOCUSED).put(escapeStroke, "CloseAction");
    getRootPane().getActionMap().put("CloseAction", closeAction);

  }

  private ToolBar createToolBar()
  {
    final ToolBar tb = new ToolBar();
    tb.setUseRolloverButtons(true);
    tb.setFloatable(false);

    final Object[] args = { getTitle(), _logDir.getAbsolutePath() };
    final String lblTitle = s_stringMgr.getString("ViewLogsSheet.storedin", args);
    final JLabel lbl = new JLabel(lblTitle);
    lbl.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
    tb.add(lbl);

    return tb;
  }

  /**
   * Create the main panel containing the log details and selector.
   */
  private JPanel createMainPanel()
  {
    // _logContentsTxt.setEditable(false);
    final TextPopupMenu pop = new TextPopupMenu();
    pop.setTextComponent(_logContentsTxt);
    _logContentsTxt.addMouseListener(new MouseAdapter()
    {
      @Override
      public void mousePressed(MouseEvent evt)
      {
        if (evt.isPopupTrigger())
        {
          pop.show(evt.getComponent(), evt.getX(), evt.getY());
        }
      }

      @Override
      public void mouseReleased(MouseEvent evt)
      {
        if (evt.isPopupTrigger())
        {
          pop.show(evt.getComponent(), evt.getX(), evt.getY());
        }
      }
    });

    final File appLogFile = new ApplicationFiles().getExecutionLogFile();
    _logDirCmb.load(appLogFile.getParentFile());

    if (_logDirCmb.getModel().getSize() > 0)
    {
      _logDirCmb.setSelectedItem(appLogFile.getName());
    }

    // Done after the set of the selected item above so that we control
    // when the initial build is done. We want to make sure that under all
    // versions of the JDK that the window is shown before the (possibly
    // lengthy) refresh starts.
    _logDirCmb.addActionListener(new ChangeLogListener());

    final JPanel pnl = new JPanel(new BorderLayout());
    pnl.add(_logDirCmb, BorderLayout.NORTH);
    _logContentsTxt.setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 0));
    pnl.add(new JScrollPane(_logContentsTxt), BorderLayout.CENTER);

    return pnl;
  }

  /**
   * Create panel at bottom containing the buttons.
   */
  private JPanel createButtonsPanel()
  {
    final JPanel pnl = new JPanel();

    pnl.add(_refreshBtn);
    _refreshBtn.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent evt)
      {
        startRefreshingLog();
      }
    });

    final JButton closeBtn = new JButton(s_stringMgr.getString("ViewLogsSheet.close"));
    closeBtn.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent evt)
      {
        performClose();
      }
    });
    pnl.add(closeBtn);

    _errorChkbox.setSelected(_prefs.getShowErrorLogMessages());
    _errorChkbox.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        _prefs.setShowErrorLogMessages(_errorChkbox.isSelected());
      }
    });
    _infoChkbox.setSelected(_prefs.getShowInfoLogMessages());
    _infoChkbox.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        _prefs.setShowInfoLogMessages(_infoChkbox.isSelected());
      }
    });
    _debugChkbox.setSelected(_prefs.getShowDebugLogMessage());
    _debugChkbox.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        _prefs.setShowDebugLogMessages(_debugChkbox.isSelected());
      }
    });
    pnl.add(_errorChkbox);
    pnl.add(_infoChkbox);
    pnl.add(_debugChkbox);

    GUIUtils.setJButtonSizesTheSame(new JButton[] { closeBtn, _refreshBtn });
    getRootPane().setDefaultButton(closeBtn);

    return pnl;
  }

  private final class ChangeLogListener implements ActionListener
  {
    public void actionPerformed(ActionEvent evt)
    {
      ViewLogsSheet.this.startRefreshingLog();
    }
  }

  private final class Refresher implements Runnable
  {
    public void run()
    {
      ViewLogsSheet.this.refreshLog();
    }
  }

  private static final class LogsComboBox extends DirectoryListComboBox
  {
    private static final long serialVersionUID = 1L;

    private File _dir;

    @Override
    public void load(File dir, FilenameFilter filter)
    {
      _dir = dir;
      super.load(dir, filter);
    }

    @Override
    public void addItem(Object anObject)
    {
      super.addItem(new LogFile(_dir, anObject.toString()));
    }
  }

  private static final class LogFile extends File
  {
    private static final long serialVersionUID = 1L;

    private final String _stringRep;

    LogFile(File dir, String name)
    {
      super(dir, name);
      final StringBuffer buf = new StringBuffer();
      buf.append(getName()).append(" (").append(Utilities.formatSize(length())).append(")");
      _stringRep = buf.toString();
    }

    @Override
    public String toString()
    {
      return _stringRep;
    }
  }
}
TOP

Related Classes of net.sourceforge.squirrel_sql.client.gui.ViewLogsSheet$Refresher

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.