/*---------------------------------------------------------------------------*\
$Id: 300065d561157205021f7b7b2ad6fad76c2442ea $
---------------------------------------------------------------------------
This software is released under a BSD-style license:
Copyright (c) 2004-2007 Brian M. Clapper. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. The end-user documentation included with the redistribution, if any,
must include the following acknowlegement:
"This product includes software developed by Brian M. Clapper
(bmc@clapper.org, http://www.clapper.org/bmc/). That software is
copyright (c) 2004-2007 Brian M. Clapper."
Alternately, this acknowlegement may appear in the software itself,
if wherever such third-party acknowlegements normally appear.
3. Neither the names "clapper.org", "clapper.org Java Utility Library",
nor any of the names of the project contributors may be used to
endorse or promote products derived from this software without prior
written permission. For written permission, please contact
bmc@clapper.org.
4. Products derived from this software may not be called "clapper.org
Java Utility Library", nor may "clapper.org" appear in their names
without prior written permission of Brian M. Clapper.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
NO EVENT SHALL BRIAN M. CLAPPER BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\*---------------------------------------------------------------------------*/
package org.clapper.util.logging;
import org.apache.commons.logging.LogFactory;
import java.util.Collection;
import java.util.ArrayList;
/**
* Logger wraps the
* Jakarta Commons Logging
* API and provides a slightly simpler, but similar, interface. This
* class supports most of the logging methods, but it doesn't actually
* instantiate an underlying java.util.logging.Logger object until
* (or unless) a thread explicitly calls the {@link #enableLogging} method.
* The first call to enableLogging() traverses the list of
* instantiated org.clapper.util.Logger objects and creates
* underlying java.util.logging.Logger objects for each one. Any
* Logger objects created after enableLogging() is called
* are automatically enabled.
*
* This approach prevents any interaction with the real logging layer,
* unless logging is explicitly enabled (e.g., because a command-line
* option has been specified). This approach was originally taken to avoid
* annoying startup messages from the Log4J logging implementation, which
* insists on writing warning messages to the console when it can't find a
* configuration file.
*
* However, this class can be reimplemented in terms of other logging
* layers (and, in fact, has been implemented solely in terms of the JDK
* 1.4 native logging library in the past).
This object's main purpose
* now is to insulate applications from the underlying logging technology,
* so that technology can be changed, if necessary, without having an
* impact on applications that use this class.
*
* The level mappings used by this class are identical to those used
* by Commons Logging. (e.g.,, a "debug" message uses the same level as
* a Commons Logging "debug" message.) Those mappings are:
*
*
*
* org.clapper.util.logging.Logger method
* Corresponding java.util.logging.Level value
*
*
*
* debug()
* FINE
*
*
*
* error()
* SEVERE
*
*
*
* fatal()
* SEVERE
*
*
*
* info()
* INFO
*
*
*
* trace()
* FINEST
*
*
*
* warn()
* WARNING
*
*
*
* If you prefer to use Commons Logging directly, then, by all means,
* use it for your applications.
*
* WARNING: If your application installs its own class loader (e.g.,
* as the thread context class loader), you may have problems with
* both Jakarta Commons Logging and java.util.logging (which
* Jakarta Commons Logging uses as its default logging implementation).
*
*
* - The java.util.logging layer explicitly bootstraps
* itself using the system class loader (i.e., the class loader
* that examines the CLASSPATH setting). In some cases, this can
* cause problems. For instance, an application that installs its
* own class loader and expects to use that class loader to find
* a custom-built java.util.logging formatter will not
* end up using its own formatter, because the formatter class
* is not available in the CLASSPATH, and that's where
* java.util.logging expects to find it. In situations
* like that, the best bet is to substitute a better-behaved
* underlying logging layer such as
* Log4J.
*
*
- Jakarta Commons Logging uses a "discovery" process that plays
* class loader games. You can solve the problem with Commons Logging
* by explicitly specifying the underlying logging API to use. For
* example:
*
*
* java -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger -Dlog4j.configuration=file:/path/to/log4j-debug.properties
*
*
* @see #enableLogging
* @see Jakarta Commons Logging API
*
* @version $Revision$
*
* @author Copyright © 2004-2007 Brian M. Clapper
*/
public class Logger
{
/*----------------------------------------------------------------------*\
Public Constants
\*----------------------------------------------------------------------*/
/**
* Log level constant for debug messages. Defined here for backward
* compatibility.
*
* @see LogLevel#DEBUG
*/
public static LogLevel LEVEL_DEBUG = LogLevel.DEBUG;
/**
* Log level constant for error messages. Defined here for backward
* compatibility.
*
* @see LogLevel#ERROR
*/
public static LogLevel LEVEL_ERROR = LogLevel.ERROR;
/**
* Log level constant for fatal-error messages. Defined here for
* backward compatibility.
*
* @see LogLevel#FATAL
*/
public static LogLevel LEVEL_FATAL = LogLevel.FATAL;
/**
* Log level constant for informational messages. Defined here for
* backward compatibility.
*
* @see LogLevel#INFO
*/
public static LogLevel LEVEL_INFO = LogLevel.INFO;
/**
* Log level constant for trace messages. Defined here for backward
* compatibility.
*
* @see LogLevel#TRACE
*/
public static LogLevel LEVEL_TRACE = LogLevel.TRACE;
/**
* Log level constant for warning messages. Defined here for backward
* compatibility.
*
* @see LogLevel#WARNING
*/
public static LogLevel LEVEL_WARNING = LogLevel.WARNING;
/*----------------------------------------------------------------------*\
Private Instance Data
\*----------------------------------------------------------------------*/
/**
* The real logging object. Not instantiated unless asked for.
*/
private org.apache.commons.logging.Log realLogger = null;
/**
* The class name to use when instantiating the underlying Log object.
*/
private String className = null;
/**
* The list of existing Logger objects.
*/
private static Collection loggers = new ArrayList();
/**
* Whether or not logging is enabled.
*/
private static boolean enabled = false;
/*----------------------------------------------------------------------*\
Constructor
\*----------------------------------------------------------------------*/
/**
* Construct a new Logger object
*
* @param className the class name to associate with the object
*/
public Logger (String className)
{
this.className = className;
synchronized (loggers)
{
loggers.add (this);
// Handle the case where the logger is instantiated after all
// the loggers are enabled.
if (enabled)
enableLogger (this);
}
}
/**
* Construct a new Logger object
*
* @param cls the class whose name should be associated with the object
*/
public Logger (Class cls)
{
this (cls.getName());
}
/*----------------------------------------------------------------------*\
Public Methods
\*----------------------------------------------------------------------*/
/**
* Enable logging by instantiating the underlying Log objects.
* Enables logging for all instantiated Logger objects, and
* ensures that any subsequently instantiated Logger objects will
* be enabled.
*
* @throws UnsupportedOperationException could not find Commons Logging
* API
*/
public static void enableLogging()
throws UnsupportedOperationException
{
synchronized (loggers)
{
if (! enabled)
{
for (Logger logger : loggers)
enableLogger (logger);
enabled = true;
}
}
}
/**
* Log a message with debug log level.
*
* @param message The message to convert to a string and log
*/
public void debug (Object message)
{
if (realLogger != null)
realLogger.debug (message.toString());
}
/**
* Log an error with debug log level.
*
* @param message The message to convert to a string and log
* @param ex The exception to log with the message
*
*/
public void debug (Object message, Throwable ex)
{
if (realLogger != null)
realLogger.debug (message.toString(), ex);
}
/**
* Log a message with error log level.
*
* @param message The message to convert to a string and log
*/
public void error (Object message)
{
if (realLogger != null)
realLogger.error (message.toString());
}
/**
* Log an error with error log level.
*
* @param message The message to convert to a string and log
* @param ex The exception to log with the message
*
*/
public void error (Object message, Throwable ex)
{
if (realLogger != null)
realLogger.error (message.toString(), ex);
}
/**
* Log a message with fatal log level.
*
* @param message The message to convert to a string and log
*/
public void fatal (Object message)
{
if (realLogger != null)
realLogger.fatal (message.toString());
}
/**
* Log an error with fatal log level.
*
* @param message The message to convert to a string and log
* @param ex The exception to log with the message
*
*/
public void fatal (Object message, Throwable ex)
{
if (realLogger != null)
realLogger.fatal (message.toString(), ex);
}
/**
* Log a message with info log level.
*
* @param message The message to convert to a string and log
*/
public void info (Object message)
{
if (realLogger != null)
realLogger.info (message.toString());
}
/**
* Log an error with info log level.
*
* @param message The message to convert to a string and log
* @param ex The exception to log with the message
*
*/
public void info (Object message, Throwable ex)
{
if (realLogger != null)
realLogger.info (message.toString(), ex);
}
/**
* Log a message at a specified log level.
*
* @param level the log level
* @param message the message
*/
public void message (LogLevel level, Object message)
{
switch (level)
{
case DEBUG:
debug (message);
break;
case ERROR:
error (message);
break;
case FATAL:
fatal (message);
break;
case INFO:
info (message);
break;
case TRACE:
trace (message);
break;
case WARNING:
warn (message);
break;
default:
assert (false);
}
}
/**
* Log a message at a specified log level.
*
* @param level the log level
* @param message the message
* @param ex The exception to log with the message
*/
public void message (LogLevel level, Object message, Throwable ex)
{
switch (level)
{
case DEBUG:
debug (message, ex);
break;
case ERROR:
error (message, ex);
break;
case FATAL:
fatal (message, ex);
break;
case INFO:
info (message, ex);
break;
case TRACE:
trace (message, ex);
break;
case WARNING:
warn (message, ex);
break;
default:
assert (false);
}
}
/**
* Log a message with trace log level.
*
* @param message The message to convert to a string and log
*/
public void trace (Object message)
{
if (realLogger != null)
realLogger.trace (message.toString());
}
/**
* Log an error with trace log level.
*
* @param message The message to convert to a string and log
* @param ex The exception to log with the message
*
*/
public void trace (Object message, Throwable ex)
{
if (realLogger != null)
realLogger.trace (message.toString(), ex);
}
/**
* Log a message with warn log level.
*
* @param message The message to convert to a string and log
*/
public void warn (Object message)
{
if (realLogger != null)
realLogger.warn (message.toString());
}
/**
* Log an error with warn log level.
*
* @param message The message to convert to a string and log
* @param ex The exception to log with the message
*
*/
public void warn (Object message, Throwable ex)
{
if (realLogger != null)
realLogger.warn (message.toString(), ex);
}
/**
* Determine whether debug logging is currently enabled.
*
* @return true if debug logging is enabled,
* false otherwise
*/
public boolean isDebugEnabled()
{
return (realLogger == null) ? false
: realLogger.isDebugEnabled();
}
/**
* Determine whether error logging is currently enabled.
*
* @return true if error logging is enabled,
* false otherwise
*/
public boolean isErrorEnabled()
{
return (realLogger == null) ? false
: realLogger.isErrorEnabled();
}
/**
* Determine whether fatal logging is currently enabled.
*
* @return true if fatal logging is enabled,
* false otherwise
*/
public boolean isFatalEnabled()
{
return (realLogger == null) ? false
: realLogger.isFatalEnabled();
}
/**
* Determine whether info logging is currently enabled.
*
* @return true if info logging is enabled,
* false otherwise
*/
public boolean isInfoEnabled()
{
return (realLogger == null) ? false
: realLogger.isInfoEnabled();
}
/**
* Determine whether trace logging is currently enabled.
*
* @return true if trace logging is enabled,
* false otherwise
*/
public boolean isTraceEnabled()
{
return (realLogger == null) ? false
: realLogger.isTraceEnabled();
}
/**
* Determine whether warn logging is currently enabled.
*
* @return true if warn logging is enabled,
* false otherwise
*/
public boolean isWarningEnabled()
{
return (realLogger == null) ? false
: realLogger.isWarnEnabled();
}
/*----------------------------------------------------------------------*\
Private Methods
\*----------------------------------------------------------------------*/
private static void enableLogger (Logger logger)
throws UnsupportedOperationException
{
synchronized (logger)
{
if (logger.realLogger == null)
logger.realLogger = LogFactory.getLog (logger.className);
}
}
}
Ads help maintain this website.