Package org.gudy.azureus2.ui.swt.views

Source Code of org.gudy.azureus2.ui.swt.views.LoggerView

/**
* Copyright (C) 2004, 2005, 2006 Aelitis SAS, All rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program 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 General Public License for more details ( see the LICENSE file ).
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* AELITIS, SAS au capital de 46,603.30 euros,
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*/
package org.gudy.azureus2.ui.swt.views;

import java.io.PrintStream;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.*;

import org.gudy.azureus2.core3.config.ParameterListener;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.logging.impl.FileLogging;
import org.gudy.azureus2.core3.util.AERunnable;
import org.gudy.azureus2.ui.swt.Messages;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.mainwindow.Colors;

/**
* @author TuxPaper
*
* @since 2.3.0.5
*/
public class LoggerView extends AbstractIView implements ILogEventListener,
    ParameterListener {
  //private final static LogIDs LOGID = LogIDs.GUI;

  private static final int COLOR_INFO = 0;

  private static final int COLOR_WARN = 1;

  private static final int COLOR_ERR = 2;

  private static Color[] colors = null;

  private static final int PREFERRED_LINES = 256;

  private static final int MAX_LINES = 1024 + PREFERRED_LINES;

  private static final SimpleDateFormat dateFormatter;

  private static final FieldPosition formatPos;

  private Display display;

  private Composite panel;

  private StyledText consoleText = null;

  private Button buttonAutoScroll = null;

  private Object[] filter = null;

  // LinkedList is better for removing entries when full
  private LinkedList buffer = new LinkedList();

  private boolean bPaused = false;

  private boolean bRealtime = false;

  private boolean bEnabled = false;

  private boolean bAutoScroll = true;
 
  private Pattern inclusionFilter;
  private Pattern exclusionFilter;

  // List of components we don't log. 
  // Array represents LogTypes (info, warning, error)
  private ArrayList[] ignoredComponents = new ArrayList[3];

  private boolean stopOnNull = false;

  static {
    dateFormatter = new SimpleDateFormat("[HH:mm:ss.SSS] ");
    formatPos = new FieldPosition(0);
  }

  public LoggerView() {
    this(false);
    setEnabled(true);
  }
 
  public LoggerView(boolean stopOnNull) {
    for (int i = 0; i < ignoredComponents.length; i++) {
      ignoredComponents[i] = new ArrayList();
    }
    this.stopOnNull = stopOnNull;
  }

  public LoggerView(java.util.List initialList) {
    this();
    if (initialList != null)
      buffer.addAll(initialList);
    setEnabled(true);
  }

  /* (non-Javadoc)
   * @see org.gudy.azureus2.ui.swt.IView#initialize(org.eclipse.swt.widgets.Composite)
   */
  public void initialize(Composite composite) {
    display = composite.getDisplay();

    Colors.getInstance().addColorsChangedListener(this);
    parameterChanged("Color");

    panel = new Composite(composite, SWT.NULL);
    GridLayout layout = new GridLayout();
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    layout.verticalSpacing = 2;
    layout.numColumns = 2;
    panel.setLayout(layout);

    GridData gd;

    consoleText = new StyledText(panel, SWT.READ_ONLY | SWT.V_SCROLL
        | SWT.H_SCROLL);
    gd = new GridData(GridData.FILL_BOTH);
    gd.horizontalSpan = 2;
    consoleText.setLayoutData(gd);

    // XXX This doesn't work well, but it's better than nothing
    consoleText.addListener(SWT.Resize, new Listener() {
      public void handleEvent(Event event) {
        GC gc = new GC(consoleText);
        int charWidth = gc.getFontMetrics().getAverageCharWidth();
        gc.dispose();

        int areaWidth = consoleText.getBounds().width;
        consoleText.setTabs(areaWidth / 6 / charWidth);
      }
    });

    ScrollBar sb = consoleText.getVerticalBar();
    sb.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        bAutoScroll = false;
        if (buttonAutoScroll != null && !buttonAutoScroll.isDisposed())
          buttonAutoScroll.setSelection(false);
      }
    });

    Composite cLeft = new Composite(panel, SWT.NULL);
    layout = new GridLayout();
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    layout.verticalSpacing = 1;
    cLeft.setLayout(layout);
    gd = new GridData(SWT.TOP, SWT.LEAD, false, false);
    cLeft.setLayoutData(gd);

    Button buttonPause = new Button(cLeft, SWT.CHECK);
    Messages.setLanguageText(buttonPause, "LoggerView.pause");
    gd = new GridData();
    buttonPause.setLayoutData(gd);
    buttonPause.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        if (e.widget == null || !(e.widget instanceof Button))
          return;
        Button btn = (Button) e.widget;
        bPaused = btn.getSelection();
        if (!bPaused && buffer != null) {
          refresh();
        }
      }
    });

    Button buttonRealtime = new Button(cLeft, SWT.CHECK);
    Messages.setLanguageText(buttonRealtime, "LoggerView.realtime");
    gd = new GridData();
    buttonRealtime.setLayoutData(gd);
    buttonRealtime.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        if (e.widget == null || !(e.widget instanceof Button))
          return;
        Button btn = (Button) e.widget;
        bRealtime = btn.getSelection();
      }
    });

    buttonAutoScroll = new Button(cLeft, SWT.CHECK);
    Messages.setLanguageText(buttonAutoScroll, "LoggerView.autoscroll");
    gd = new GridData();
    buttonAutoScroll.setLayoutData(gd);
    buttonAutoScroll.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        if (e.widget == null || !(e.widget instanceof Button))
          return;
        Button btn = (Button) e.widget;
        bAutoScroll = btn.getSelection();
      }
    });
    buttonAutoScroll.setSelection(true);

    Button buttonClear = new Button(cLeft, SWT.PUSH);
    Messages.setLanguageText(buttonClear, "LoggerView.clear");
    gd = new GridData();
    buttonClear.setLayoutData(gd);
    buttonClear.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        consoleText.setText("");
      }
    });

    /** FileLogging filter, consisting of a List of types (info, warning, error)
     * and a checkbox Table of component IDs.
     */
    final String sFilterPrefix = "ConfigView.section.logging.filter";
    Group gLogIDs = new Group(panel, SWT.NULL);
    Messages.setLanguageText(gLogIDs, "LoggerView.filter");
    layout = new GridLayout();
    layout.marginHeight = 0;
    layout.numColumns = 2;
    gLogIDs.setLayout(layout);
    gd = new GridData();
    gLogIDs.setLayoutData(gd);

    Label label = new Label(gLogIDs, SWT.NONE);
    Messages.setLanguageText(label, "ConfigView.section.logging.level");
    label.setLayoutData(new GridData());

    final Label labelCatFilter = new Label(gLogIDs, SWT.NONE);
    labelCatFilter.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

    final List listLogTypes = new List(gLogIDs, SWT.BORDER | SWT.SINGLE
        | SWT.V_SCROLL);
    gd = new GridData(SWT.NULL, SWT.BEGINNING, false, false);
    listLogTypes.setLayoutData(gd);

    final int[] logTypes = { LogEvent.LT_INFORMATION, LogEvent.LT_WARNING,
        LogEvent.LT_ERROR };
    for (int i = 0; i < logTypes.length; i++)
      listLogTypes.add(MessageText.getString("ConfigView.section.logging.log"
          + i + "type"));
    listLogTypes.select(0);

    final LogIDs[] logIDs = FileLogging.configurableLOGIDs;
    //Arrays.sort(logIDs);

    Composite cChecksAndButtons = new Composite(gLogIDs, SWT.NULL);
    layout = new GridLayout(2, false);
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    cChecksAndButtons.setLayout(layout);
    cChecksAndButtons.setLayoutData(new GridData());

    final Composite cChecks = new Composite(cChecksAndButtons, SWT.NULL);
    RowLayout rowLayout = new RowLayout(SWT.VERTICAL);
    rowLayout.wrap = true;
    rowLayout.marginLeft = 0;
    rowLayout.marginRight = 0;
    rowLayout.marginTop = 0;
    rowLayout.marginBottom = 0;
    cChecks.setLayout(rowLayout);

    SelectionAdapter buttonClickListener = new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        int index = listLogTypes.getSelectionIndex();
        if (index < 0 || index >= logTypes.length)
          return;
        Button item = (Button) e.widget;
        if (item.getSelection())
          ignoredComponents[index].remove(item.getData("LOGID"));
        else
          ignoredComponents[index].add(item.getData("LOGID"));
      }
    };
    for (int i = 0; i < logIDs.length; i++) {
      Button btn = new Button(cChecks, SWT.CHECK);
      btn.setText(MessageText.getString(sFilterPrefix + "." + logIDs[i],
          logIDs[i].toString()));

      btn.setData("LOGID", logIDs[i]);

      btn.addSelectionListener(buttonClickListener);

      if (i == 0) {
        gd = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 2);
        gd.heightHint = (btn.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + 2) * 3;
        cChecks.setLayoutData(gd);
      }
    }

    // Update table when list selection changes
    listLogTypes.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        int index = listLogTypes.getSelectionIndex();
        if (index < 0 || index >= logTypes.length)
          return;

        labelCatFilter.setText(MessageText.getString(
            "ConfigView.section.logging.showLogsFor", listLogTypes
                .getSelection()));

        Control[] items = cChecks.getChildren();
        for (int i = 0; i < items.length; i++) {
          if (items[i] instanceof Button) {
            LogIDs ID = (LogIDs) items[i].getData("LOGID");
            if (ID != null) {
              boolean checked = !ignoredComponents[index].contains(ID);
              ((Button) items[i]).setSelection(checked);
            }
          }
        }
      }
    });

    listLogTypes.notifyListeners(SWT.Selection, null);

    Button btn;
    btn = new Button(cChecksAndButtons, SWT.PUSH);
    gd = new GridData();
    btn.setLayoutData(gd);
    Messages.setLanguageText(btn, "LoggerView.filter.checkAll");
    btn.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        int index = listLogTypes.getSelectionIndex();

        Control[] items = cChecks.getChildren();
        for (int i = 0; i < items.length; i++) {
          if (items[i] instanceof Button) {
            LogIDs ID = (LogIDs) items[i].getData("LOGID");
            if (ID != null && ignoredComponents[index].contains(ID)) {
              ((Button) items[i]).setSelection(true);
              ignoredComponents[index].remove(ID);
            }
          }
        }
      }
    });

    btn = new Button(cChecksAndButtons, SWT.PUSH);
    gd = new GridData();
    btn.setLayoutData(gd);
    Messages.setLanguageText(btn, "LoggerView.filter.uncheckAll");
    btn.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        int index = listLogTypes.getSelectionIndex();

        Control[] items = cChecks.getChildren();
        for (int i = 0; i < items.length; i++) {
          if (items[i] instanceof Button) {
            LogIDs ID = (LogIDs) items[i].getData("LOGID");
            if (ID != null && !ignoredComponents[index].contains(ID)) {
              ((Button) items[i]).setSelection(false);
              ignoredComponents[index].add(ID);
            }
          }
        }
      }
    });
   
    Composite cBottom = new Composite(panel, SWT.NONE);
    gd = new GridData(SWT.FILL, SWT.FILL, true, false);
    gd.horizontalSpan = 2;
    cBottom.setLayoutData(gd);
    cBottom.setLayout(new GridLayout(2, false));
    
   
    label = new Label(cBottom, SWT.NONE);
    label.setLayoutData(new GridData());
    Messages.setLanguageText(label, "LoggerView.includeOnly");
   
    final Text inclText = new Text(cBottom, SWT.BORDER);
    gd = new GridData();
    gd.widthHint = 200;
    inclText.setLayoutData(gd);
    inclText.addModifyListener(new ModifyListener()
    {
      public void modifyText(ModifyEvent e) {
        String newExpression = inclText.getText();
        if (newExpression.length() == 0)
          inclusionFilter = null;
        else
        {
          try
          {
            inclusionFilter = Pattern.compile(newExpression, Pattern.CASE_INSENSITIVE);
            inclText.setBackground(null);
          } catch (PatternSyntaxException e1)
          {
            inclText.setBackground(Colors.colorErrorBG);
          }
        }
      }
    });
   
    label = new Label(cBottom, SWT.NONE);
    label.setLayoutData(new GridData());
    Messages.setLanguageText(label, "LoggerView.excludeAll");
       
    final Text exclText = new Text(cBottom, SWT.BORDER);
    gd = new GridData();
    gd.widthHint = 200;
    exclText.setLayoutData(gd);
    exclText.addModifyListener(new ModifyListener()
    {
      public void modifyText(ModifyEvent e) {
        String newExpression = exclText.getText();
        if (newExpression.length() == 0)
          exclusionFilter = null;
        else
        {
          try
          {
            exclusionFilter = Pattern.compile(newExpression, Pattern.CASE_INSENSITIVE);
            exclText.setBackground(null);
          } catch (PatternSyntaxException e1)
          {
            exclText.setBackground(Colors.colorErrorBG);
          }
        }
      }
    });


    if (!Logger.isEnabled()) {
      consoleText.setText(MessageText.getString("LoggerView.loggingDisabled")
          + "\n");
    }
  }

  /* (non-Javadoc)
   * @see org.gudy.azureus2.ui.swt.IView#getComposite()
   */
  public Composite getComposite() {
    return panel;
  }

  /* (non-Javadoc)
   * @see org.gudy.azureus2.ui.swt.IView#refresh()
   */
  public void refresh() {
    if (bPaused)
      return;
   
    synchronized (buffer) {
      if (consoleText == null || consoleText.isDisposed())
        return;

      for (int i = 0; i < buffer.size(); i++) {
        try {
          LogEvent event = (LogEvent) buffer.get(i);

          int nbLinesBefore = consoleText.getLineCount();
          if (nbLinesBefore > MAX_LINES)
          {
            consoleText.replaceTextRange(0, consoleText.getOffsetAtLine(PREFERRED_LINES), "");
            nbLinesBefore = consoleText.getLineCount();
          }


          final StringBuffer buf = new StringBuffer();
          buf.append('\n');
         
          dateFormatter.format(event.timeStamp, buf, formatPos);
          buf.append("{").append(event.logID).append("} ");

          buf.append(event.text);
          if (event.relatedTo != null) {
            buf.append("; \t| ");
            for (int j = 0; j < event.relatedTo.length; j++) {
              Object obj = event.relatedTo[j];
              if (j > 0)
                buf.append("; ");
              if (obj instanceof LogRelation) {
                buf.append(((LogRelation) obj).getRelationText());
              } else if (obj != null) {
                buf.append(obj.getClass().getName()).append(": '").append(
                    obj.toString()).append("'");
              }
            }
          }


          String toAppend = buf.toString();
         
          if((inclusionFilter != null && !inclusionFilter.matcher(toAppend).find()) || (exclusionFilter != null && exclusionFilter.matcher(toAppend).find()))
            continue;
         
          consoleText.append(toAppend);

          int nbLinesNow = consoleText.getLineCount();
          int colorIdx = -1;
          if (event.entryType == LogEvent.LT_INFORMATION)
            colorIdx = COLOR_INFO;
          else if (event.entryType == LogEvent.LT_WARNING)
            colorIdx = COLOR_WARN;
          else if (event.entryType == LogEvent.LT_ERROR)
            colorIdx = COLOR_ERR;

          if (colors != null && colorIdx >= 0)
            consoleText.setLineBackground(nbLinesBefore, nbLinesNow
                - nbLinesBefore, colors[colorIdx]);
        } catch (Exception e) {
          // don't send it to log, we might be feeding ourselves
          PrintStream ps = Logger.getOldStdErr();
          if (ps != null) {
            ps.println("Error writing event to console:");
            e.printStackTrace(ps);
          }
        }

      }
      buffer.clear();
      if (bAutoScroll)
        consoleText.setTopIndex(consoleText.getLineCount());
    }
  }

  /* (non-Javadoc)
   * @see org.gudy.azureus2.ui.swt.IView#delete()
   */
  public void delete() {
    Logger.removeListener(this);
    if (panel != null && !panel.isDisposed())
      panel.dispose();
    Colors.getInstance().removeColorsChangedListener(this);
  }

  /* (non-Javadoc)
   * @see org.gudy.azureus2.ui.swt.IView#getFullTitle()
   */
  public String getFullTitle() {
    return MessageText.getString("ConsoleView.title.full");
  }

  public String getData() {
    return "ConsoleView.title.short";
  }

  // @see org.gudy.azureus2.core3.logging.ILogEventListener#log(org.gudy.azureus2.core3.logging.LogEvent)
  public synchronized void log(final LogEvent event) {
    if (display == null || display.isDisposed())
      return;

    if (ignoredComponents[logTypeToIndex(event.entryType)].contains(event.logID))
      return;

    // Always display STDERR messages, as they may relate to the filter
    boolean bMatch = (event.logID == LogIDs.STDERR || filter == null);

    if (!bMatch && event.relatedTo != null) {
      for (int i = 0; !bMatch && i < event.relatedTo.length; i++) {
        Object obj = event.relatedTo[i];

        if (obj == null)
          continue;

        for (int j = 0; !bMatch && j < filter.length; j++) {
          if (obj instanceof LogRelation) {
            //System.err.println(obj.getClass().getSimpleName() + " is Logrelation");

            Object newObj = ((LogRelation) obj).queryForClass(filter[j]
                .getClass());
            if (newObj != null)
              obj = newObj;
          }

          //System.err.println(obj.getClass().getName() + " matches " + filter[j].getClass().getSimpleName() + "?");

          if (obj == filter[j])
            bMatch = true;
        } // for filter
      } // for relatedTo
    }

    if (bMatch) {
      synchronized (buffer) {
        if (buffer.size() >= 200)
          buffer.removeFirst();
        buffer.add(event);
      }

      if (bRealtime && !bPaused) {
        Utils.execSWTThread(new AERunnable() {
          public void runSupport() {
            refresh();
          }
        });
      }
    }
  }

  public void setFilter(Object[] _filter) {
    filter = _filter;
    clearConsole();
  }

  private void clearConsole() {
    if (display == null || display.isDisposed())
      return;

    Utils.execSWTThread(new AERunnable() {
      public void runSupport() {
        consoleText.setText("");
      }
    });
  }

  public void setEnabled(boolean on) {
    if (bEnabled == on)
      return;
    bEnabled = on;
    if (on)
      Logger.addListener(this);
    else
      Logger.removeListener(this);
  }

  /* (non-Javadoc)
   * @see org.gudy.azureus2.plugins.PluginView#getPluginViewName()
   */
  public String getPluginViewName() {
    return "Console";
  }

  // TODO: Support multiple selection
  public void dataSourceChanged(Object newDataSource) {
    if (newDataSource == null) {
      if (stopOnNull) {
        setEnabled(false);
        return;
      }
      setFilter(null);
    } else if (newDataSource instanceof Object[]) {
      setFilter((Object[]) newDataSource);
    } else {
      setFilter(new Object[] { newDataSource });
    }

    setEnabled(true);
  }

  private int logTypeToIndex(int entryType) {
    switch (entryType) {
      case LogEvent.LT_INFORMATION:
        return 0;
      case LogEvent.LT_WARNING:
        return 1;
      case LogEvent.LT_ERROR:
        return 2;
    }
    return 0;
  }

  private int indexToLogType(int index) {
    switch (index) {
      case 0:
        return LogEvent.LT_INFORMATION;
      case 1:
        return LogEvent.LT_WARNING;
      case 2:
        return LogEvent.LT_ERROR;
    }
    return LogEvent.LT_INFORMATION;
  }

  public void parameterChanged(String parameterName) {
    if (parameterName.startsWith("Color")) {
      Utils.execSWTThread(new AERunnable() {
        public void runSupport() {
          if (display == null || display.isDisposed())
            return;

          if (colors == null)
            colors = new Color[3];

          final Color[] newColors = { Colors.blues[Colors.BLUES_MIDLIGHT],
              Colors.colorWarning, Colors.red_ConsoleView };
          boolean bColorChanged = false;

          for (int i = 0; i < newColors.length; i++) {
            if (colors[i] == null || colors[i].isDisposed()) {
              colors[i] = newColors[i];
              bColorChanged = true;
            }
          }

          if (bColorChanged && consoleText != null) {
            // remove color
            String text = consoleText.getText();
            consoleText.setText(text);
          }
        }
      });
    }
  }
}
TOP

Related Classes of org.gudy.azureus2.ui.swt.views.LoggerView

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.