/*****************************************************************************
* Copyright (c) 2006-2007, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
*****************************************************************************/
package org.eclipse.equinox.p2.authoring.internal;
import java.io.PrintStream;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.p2.authoring.P2AuthoringUIPlugin;
import org.osgi.framework.Bundle;
/**
* This logger will disptach all messages to two destinations; the eclipse logger and the console.
* Depending on the settings, the message might be dispatched to none, one, or both destinations.
* The logger can also be made to dispatch console messages through the eclipse logger. It does that
* by adding an ILogListener to the platform that will dispatch all messages to standard out.
* @author Thomas Hallgren
*/
public class Logger
{
public static final int SILENT = IStatus.CANCEL; // We use this constant to avoid collisions
public static final int DEBUG = IStatus.OK;
public static final int ERROR = IStatus.ERROR;
public static final int INFO = IStatus.INFO;
public static final int WARNING = IStatus.WARNING;
// Magic used as the bundle specific code in log entries. Can be used
// for filtering (although not in the Eclipse log viewer since it
// doesn't support filtering on plugin specific code yet)
//
private static final int MAGIC = 293;
private static Logger s_defaultLogger;
private static int s_consoleThreshold = IP2AuthoringPreferenceConstants.LOG_LEVEL_CONSOLE_DEFAULT;
private static int s_eclipseLoggerThreshold = IP2AuthoringPreferenceConstants.LOG_LEVEL_ECLIPSE_LOGGER_DEFAULT;
private static ILogListener s_eclipseLogListener;
private static class EclipseLogListener implements ILogListener
{
public void logging(IStatus status, String plugin)
{
int severity = status.getSeverity();
if(severity >= s_consoleThreshold)
{
PrintStream out;
switch(severity)
{
case IStatus.ERROR:
case IStatus.WARNING:
out = System.err;
break;
default:
out = System.out;
}
Logger.printStatus(status, out);
}
}
};
public static Logger getDefault()
{
return s_defaultLogger;
}
public static void setConsoleLevelThreshold(int threshold)
{
s_consoleThreshold = threshold;
}
public static void setEclipseLoggerLevelThreshold(int threshold)
{
s_eclipseLoggerThreshold = threshold;
}
public static synchronized void setEclipseLoggerToConsole(boolean flag)
{
if(flag)
{
if(s_eclipseLogListener == null)
{
s_eclipseLogListener = new EclipseLogListener();
Platform.addLogListener(s_eclipseLogListener);
}
}
else
{
if(s_eclipseLogListener != null)
{
Platform.removeLogListener(s_eclipseLogListener);
s_eclipseLogListener = null;
}
}
}
static void setDefaultLogger(Bundle bundle)
{
s_defaultLogger = new Logger(bundle);
}
private final ILog m_log;
public static final String BUILDER_LOG_RECEIVER_POINT = P2AuthoringUIPlugin.PLUGIN_ID + ".logReceivers";
public Logger(Bundle bundle)
{
if(bundle == null)
throw new IllegalArgumentException("The bundle for a logger cannot be null");
m_log = Platform.getLog(bundle);
}
public Logger(ILog log)
{
m_log = log;
}
public Logger(String bundleId)
{
this(Platform.getBundle(bundleId));
}
public void debug(String msg, Object ...args)
{
log(DEBUG, msg, args);
}
public void debug(Throwable t, String msg, Object ...args)
{
log(DEBUG, t, msg, args);
}
public void error(String msg, Object ...args)
{
log(ERROR, msg, args);
}
public void error(Throwable t, String msg, Object ...args)
{
log(ERROR, t, msg, args);
}
public void info(String msg, Object ...args)
{
log(INFO, msg, args);
}
public void info(Throwable t, String msg, Object ...args)
{
log(INFO, t, msg, args);
}
public boolean isInfoEnabled()
{
return s_consoleThreshold <= INFO || s_eclipseLoggerThreshold <= INFO;
}
public boolean isDebugEnabled()
{
return s_consoleThreshold <= DEBUG || s_eclipseLoggerThreshold <= DEBUG;
}
public boolean isErrorEnabled()
{
return s_consoleThreshold <= ERROR || s_eclipseLoggerThreshold <= ERROR;
}
public boolean isWarningEnabled()
{
return s_consoleThreshold <= WARNING || s_eclipseLoggerThreshold <= WARNING;
}
public void log(int level, String msg, Object ...args)
{
log(level, null, msg, args);
}
private static PrintStream s_errStream;
private static PrintStream s_outStream;
static
{
setOutStream(getLoggerStream(false));
setErrStream(getLoggerStream(true));
}
public void log(int level, Throwable t, String msg, Object ...args)
{
if(level >= s_consoleThreshold && (s_eclipseLogListener == null || level < s_eclipseLoggerThreshold))
{
PrintStream logStream = (level == WARNING || level == ERROR) ? s_errStream : s_outStream;
synchronized(logStream)
{
logStream.format(msg, args);
logStream.println();
if(t != null && level == DEBUG)
t.printStackTrace(logStream);
logStream.flush();
}
}
if(level >= s_eclipseLoggerThreshold)
m_log.log(new Status(level, m_log.getBundle().getSymbolicName(), MAGIC, String.format(msg, args), t));
}
public void warning(String msg, Object ...args)
{
log(WARNING, msg, args);
}
public void warning(Throwable t, String msg, Object ...args)
{
log(WARNING, t, msg, args);
}
public static PrintStream getOutStream()
{
return s_outStream;
}
public static PrintStream getErrStream()
{
return s_errStream;
}
public static void printStatus(IStatus status, PrintStream out)
{
synchronized(out)
{
printStatus(status, out, 0);
out.flush();
}
}
private static void printStatus(IStatus status, PrintStream out, int indent)
{
boolean hasSeverityPrefix = false;
String msg = status.getMessage();
if(msg != null)
hasSeverityPrefix = msg.startsWith("ERROR") || msg.startsWith("WARN") || msg.startsWith("INFO");
for(int idx = 0; idx < indent; ++idx)
out.print(' ');
if(!hasSeverityPrefix)
{
switch(status.getSeverity())
{
case IStatus.CANCEL:
return;
case IStatus.ERROR:
out.print("ERROR: ");
break;
case IStatus.INFO:
out.print("INFO: ");
break;
case IStatus.WARNING:
out.print("WARN: ");
}
}
out.println(msg);
Throwable t = status.getException();
if(t != null)
t.printStackTrace(out);
indent += 2;
for(IStatus child : status.getChildren())
printStatus(child, out, indent);
}
private static PrintStream getLoggerStream(boolean errorStream)
{
return errorStream ? System.err : System.out;
}
public static void setOutStream(PrintStream out)
{
s_outStream = out;
}
public static void setErrStream(PrintStream err)
{
s_errStream = err;
}
}