products/Sources/formale Sprachen/Isabelle/Tools/jEdit/dist/jEdit/org/gjt/sp/util image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: Log.java   Sprache: JAVA

Original von: Isabelle©

/*
 * Log.java - A class for logging events
 * :tabSize=4:indentSize=4:noTabs=false:
 * :folding=explicit:collapseFolds=1:
 *
 * Copyright (C) 1999, 2003 Slava Pestov
 *
 * 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, or any later version.
 *
 * 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.
 *
 * 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.
 */


package org.gjt.sp.util;

//{{{ Imports
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Writer;

import java.text.DateFormat;

import java.util.*;

import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import javax.swing.ListModel;
import javax.swing.SwingUtilities;

import static java.text.DateFormat.MEDIUM;
//}}}

/**
 * This class provides methods for logging events. In terms of functionality,
 * it is somewhere in between <code>System.out.println()</code> and
 * full-blown logging packages such as log4j.<p>
 *
 * All events are logged to an in-memory buffer and optionally a stream,
 * and those with a high urgency (warnings and errors) are also printed
 * to standard output.<p>
 *
 * Logging of exception tracebacks is supported.<p>
 *
 * This class can also optionally redirect standard output and error
 * to the log, see {@link #init}.
 *
 * @author Slava Pestov
 * @version $Id: Log.java 25123 2020-04-04 22:40:51Z kpouer $
 */

public class Log
{
 //{{{ Constants
 /**
 * The maximum number of log messages that will be kept in memory.
 * @since jEdit 2.6pre5
 */

 public static int MAXLINES = 500;

 /**
 * Debugging message urgency. Should be used for messages only
 * useful when debugging a problem.
 * @since jEdit 2.2pre2
 */

 public static final int DEBUG = 1;

 /**
 * Message urgency. Should be used for messages which give more
 * detail than notices.
 * @since jEdit 2.2pre2
 */

 public static final int MESSAGE = 3;

 /**
 * Notice urgency. Should be used for messages that directly
 * affect the user.
 * @since jEdit 2.2pre2
 */

 public static final int NOTICE = 5;

 /**
 * Warning urgency. Should be used for messages that warrant
 * attention.
 * @since jEdit 2.2pre2
 */

 public static final int WARNING = 7;

 /**
 * Error urgency. Should be used for messages that signal a
 * failure.
 * @since jEdit 2.2pre2
 */

 public static final int ERROR = 9;
 //}}}

 //{{{ init() method
 /**
 * Initializes the log.
 * @param stdio If true, standard output and error will be
 * intercepted and sent to the log. The <code>urgency</code>
 * for these implicit log entries is <code>NOTICE</code>
 * and <code>ERROR</code> accordingly. Note that in such a situation
 * <code>System.out.print()</code> calls will not appear on standard
 * output, if default output level is higher than <code>NOTICE</code>.
 * @param level Messages with this log level or higher will
 * be printed to the system console.
 * @since jEdit 3.2pre4
 */

 public static void init(boolean stdio, int level)
 {
  if(stdio && System.out == realOut && System.err == realErr)
  {
   System.setOut(createPrintStream(NOTICE,null));
   System.setErr(createPrintStream(ERROR,null));
  }

  Log.level = level;

  // Log some stuff
  log(MESSAGE,Log.class,"When reporting bugs, please"
   + " include the following information:");
  String[] props = {
   "java.version""java.vm.version""java.vm.name",
   "java.runtime.version""java.runtime.name",
   "java.vendor""java.compiler""os.name""os.version",
   "os.arch""user.home""java.home",
   "java.class.path",
   };
  for (String prop : props)
  {
   log(MESSAGE, Log.class, prop + '=' + System.getProperty(prop));
  }
 } //}}}

 //{{{ setLogWriter() method
 /**
 * Writes all currently logged messages to this stream if there was no
 * stream set previously, and sets the stream to write future log
 * messages to.
 * @param stream The writer
 * @since jEdit 3.2pre4
 */

 public static void setLogWriter(Writer stream)
 {
  if(Log.stream == null && stream != null)
  {
   try
   {
    if(wrap)
    {
     for(int i = logLineCount; i < log.length; i++)
     {
      stream.write(log[i]);
      stream.write(lineSep);
     }
    }
    for(int i = 0; i < logLineCount; i++)
    {
     stream.write(log[i]);
     stream.write(lineSep);
    }

    stream.flush();
   }
   catch(Exception e)  // NOPMD
   {
    // do nothing, who cares -- well, PMD will call you on it.
   }
  }

  Log.stream = stream;
 } //}}}

 //{{{ get/setBeepOnOutput method
 /**
 * @since jEdit 5.1pre1
 */

 public static boolean getBeepOnOutput()
 {
  return beepOnOutput;
 }

 /**
 * When <code>beepOnOutput</code> is set, every output going to standard
 * error is signaled by a standard beep. This is intended for debugging
 * purposes, to allow for immediate problem detection.
 * @since jEdit 5.1pre1
 */

 public static void setBeepOnOutput(boolean beepOnOutput)
 {
  Log.beepOnOutput = beepOnOutput;
 } //}}}
 
 public static void setMaxLines(int newMax)
 {
  if (newMax == MAXLINES)
   return;
  
  // find last non-null entry in log array
  int lineCount = 0;
  for (int i = 0; i < log.length; i++) 
  {
   if (log[i] == null)
    break;
   ++lineCount;
  }
  
  // copy entries from log to newLog
  String[] newLog = new String[newMax];
  if (newMax > lineCount)
  {
   System.arraycopy(log, 0, newLog, 0, lineCount);
  }
  else
  {
   // lineCount > newMax
   System.arraycopy(log, lineCount - newMax, newLog, 0, newMax);
   logLineCount = newMax;
  }
  
  MAXLINES = newMax;
  log = newLog;
  listModel.update(lineCount, true);
 }
 
 public static int getMaxLinex()
 {
  return MAXLINES; 
 }

 //{{{ flushStream() method
 /**
 * Flushes the log stream.
 * @since jEdit 2.6pre5
 */

 public static void flushStream()
 {
  if(stream != null)
  {
   try
   {
    stream.flush();
   }
   catch(IOException io)
   {
    io.printStackTrace(realErr);
   }
  }
 } //}}}

 //{{{ closeStream() method
 /**
 * Closes the log stream. Should be done before your program exits.
 * @since jEdit 2.6pre5
 */

 public static void closeStream()
 {
  if(stream != null)
  {
   try
   {
    stream.close();
    stream = null;
   }
   catch(IOException io)
   {
    io.printStackTrace(realErr);
   }
  }
 } //}}}

 //{{{ getLogListModel() method
 /**
 * Returns the list model for viewing the log contents.
 * @since jEdit 4.2pre1
 */

 public static ListModel<String> getLogListModel()
 {
  return listModel;
 } //}}}

 //{{{ log() method
 /**
 * Logs an exception with a message.
 *
 * If an exception is the cause of a call to {@link #log}, then
 * the exception should be explicitly provided so that it can
 * be presented to the (debugging) user in a useful manner
 * (not just the exception message, but also the exception stack trace)
 *
 * @since jEdit 4.3pre5
 */

 public static void log(int urgency, Object source, Object message,
  Throwable exception)
 {
  // We can do nicer here, but this is a start...
  log(urgency,source,message);
  log(urgency,source,exception);
 } //}}}

 //{{{ log() method
 /**
 * Logs a message. This method is thread-safe.<p>
 *
 * The following code sends a typical debugging message to the activity
 * log:
 * <pre>Log.log(Log.DEBUG,this,"counter = " + counter);</pre>
 * The corresponding activity log entry might read as follows:
 * <pre>[debug] JavaParser: counter = 15</pre>
 *
 * @param urgency The urgency; can be one of
 * <code>Log.DEBUG</code>, <code>Log.MESSAGE</code>,
 * <code>Log.NOTICE</code>, <code>Log.WARNING</code>, or
 * <code>Log.ERROR</code>.
 * @param source The source of the message, either an object or a
 * class instance. When writing log messages from macros, set
 * this parameter to <code>BeanShell.class</code> to make macro
 * errors easier to spot in the activity log.
 * @param message The message. This can either be a string or
 * an exception
 *
 * @since jEdit 2.2pre2
 */

 public static void log(int urgency, Object source, Object message)
 {
  String _source;
  if(source == null)
  {
   _source = Thread.currentThread().getName();
   if(_source == null)
   {
    _source = Thread.currentThread().getClass().getName();
   }
  }
  else if(source instanceof Class)
   _source = ((Class<?>)source).getName();
  else
   _source = source.getClass().getName();
  int index = _source.lastIndexOf('.');
  if(index != -1)
   _source = _source.substring(index+1);

  if(message instanceof Throwable)
  {
   _logException(urgency,source,(Throwable)message);
  }
  else
  {
   String _message = String.valueOf(message);
   // If multiple threads log stuff, we don't want
   // the output to get mixed up
   synchronized(LOCK)
   {
    StringTokenizer st = new StringTokenizer(
     _message,"\r\n");
    int lineCount = 0;
    boolean oldWrap = wrap;
    while(st.hasMoreTokens())
    {
     lineCount++;
     _log(urgency,_source,st.nextToken()
      .replace('\t',' '));
    }
    listModel.update(lineCount,oldWrap);
   }
  }
 } //}}}

 //{{{ Private members

 //{{{ Instance variables
 private static final Object LOCK;
 private static String[] log;
 private static int logLineCount;
 private static boolean wrap;
 private static int level;
 private static Writer stream;
 private static final String lineSep;
 private static final PrintStream realOut;
 private static final PrintStream realErr;
 private static final LogListModel listModel;
 private static final DateFormat timeFormat;
 private static final int MAX_THROWABLES = 10;
 public static final List<Throwable> throwables;
 // initialized externally through setBeepOnOutput method
 private static boolean beepOnOutput = false;
 // to prevent too much beeping we remember last beep time
 private static long lastBeepTime = 0;
 //}}}

 //{{{ Class initializer
 static
 {
  LOCK = new Object();
  level = WARNING;

  realOut = System.out;
  realErr = System.err;

  log = new String[MAXLINES];
  lineSep = System.getProperty("line.separator");
  listModel = new LogListModel();
  
  timeFormat = DateFormat.getTimeInstance(MEDIUM);
  throwables = Collections.synchronizedList(new ArrayList<Throwable>(MAX_THROWABLES));
 } //}}}

 //{{{ createPrintStream() method
 private static PrintStream createPrintStream(final int urgency,
  final Object source)
 {
  return new LogPrintStream(urgency, source);
 } //}}}

 //{{{ _logException() method
 private static void _logException(final int urgency,
  final Object source,
  final Throwable message)
 {
  PrintStream out = createPrintStream(urgency,source);
  if (urgency >= level)
  {
   synchronized (throwables)
   {
    if (throwables.size() == MAX_THROWABLES)
    {
     throwables.remove(0);
    }
    throwables.add(message);
   }
  }
  synchronized(LOCK)
  {
   message.printStackTrace(out);
  }
 } //}}}

 //{{{ _log() method
 private static void _log(int urgency, String source, String message)
 {
  String fullMessage = timeFormat.format(new Date()) + " ["+Thread.currentThread().getName()+"] [" + urgencyToString(urgency) + "] " + source
   + ": " + message;

  try
  {
   log[logLineCount] = fullMessage;
   if(++logLineCount >= log.length)
   {
    wrap = true;
    logLineCount = 0;
   }

   if(stream != null)
   {
    stream.write(fullMessage);
    stream.write(lineSep);
   }
  }
  catch(Exception e)
  {
   e.printStackTrace(realErr);
  }

  if(urgency >= level)
  {
   if(urgency == ERROR)
    realErr.println(fullMessage);
   else
    realOut.println(fullMessage);

   if (beepOnOutput)
   {
    long time = System.currentTimeMillis();
    
    if (time - lastBeepTime > 1000)
    {
     javax.swing.UIManager.getLookAndFeel().provideErrorFeedback(null); 
     lastBeepTime = System.currentTimeMillis();
    }
   }
  }
 } //}}}

 //{{{ urgencyToString() method
 private static String urgencyToString(int urgency)
 {
  switch(urgency)
  {
  case DEBUG:
   return "debug";
  case MESSAGE:
   return "message";
  case NOTICE:
   return "notice";
  case WARNING:
   return "warning";
  case ERROR:
   return "error";
  }

  throw new IllegalArgumentException("Invalid urgency: " + urgency);
 } //}}}

 //}}}

 //{{{ LogListModel class
 static class LogListModel implements ListModel<String>
 {
  final List<ListDataListener> listeners = new ArrayList<>();

  //{{{ fireIntervalAdded() method
  private void fireIntervalAdded(int index1, int index2)
  {
   for (ListDataListener listener : listeners)
   {
    listener.intervalAdded(new ListDataEvent(this,
     ListDataEvent.INTERVAL_ADDED, index1, index2));
   }
  } //}}}

  //{{{ fireIntervalRemoved() method
  private void fireIntervalRemoved(int index1, int index2)
  {
   for (ListDataListener listener : listeners)
   {
    listener.intervalRemoved(new ListDataEvent(
     this, ListDataEvent.INTERVAL_REMOVED, index1, index2));
   }
  } //}}}

  //{{{ addListDataListener() method
  @Override
  public void addListDataListener(ListDataListener listener)
  {
   listeners.add(listener);
  } //}}}

  //{{{ removeListDataListener() method
  @Override
  public void removeListDataListener(ListDataListener listener)
  {
   listeners.remove(listener);
  } //}}}

  //{{{ getElementAt() method
  @Override
  public String getElementAt(int index)
  {
   if(wrap)
   {
    if(index < MAXLINES - logLineCount)
     return log[index + logLineCount];
    else
     return log[index - MAXLINES + logLineCount];
   }
   else
    return log[index];
  } //}}}

  //{{{ getSize() method
  @Override
  public int getSize()
  {
   if(wrap)
    return MAXLINES;
   else
    return logLineCount;
  } //}}}

  //{{{ update() method
  void update(final int lineCount, final boolean oldWrap)
  {
   if(lineCount == 0 || listeners.isEmpty())
    return;

   SwingUtilities.invokeLater(() ->
   {
    if(wrap)
    {
     if(oldWrap)
      fireIntervalRemoved(0,lineCount - 1);
     else
     {
      fireIntervalRemoved(0,
       logLineCount);
     }
     fireIntervalAdded(
      MAXLINES - lineCount + 1,
      MAXLINES);
    }
    else
    {
     fireIntervalAdded(
      logLineCount - lineCount + 1,
      logLineCount);
    }
   });
  } //}}}
 } //}}}

 //{{{ LogPrintStream class
 /**
 * A print stream that uses the "Log" class to output the messages,
 * and has special treatment for the printf() function. Using this
 * stream has one caveat: printing messages that don't have a line
 * break at the end will have one added automatically...
 */

 private static class LogPrintStream extends PrintStream {

  private final ByteArrayOutputStream buffer;
  private final OutputStream orig;

  //{{{ LogPrintStream constructor
  LogPrintStream(int urgency, Object source)
  {
   super(new LogOutputStream(urgency, source));
   buffer = new ByteArrayOutputStream();
   orig = out;
  } //}}}

  //{{{ printf() method
  /**
 * This is a hack to allow "printf" to not print weird
 * stuff to the output. Since "printf" doesn't seem to
 * print the whole message in one shot, our output
 * stream above would break a line of log into several
 * lines; so we buffer the result of the printf call and
 * print the whole thing in one shot. A similar hack
 * would be needed for the "other" printf method, but
 * I'll settle for the common case only.
 */

  @Override
  public PrintStream printf(String format, Object... args)
  {
   synchronized (orig)
   {
    buffer.reset();
    out = buffer;
    super.printf(format, args);

    try
    {
     byte[] data = buffer.toByteArray();
     orig.write(data, 0, data.length);
     out = orig;
    }
    catch (IOException ioe)  // NOPMD
    {
     // don't do anything?
    }
    finally
    {
     buffer.reset();
    }
   }
   return this;
  } //}}}
 } //}}}

 //{{{ LogOutputStream class
 private static class LogOutputStream extends OutputStream
 {
  private final int  urgency;
  private final Object  source;

  //{{{ LogOutputStream constructor
  LogOutputStream(int urgency, Object source)
  {
   this.urgency  = urgency;
   this.source  = source;
  } //}}}

  //{{{ write() method
  @Override
  public synchronized void write(int b)
  {
   byte[] barray = { (byte)b };
   write(barray,0,1);
  } //}}}

  //{{{ write() method
  @Override
  public synchronized void write(byte[] b, int off, int len)
  {
   String str = new String(b,off,len);
   log(urgency,source,str);
  } //}}}
 } //}}}
}

¤ Dauer der Verarbeitung: 0.8 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.


Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff