1
0

Move source to standard maven location.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/logging/trunk@1432690 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart
2013-01-13 18:22:20 +00:00
parent 89d15f9381
commit d2b94cf9eb
18 changed files with 0 additions and 1 deletions

View File

@@ -0,0 +1,220 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
/**
* A simple logging interface abstracting logging APIs. In order to be
* instantiated successfully by {@link LogFactory}, classes that implement
* this interface must have a constructor that takes a single String
* parameter representing the "name" of this Log.
* <p>
* The six logging levels used by <code>Log</code> are (in order):
* <ol>
* <li>trace (the least serious)</li>
* <li>debug</li>
* <li>info</li>
* <li>warn</li>
* <li>error</li>
* <li>fatal (the most serious)</li>
* </ol>
* The mapping of these log levels to the concepts used by the underlying
* logging system is implementation dependent.
* The implementation should ensure, though, that this ordering behaves
* as expected.
* <p>
* Performance is often a logging concern.
* By examining the appropriate property,
* a component can avoid expensive operations (producing information
* to be logged).
* <p>
* For example,
* <code><pre>
* if (log.isDebugEnabled()) {
* ... do something expensive ...
* log.debug(theResult);
* }
* </pre></code>
* <p>
* Configuration of the underlying logging system will generally be done
* external to the Logging APIs, through whatever mechanism is supported by
* that system.
*
* @version $Id$
*/
public interface Log {
// ----------------------------------------------------- Logging Properties
/**
* Is debug logging currently enabled?
* <p>
* Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than debug.
*
* @return true if debug is enabled in the underlying logger.
*/
public boolean isDebugEnabled();
/**
* Is error logging currently enabled?
* <p>
* Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than error.
*
* @return true if error is enabled in the underlying logger.
*/
public boolean isErrorEnabled();
/**
* Is fatal logging currently enabled?
* <p>
* Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than fatal.
*
* @return true if fatal is enabled in the underlying logger.
*/
public boolean isFatalEnabled();
/**
* Is info logging currently enabled?
* <p>
* Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than info.
*
* @return true if info is enabled in the underlying logger.
*/
public boolean isInfoEnabled();
/**
* Is trace logging currently enabled?
* <p>
* Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than trace.
*
* @return true if trace is enabled in the underlying logger.
*/
public boolean isTraceEnabled();
/**
* Is warn logging currently enabled?
* <p>
* Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than warn.
*
* @return true if warn is enabled in the underlying logger.
*/
public boolean isWarnEnabled();
// -------------------------------------------------------- Logging Methods
/**
* Log a message with trace log level.
*
* @param message log this message
*/
public void trace(Object message);
/**
* Log an error with trace log level.
*
* @param message log this message
* @param t log this cause
*/
public void trace(Object message, Throwable t);
/**
* Log a message with debug log level.
*
* @param message log this message
*/
public void debug(Object message);
/**
* Log an error with debug log level.
*
* @param message log this message
* @param t log this cause
*/
public void debug(Object message, Throwable t);
/**
* Log a message with info log level.
*
* @param message log this message
*/
public void info(Object message);
/**
* Log an error with info log level.
*
* @param message log this message
* @param t log this cause
*/
public void info(Object message, Throwable t);
/**
* Log a message with warn log level.
*
* @param message log this message
*/
public void warn(Object message);
/**
* Log an error with warn log level.
*
* @param message log this message
* @param t log this cause
*/
public void warn(Object message, Throwable t);
/**
* Log a message with error log level.
*
* @param message log this message
*/
public void error(Object message);
/**
* Log an error with error log level.
*
* @param message log this message
* @param t log this cause
*/
public void error(Object message, Throwable t);
/**
* Log a message with fatal log level.
*
* @param message log this message
*/
public void fatal(Object message);
/**
* Log an error with fatal log level.
*
* @param message log this message
* @param t log this cause
*/
public void fatal(Object message, Throwable t);
}

View File

@@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
/**
* An exception that is thrown only if a suitable <code>LogFactory</code>
* or <code>Log</code> instance cannot be created by the corresponding
* factory methods.
*
* @version $Id$
*/
public class LogConfigurationException extends RuntimeException {
/** Serializable version identifier. */
private static final long serialVersionUID = 8486587136871052495L;
/**
* Construct a new exception with <code>null</code> as its detail message.
*/
public LogConfigurationException() {
super();
}
/**
* Construct a new exception with the specified detail message.
*
* @param message The detail message
*/
public LogConfigurationException(String message) {
super(message);
}
/**
* Construct a new exception with the specified cause and a derived
* detail message.
*
* @param cause The underlying cause
*/
public LogConfigurationException(Throwable cause) {
this(cause == null ? null : cause.toString(), cause);
}
/**
* Construct a new exception with the specified detail message and cause.
*
* @param message The detail message
* @param cause The underlying cause
*/
public LogConfigurationException(String message, Throwable cause) {
super(message + " (Caused by " + cause + ")");
this.cause = cause; // Two-argument version requires JDK 1.4 or later
}
/**
* The underlying cause of this exception.
*/
protected Throwable cause = null;
/**
* Return the underlying cause of this exception (if any).
*/
public Throwable getCause() {
return this.cause;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,219 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import java.lang.reflect.Constructor;
import java.util.Hashtable;
import org.apache.commons.logging.impl.NoOpLog;
/**
* Factory for creating {@link Log} instances. Applications should call
* the <code>makeNewLogInstance()</code> method to instantiate new instances
* of the configured {@link Log} implementation class.
* <p>
* By default, calling <code>getInstance()</code> will use the following
* algorithm:
* <ul>
* <li>If Log4J is available, return an instance of
* <code>org.apache.commons.logging.impl.Log4JLogger</code>.</li>
* <li>If JDK 1.4 or later is available, return an instance of
* <code>org.apache.commons.logging.impl.Jdk14Logger</code>.</li>
* <li>Otherwise, return an instance of
* <code>org.apache.commons.logging.impl.NoOpLog</code>.</li>
* </ul>
* <p>
* You can change the default behavior in one of two ways:
* <ul>
* <li>On the startup command line, set the system property
* <code>org.apache.commons.logging.log</code> to the name of the
* <code>org.apache.commons.logging.Log</code> implementation class
* you want to use.</li>
* <li>At runtime, call <code>LogSource.setLogImplementation()</code>.</li>
* </ul>
*
* @deprecated Use {@link LogFactory} instead - The default factory
* implementation performs exactly the same algorithm as this class did
*
* @version $Id$
*/
public class LogSource {
// ------------------------------------------------------- Class Attributes
static protected Hashtable logs = new Hashtable();
/** Is log4j available (in the current classpath) */
static protected boolean log4jIsAvailable = false;
/** Is JDK 1.4 logging available */
static protected boolean jdk14IsAvailable = false;
/** Constructor for current log class */
static protected Constructor logImplctor = null;
// ----------------------------------------------------- Class Initializers
static {
// Is Log4J Available?
try {
log4jIsAvailable = null != Class.forName("org.apache.log4j.Logger");
} catch (Throwable t) {
log4jIsAvailable = false;
}
// Is JDK 1.4 Logging Available?
try {
jdk14IsAvailable = null != Class.forName("java.util.logging.Logger") &&
null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger");
} catch (Throwable t) {
jdk14IsAvailable = false;
}
// Set the default Log implementation
String name = null;
try {
name = System.getProperty("org.apache.commons.logging.log");
if (name == null) {
name = System.getProperty("org.apache.commons.logging.Log");
}
} catch (Throwable t) {
}
if (name != null) {
try {
setLogImplementation(name);
} catch (Throwable t) {
try {
setLogImplementation("org.apache.commons.logging.impl.NoOpLog");
} catch (Throwable u) {
// ignored
}
}
} else {
try {
if (log4jIsAvailable) {
setLogImplementation("org.apache.commons.logging.impl.Log4JLogger");
} else if (jdk14IsAvailable) {
setLogImplementation("org.apache.commons.logging.impl.Jdk14Logger");
} else {
setLogImplementation("org.apache.commons.logging.impl.NoOpLog");
}
} catch (Throwable t) {
try {
setLogImplementation("org.apache.commons.logging.impl.NoOpLog");
} catch (Throwable u) {
// ignored
}
}
}
}
// ------------------------------------------------------------ Constructor
/** Don't allow others to create instances. */
private LogSource() {
}
// ---------------------------------------------------------- Class Methods
/**
* Set the log implementation/log implementation factory
* by the name of the class. The given class must implement {@link Log},
* and provide a constructor that takes a single {@link String} argument
* (containing the name of the log).
*/
static public void setLogImplementation(String classname)
throws LinkageError, NoSuchMethodException, SecurityException, ClassNotFoundException {
try {
Class logclass = Class.forName(classname);
Class[] argtypes = new Class[1];
argtypes[0] = "".getClass();
logImplctor = logclass.getConstructor(argtypes);
} catch (Throwable t) {
logImplctor = null;
}
}
/**
* Set the log implementation/log implementation factory by class.
* The given class must implement {@link Log}, and provide a constructor
* that takes a single {@link String} argument (containing the name of the log).
*/
static public void setLogImplementation(Class logclass)
throws LinkageError, ExceptionInInitializerError, NoSuchMethodException, SecurityException {
Class[] argtypes = new Class[1];
argtypes[0] = "".getClass();
logImplctor = logclass.getConstructor(argtypes);
}
/** Get a <code>Log</code> instance by class name. */
static public Log getInstance(String name) {
Log log = (Log) logs.get(name);
if (null == log) {
log = makeNewLogInstance(name);
logs.put(name, log);
}
return log;
}
/** Get a <code>Log</code> instance by class. */
static public Log getInstance(Class clazz) {
return getInstance(clazz.getName());
}
/**
* Create a new {@link Log} implementation, based on the given <i>name</i>.
* <p>
* The specific {@link Log} implementation returned is determined by the
* value of the <tt>org.apache.commons.logging.log</tt> property. The value
* of <tt>org.apache.commons.logging.log</tt> may be set to the fully specified
* name of a class that implements the {@link Log} interface. This class must
* also have a public constructor that takes a single {@link String} argument
* (containing the <i>name</i> of the {@link Log} to be constructed.
* <p>
* When <tt>org.apache.commons.logging.log</tt> is not set, or when no corresponding
* class can be found, this method will return a Log4JLogger if the log4j Logger
* class is available in the {@link LogSource}'s classpath, or a Jdk14Logger if we
* are on a JDK 1.4 or later system, or NoOpLog if neither of the above conditions is true.
*
* @param name the log name (or category)
*/
static public Log makeNewLogInstance(String name) {
Log log;
try {
Object[] args = { name };
log = (Log) logImplctor.newInstance(args);
} catch (Throwable t) {
log = null;
}
if (null == log) {
log = new NoOpLog(name);
}
return log;
}
/**
* Returns a {@link String} array containing the names of
* all logs known to me.
*/
static public String[] getLogNames() {
return (String[]) logs.keySet().toArray(new String[logs.size()]);
}
}

View File

@@ -0,0 +1,298 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import org.apache.avalon.framework.logger.Logger;
import org.apache.commons.logging.Log;
/**
* Implementation of commons-logging Log interface that delegates all
* logging calls to the Avalon logging abstraction: the Logger interface.
* <p>
* There are two ways in which this class can be used:
* <ul>
* <li>the instance can be constructed with an Avalon logger
* (by calling {@link #AvalonLogger(Logger)}). In this case, it acts
* as a simple thin wrapping implementation over the logger. This is
* particularly useful when using a property setter.
* </li>
* <li>the {@link #setDefaultLogger} class property can be called which
* sets the ancestral Avalon logger for this class. Any <code>AvalonLogger</code>
* instances created through the <code>LogFactory</code> mechanisms will output
* to child loggers of this <code>Logger</code>.
* </li>
* </ul>
* <p>
* <strong>Note:</strong> <code>AvalonLogger</code> does not implement Serializable
* because the constructors available for it make this impossible to achieve in all
* circumstances; there is no way to "reconnect" to an underlying Logger object on
* deserialization if one was just passed in to the constructor of the original
* object. This class <i>was</i> marked Serializable in the 1.0.4 release of
* commons-logging, but this never actually worked (a NullPointerException would
* be thrown as soon as the deserialized object was used), so removing this marker
* is not considered to be an incompatible change.
*
* @version $Id$
*/
public class AvalonLogger implements Log {
/** Ancestral Avalon logger. */
private static Logger defaultLogger = null;
/** Avalon logger used to perform log. */
private final transient Logger logger;
/**
* Constructs an <code>AvalonLogger</code> that outputs to the given
* <code>Logger</code> instance.
*
* @param logger the Avalon logger implementation to delegate to
*/
public AvalonLogger(Logger logger) {
this.logger = logger;
}
/**
* Constructs an <code>AvalonLogger</code> that will log to a child
* of the <code>Logger</code> set by calling {@link #setDefaultLogger}.
*
* @param name the name of the avalon logger implementation to delegate to
*/
public AvalonLogger(String name) {
if (defaultLogger == null) {
throw new NullPointerException("default logger has to be specified if this constructor is used!");
}
this.logger = defaultLogger.getChildLogger(name);
}
/**
* Gets the Avalon logger implementation used to perform logging.
*
* @return avalon logger implementation
*/
public Logger getLogger() {
return logger;
}
/**
* Sets the ancestral Avalon logger from which the delegating loggers will descend.
*
* @param logger the default avalon logger,
* in case there is no logger instance supplied in constructor
*/
public static void setDefaultLogger(Logger logger) {
defaultLogger = logger;
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.debug</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable t) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.debug</code>.
*
* @param message to log.
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.error</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable t) {
if (getLogger().isErrorEnabled()) {
getLogger().error(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.error</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
if (getLogger().isErrorEnabled()) {
getLogger().error(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.fatalError</code>.
*
* @param message to log.
* @param t log this cause.
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable t) {
if (getLogger().isFatalErrorEnabled()) {
getLogger().fatalError(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.fatalError</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
if (getLogger().isFatalErrorEnabled()) {
getLogger().fatalError(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.info</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable t) {
if (getLogger().isInfoEnabled()) {
getLogger().info(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.info</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
if (getLogger().isInfoEnabled()) {
getLogger().info(String.valueOf(message));
}
}
/**
* Is logging to <code>org.apache.avalon.framework.logger.Logger.debug</code> enabled?
* @see org.apache.commons.logging.Log#isDebugEnabled()
*/
public boolean isDebugEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Is logging to <code>org.apache.avalon.framework.logger.Logger.error</code> enabled?
* @see org.apache.commons.logging.Log#isErrorEnabled()
*/
public boolean isErrorEnabled() {
return getLogger().isErrorEnabled();
}
/**
* Is logging to <code>org.apache.avalon.framework.logger.Logger.fatalError</code> enabled?
* @see org.apache.commons.logging.Log#isFatalEnabled()
*/
public boolean isFatalEnabled() {
return getLogger().isFatalErrorEnabled();
}
/**
* Is logging to <code>org.apache.avalon.framework.logger.Logger.info</code> enabled?
* @see org.apache.commons.logging.Log#isInfoEnabled()
*/
public boolean isInfoEnabled() {
return getLogger().isInfoEnabled();
}
/**
* Is logging to <code>org.apache.avalon.framework.logger.Logger.debug</code> enabled?
* @see org.apache.commons.logging.Log#isTraceEnabled()
*/
public boolean isTraceEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Is logging to <code>org.apache.avalon.framework.logger.Logger.warn</code> enabled?
* @see org.apache.commons.logging.Log#isWarnEnabled()
*/
public boolean isWarnEnabled() {
return getLogger().isWarnEnabled();
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.debug</code>.
*
* @param message to log.
* @param t log this cause.
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable t) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.debug</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.warn</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable t) {
if (getLogger().isWarnEnabled()) {
getLogger().warn(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.avalon.framework.logger.Logger.warn</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
if (getLogger().isWarnEnabled()) {
getLogger().warn(String.valueOf(message));
}
}
}

View File

@@ -0,0 +1,302 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.LogRecord;
import java.util.StringTokenizer;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.commons.logging.Log;
/**
* Implementation of the <code>org.apache.commons.logging.Log</code>
* interface that wraps the standard JDK logging mechanisms that are
* available in SourceForge's Lumberjack for JDKs prior to 1.4.
*
* @version $Id$
* @since 1.1
*/
public class Jdk13LumberjackLogger implements Log, Serializable {
/** Serializable version identifier. */
private static final long serialVersionUID = -8649807923527610591L;
// ----------------------------------------------------- Instance Variables
/**
* The underlying Logger implementation we are using.
*/
protected transient Logger logger = null;
protected String name = null;
private String sourceClassName = "unknown";
private String sourceMethodName = "unknown";
private boolean classAndMethodFound = false;
/**
* This member variable simply ensures that any attempt to initialise
* this class in a pre-1.4 JVM will result in an ExceptionInInitializerError.
* It must not be private, as an optimising compiler could detect that it
* is not used and optimise it away.
*/
protected static final Level dummyLevel = Level.FINE;
// ----------------------------------------------------------- Constructors
/**
* Construct a named instance of this Logger.
*
* @param name Name of the logger to be constructed
*/
public Jdk13LumberjackLogger(String name) {
this.name = name;
logger = getLogger();
}
// --------------------------------------------------------- Public Methods
private void log( Level level, String msg, Throwable ex ) {
if( getLogger().isLoggable(level) ) {
LogRecord record = new LogRecord(level, msg);
if( !classAndMethodFound ) {
getClassAndMethod();
}
record.setSourceClassName(sourceClassName);
record.setSourceMethodName(sourceMethodName);
if( ex != null ) {
record.setThrown(ex);
}
getLogger().log(record);
}
}
/**
* Gets the class and method by looking at the stack trace for the
* first entry that is not this class.
*/
private void getClassAndMethod() {
try {
Throwable throwable = new Throwable();
throwable.fillInStackTrace();
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter( stringWriter );
throwable.printStackTrace( printWriter );
String traceString = stringWriter.getBuffer().toString();
StringTokenizer tokenizer =
new StringTokenizer( traceString, "\n" );
tokenizer.nextToken();
String line = tokenizer.nextToken();
while ( line.indexOf( this.getClass().getName() ) == -1 ) {
line = tokenizer.nextToken();
}
while ( line.indexOf( this.getClass().getName() ) >= 0 ) {
line = tokenizer.nextToken();
}
int start = line.indexOf( "at " ) + 3;
int end = line.indexOf( '(' );
String temp = line.substring( start, end );
int lastPeriod = temp.lastIndexOf( '.' );
sourceClassName = temp.substring( 0, lastPeriod );
sourceMethodName = temp.substring( lastPeriod + 1 );
} catch ( Exception ex ) {
// ignore - leave class and methodname unknown
}
classAndMethodFound = true;
}
/**
* Logs a message with <code>java.util.logging.Level.FINE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
log(Level.FINE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.FINE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable exception) {
log(Level.FINE, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable exception) {
log(Level.SEVERE, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable exception) {
log(Level.SEVERE, String.valueOf(message), exception);
}
/**
* Return the native Logger instance we are using.
*/
public Logger getLogger() {
if (logger == null) {
logger = Logger.getLogger(name);
}
return logger;
}
/**
* Logs a message with <code>java.util.logging.Level.INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
log(Level.INFO, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.INFO</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable exception) {
log(Level.INFO, String.valueOf(message), exception);
}
/**
* Is debug logging currently enabled?
*/
public boolean isDebugEnabled() {
return getLogger().isLoggable(Level.FINE);
}
/**
* Is error logging currently enabled?
*/
public boolean isErrorEnabled() {
return getLogger().isLoggable(Level.SEVERE);
}
/**
* Is fatal logging currently enabled?
*/
public boolean isFatalEnabled() {
return getLogger().isLoggable(Level.SEVERE);
}
/**
* Is info logging currently enabled?
*/
public boolean isInfoEnabled() {
return getLogger().isLoggable(Level.INFO);
}
/**
* Is trace logging currently enabled?
*/
public boolean isTraceEnabled() {
return getLogger().isLoggable(Level.FINEST);
}
/**
* Is warn logging currently enabled?
*/
public boolean isWarnEnabled() {
return getLogger().isLoggable(Level.WARNING);
}
/**
* Logs a message with <code>java.util.logging.Level.FINEST</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
log(Level.FINEST, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.FINEST</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable exception) {
log(Level.FINEST, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.WARNING</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
log(Level.WARNING, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.WARNING</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable exception) {
log(Level.WARNING, String.valueOf(message), exception);
}
}

View File

@@ -0,0 +1,271 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.logging.Log;
/**
* Implementation of the <code>org.apache.commons.logging.Log</code>
* interface that wraps the standard JDK logging mechanisms that were
* introduced in the Merlin release (JDK 1.4).
*
* @version $Id$
*/
public class Jdk14Logger implements Log, Serializable {
/** Serializable version identifier. */
private static final long serialVersionUID = 4784713551416303804L;
/**
* This member variable simply ensures that any attempt to initialise
* this class in a pre-1.4 JVM will result in an ExceptionInInitializerError.
* It must not be private, as an optimising compiler could detect that it
* is not used and optimise it away.
*/
protected static final Level dummyLevel = Level.FINE;
// ----------------------------------------------------------- Constructors
/**
* Construct a named instance of this Logger.
*
* @param name Name of the logger to be constructed
*/
public Jdk14Logger(String name) {
this.name = name;
logger = getLogger();
}
// ----------------------------------------------------- Instance Variables
/**
* The underlying Logger implementation we are using.
*/
protected transient Logger logger = null;
/**
* The name of the logger we are wrapping.
*/
protected String name = null;
// --------------------------------------------------------- Public Methods
private void log( Level level, String msg, Throwable ex ) {
Logger logger = getLogger();
if (logger.isLoggable(level)) {
// Hack (?) to get the stack trace.
Throwable dummyException = new Throwable();
StackTraceElement locations[] = dummyException.getStackTrace();
// Caller will be the third element
String cname = "unknown";
String method = "unknown";
if( locations != null && locations.length > 2 ) {
StackTraceElement caller=locations[2];
cname=caller.getClassName();
method=caller.getMethodName();
}
if( ex == null ) {
logger.logp( level, cname, method, msg );
} else {
logger.logp( level, cname, method, msg, ex );
}
}
}
/**
* Logs a message with <code>java.util.logging.Level.FINE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
log(Level.FINE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.FINE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable exception) {
log(Level.FINE, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable exception) {
log(Level.SEVERE, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable exception) {
log(Level.SEVERE, String.valueOf(message), exception);
}
/**
* Return the native Logger instance we are using.
*/
public Logger getLogger() {
if (logger == null) {
logger = Logger.getLogger(name);
}
return logger;
}
/**
* Logs a message with <code>java.util.logging.Level.INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
log(Level.INFO, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.INFO</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable exception) {
log(Level.INFO, String.valueOf(message), exception);
}
/**
* Is debug logging currently enabled?
*/
public boolean isDebugEnabled() {
return getLogger().isLoggable(Level.FINE);
}
/**
* Is error logging currently enabled?
*/
public boolean isErrorEnabled() {
return getLogger().isLoggable(Level.SEVERE);
}
/**
* Is fatal logging currently enabled?
*/
public boolean isFatalEnabled() {
return getLogger().isLoggable(Level.SEVERE);
}
/**
* Is info logging currently enabled?
*/
public boolean isInfoEnabled() {
return getLogger().isLoggable(Level.INFO);
}
/**
* Is trace logging currently enabled?
*/
public boolean isTraceEnabled() {
return getLogger().isLoggable(Level.FINEST);
}
/**
* Is warn logging currently enabled?
*/
public boolean isWarnEnabled() {
return getLogger().isLoggable(Level.WARNING);
}
/**
* Logs a message with <code>java.util.logging.Level.FINEST</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
log(Level.FINEST, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.FINEST</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable exception) {
log(Level.FINEST, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.WARNING</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
log(Level.WARNING, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.WARNING</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable exception) {
log(Level.WARNING, String.valueOf(message), exception);
}
}

View File

@@ -0,0 +1,306 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import org.apache.commons.logging.Log;
import org.apache.log4j.Logger;
import org.apache.log4j.Priority;
import org.apache.log4j.Level;
/**
* Implementation of {@link Log} that maps directly to a
* <strong>Logger</strong> for log4J version 1.2.
* <p>
* Initial configuration of the corresponding Logger instances should be done
* in the usual manner, as outlined in the Log4J documentation.
* <p>
* The reason this logger is distinct from the 1.3 logger is that in version 1.2
* of Log4J:
* <ul>
* <li>class Logger takes Priority parameters not Level parameters.
* <li>class Level extends Priority
* </ul>
* Log4J1.3 is expected to change Level so it no longer extends Priority, which is
* a non-binary-compatible change. The class generated by compiling this code against
* log4j 1.2 will therefore not run against log4j 1.3.
*
* @version $Id$
*/
public class Log4JLogger implements Log, Serializable {
/** Serializable version identifier. */
private static final long serialVersionUID = 5160705895411730424L;
// ------------------------------------------------------------- Attributes
/** The fully qualified name of the Log4JLogger class. */
private static final String FQCN = Log4JLogger.class.getName();
/** Log to this logger */
private transient Logger logger = null;
/** Logger name */
private final String name;
private static final Priority traceLevel;
// ------------------------------------------------------------
// Static Initializer.
//
// Note that this must come after the static variable declarations
// otherwise initialiser expressions associated with those variables
// will override any settings done here.
//
// Verify that log4j is available, and that it is version 1.2.
// If an ExceptionInInitializerError is generated, then LogFactoryImpl
// will treat that as meaning that the appropriate underlying logging
// library is just not present - if discovery is in progress then
// discovery will continue.
// ------------------------------------------------------------
static {
if (!Priority.class.isAssignableFrom(Level.class)) {
// nope, this is log4j 1.3, so force an ExceptionInInitializerError
throw new InstantiationError("Log4J 1.2 not available");
}
// Releases of log4j1.2 >= 1.2.12 have Priority.TRACE available, earlier
// versions do not. If TRACE is not available, then we have to map
// calls to Log.trace(...) onto the DEBUG level.
Priority _traceLevel;
try {
_traceLevel = (Priority) Level.class.getDeclaredField("TRACE").get(null);
} catch(Exception ex) {
// ok, trace not available
_traceLevel = Level.DEBUG;
}
traceLevel = _traceLevel;
}
// ------------------------------------------------------------ Constructor
public Log4JLogger() {
name = null;
}
/**
* Base constructor.
*/
public Log4JLogger(String name) {
this.name = name;
this.logger = getLogger();
}
/**
* For use with a log4j factory.
*/
public Log4JLogger(Logger logger ) {
if (logger == null) {
throw new IllegalArgumentException(
"Warning - null logger in constructor; possible log4j misconfiguration.");
}
this.name = logger.getName();
this.logger = logger;
}
/**
* Logs a message with <code>org.apache.log4j.Priority.TRACE</code>.
* When using a log4j version that does not support the <code>TRACE</code>
* level, the message will be logged at the <code>DEBUG</code> level.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
getLogger().log(FQCN, traceLevel, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.TRACE</code>.
* When using a log4j version that does not support the <code>TRACE</code>
* level, the message will be logged at the <code>DEBUG</code> level.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable t) {
getLogger().log(FQCN, traceLevel, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.DEBUG</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
getLogger().log(FQCN, Level.DEBUG, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.DEBUG</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable t) {
getLogger().log(FQCN, Level.DEBUG, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
getLogger().log(FQCN, Level.INFO, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.INFO</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable t) {
getLogger().log(FQCN, Level.INFO, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.WARN</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
getLogger().log(FQCN, Level.WARN, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.WARN</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable t) {
getLogger().log(FQCN, Level.WARN, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.ERROR</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
getLogger().log(FQCN, Level.ERROR, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.ERROR</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable t) {
getLogger().log(FQCN, Level.ERROR, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.FATAL</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
getLogger().log(FQCN, Level.FATAL, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.FATAL</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable t) {
getLogger().log(FQCN, Level.FATAL, message, t );
}
/**
* Return the native Logger instance we are using.
*/
public Logger getLogger() {
if (logger == null) {
logger = Logger.getLogger(name);
}
return this.logger;
}
/**
* Check whether the Log4j Logger used is enabled for <code>DEBUG</code> priority.
*/
public boolean isDebugEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Check whether the Log4j Logger used is enabled for <code>ERROR</code> priority.
*/
public boolean isErrorEnabled() {
return getLogger().isEnabledFor(Level.ERROR);
}
/**
* Check whether the Log4j Logger used is enabled for <code>FATAL</code> priority.
*/
public boolean isFatalEnabled() {
return getLogger().isEnabledFor(Level.FATAL);
}
/**
* Check whether the Log4j Logger used is enabled for <code>INFO</code> priority.
*/
public boolean isInfoEnabled() {
return getLogger().isInfoEnabled();
}
/**
* Check whether the Log4j Logger used is enabled for <code>TRACE</code> priority.
* When using a log4j version that does not support the TRACE level, this call
* will report whether <code>DEBUG</code> is enabled or not.
*/
public boolean isTraceEnabled() {
return getLogger().isEnabledFor(traceLevel);
}
/**
* Check whether the Log4j Logger used is enabled for <code>WARN</code> priority.
*/
public boolean isWarnEnabled() {
return getLogger().isEnabledFor(Level.WARN);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,265 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import org.apache.log.Logger;
import org.apache.log.Hierarchy;
import org.apache.commons.logging.Log;
/**
* Implementation of <code>org.apache.commons.logging.Log</code>
* that wraps the <a href="http://avalon.apache.org/logkit/">avalon-logkit</a>
* logging system. Configuration of <code>LogKit</code> is left to the user.
* <p>
* <code>LogKit</code> accepts only <code>String</code> messages.
* Therefore, this implementation converts object messages into strings
* by called their <code>toString()</code> method before logging them.
*
* @version $Id$
*/
public class LogKitLogger implements Log, Serializable {
/** Serializable version identifier. */
private static final long serialVersionUID = 3768538055836059519L;
// ------------------------------------------------------------- Attributes
/** Logging goes to this <code>LogKit</code> logger */
protected transient Logger logger = null;
/** Name of this logger */
protected String name = null;
// ------------------------------------------------------------ Constructor
/**
* Construct <code>LogKitLogger</code> which wraps the <code>LogKit</code>
* logger with given name.
*
* @param name log name
*/
public LogKitLogger(String name) {
this.name = name;
this.logger = getLogger();
}
// --------------------------------------------------------- Public Methods
/**
* Return the underlying Logger we are using.
*/
public Logger getLogger() {
if (logger == null) {
logger = Hierarchy.getDefaultHierarchy().getLoggerFor(name);
}
return logger;
}
// ----------------------------------------------------- Log Implementation
/**
* Logs a message with <code>org.apache.log.Priority.DEBUG</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
debug(message);
}
/**
* Logs a message with <code>org.apache.log.Priority.DEBUG</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable t) {
debug(message, t);
}
/**
* Logs a message with <code>org.apache.log.Priority.DEBUG</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
if (message != null) {
getLogger().debug(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.DEBUG</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable t) {
if (message != null) {
getLogger().debug(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.log.Priority.INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
if (message != null) {
getLogger().info(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.INFO</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable t) {
if (message != null) {
getLogger().info(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.log.Priority.WARN</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
if (message != null) {
getLogger().warn(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.WARN</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable t) {
if (message != null) {
getLogger().warn(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.log.Priority.ERROR</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
if (message != null) {
getLogger().error(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.ERROR</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable t) {
if (message != null) {
getLogger().error(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.log.Priority.FATAL_ERROR</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
if (message != null) {
getLogger().fatalError(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.FATAL_ERROR</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable t) {
if (message != null) {
getLogger().fatalError(String.valueOf(message), t);
}
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>DEBUG</code>.
*/
public boolean isDebugEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>ERROR</code>.
*/
public boolean isErrorEnabled() {
return getLogger().isErrorEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>FATAL_ERROR</code>.
*/
public boolean isFatalEnabled() {
return getLogger().isFatalErrorEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>INFO</code>.
*/
public boolean isInfoEnabled() {
return getLogger().isInfoEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>DEBUG</code>.
*/
public boolean isTraceEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>WARN</code>.
*/
public boolean isWarnEnabled() {
return getLogger().isWarnEnabled();
}
}

View File

@@ -0,0 +1,104 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import org.apache.commons.logging.Log;
/**
* Trivial implementation of Log that throws away all messages. No
* configurable system properties are supported.
*
* @version $Id$
*/
public class NoOpLog implements Log, Serializable {
/** Serializable version identifier. */
private static final long serialVersionUID = 561423906191706148L;
/** Convenience constructor */
public NoOpLog() { }
/** Base constructor */
public NoOpLog(String name) { }
/** Do nothing */
public void trace(Object message) { }
/** Do nothing */
public void trace(Object message, Throwable t) { }
/** Do nothing */
public void debug(Object message) { }
/** Do nothing */
public void debug(Object message, Throwable t) { }
/** Do nothing */
public void info(Object message) { }
/** Do nothing */
public void info(Object message, Throwable t) { }
/** Do nothing */
public void warn(Object message) { }
/** Do nothing */
public void warn(Object message, Throwable t) { }
/** Do nothing */
public void error(Object message) { }
/** Do nothing */
public void error(Object message, Throwable t) { }
/** Do nothing */
public void fatal(Object message) { }
/** Do nothing */
public void fatal(Object message, Throwable t) { }
/**
* Debug is never enabled.
*
* @return false
*/
public final boolean isDebugEnabled() { return false; }
/**
* Error is never enabled.
*
* @return false
*/
public final boolean isErrorEnabled() { return false; }
/**
* Fatal is never enabled.
*
* @return false
*/
public final boolean isFatalEnabled() { return false; }
/**
* Info is never enabled.
*
* @return false
*/
public final boolean isInfoEnabled() { return false; }
/**
* Trace is never enabled.
*
* @return false
*/
public final boolean isTraceEnabled() { return false; }
/**
* Warn is never enabled.
*
* @return false
*/
public final boolean isWarnEnabled() { return false; }
}

View File

@@ -0,0 +1,136 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.LogFactory;
/**
* This class is capable of receiving notifications about the undeployment of
* a webapp, and responds by ensuring that commons-logging releases all
* memory associated with the undeployed webapp.
* <p>
* In general, the WeakHashtable support added in commons-logging release 1.1
* ensures that logging classes do not hold references that prevent an
* undeployed webapp's memory from being garbage-collected even when multiple
* copies of commons-logging are deployed via multiple classloaders (a
* situation that earlier versions had problems with). However there are
* some rare cases where the WeakHashtable approach does not work; in these
* situations specifying this class as a listener for the web application will
* ensure that all references held by commons-logging are fully released.
* <p>
* To use this class, configure the webapp deployment descriptor to call
* this class on webapp undeploy; the contextDestroyed method will tell
* every accessible LogFactory class that the entry in its map for the
* current webapp's context classloader should be cleared.
*
* @version $Id$
* @since 1.1
*/
public class ServletContextCleaner implements ServletContextListener {
private static final Class[] RELEASE_SIGNATURE = {ClassLoader.class};
/**
* Invoked when a webapp is undeployed, this tells the LogFactory
* class to release any logging information related to the current
* contextClassloader.
*/
public void contextDestroyed(ServletContextEvent sce) {
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
Object[] params = new Object[1];
params[0] = tccl;
// Walk up the tree of classloaders, finding all the available
// LogFactory classes and releasing any objects associated with
// the tccl (ie the webapp).
//
// When there is only one LogFactory in the classpath, and it
// is within the webapp being undeployed then there is no problem;
// garbage collection works fine.
//
// When there are multiple LogFactory classes in the classpath but
// parent-first classloading is used everywhere, this loop is really
// short. The first instance of LogFactory found will
// be the highest in the classpath, and then no more will be found.
// This is ok, as with this setup this will be the only LogFactory
// holding any data associated with the tccl being released.
//
// When there are multiple LogFactory classes in the classpath and
// child-first classloading is used in any classloader, then multiple
// LogFactory instances may hold info about this TCCL; whenever the
// webapp makes a call into a class loaded via an ancestor classloader
// and that class calls LogFactory the tccl gets registered in
// the LogFactory instance that is visible from the ancestor
// classloader. However the concrete logging library it points
// to is expected to have been loaded via the TCCL, so the
// underlying logging lib is only initialised/configured once.
// These references from ancestor LogFactory classes down to
// TCCL classloaders are held via weak references and so should
// be released but there are circumstances where they may not.
// Walking up the classloader ancestry ladder releasing
// the current tccl at each level tree, though, will definitely
// clear any problem references.
ClassLoader loader = tccl;
while (loader != null) {
// Load via the current loader. Note that if the class is not accessible
// via this loader, but is accessible via some ancestor then that class
// will be returned.
try {
Class logFactoryClass = loader.loadClass("org.apache.commons.logging.LogFactory");
Method releaseMethod = logFactoryClass.getMethod("release", RELEASE_SIGNATURE);
releaseMethod.invoke(null, params);
loader = logFactoryClass.getClassLoader().getParent();
} catch(ClassNotFoundException ex) {
// Neither the current classloader nor any of its ancestors could find
// the LogFactory class, so we can stop now.
loader = null;
} catch(NoSuchMethodException ex) {
// This is not expected; every version of JCL has this method
System.err.println("LogFactory instance found which does not support release method!");
loader = null;
} catch(IllegalAccessException ex) {
// This is not expected; every ancestor class should be accessible
System.err.println("LogFactory instance found which is not accessable!");
loader = null;
} catch(InvocationTargetException ex) {
// This is not expected
System.err.println("LogFactory instance release method failed!");
loader = null;
}
}
// Just to be sure, invoke release on the LogFactory that is visible from
// this ServletContextCleaner class too. This should already have been caught
// by the above loop but just in case...
LogFactory.release(tccl);
}
/**
* Invoked when a webapp is deployed. Nothing needs to be done here.
*/
public void contextInitialized(ServletContextEvent sce) {
// do nothing
}
}

View File

@@ -0,0 +1,649 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogConfigurationException;
/**
* Simple implementation of Log that sends all enabled log messages,
* for all defined loggers, to System.err. The following system properties
* are supported to configure the behavior of this logger:
* <ul>
* <li><code>org.apache.commons.logging.simplelog.defaultlog</code> -
* Default logging detail level for all instances of SimpleLog.
* Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
* If not specified, defaults to "info". </li>
* <li><code>org.apache.commons.logging.simplelog.log.xxxxx</code> -
* Logging detail level for a SimpleLog instance named "xxxxx".
* Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
* If not specified, the default logging detail level is used.</li>
* <li><code>org.apache.commons.logging.simplelog.showlogname</code> -
* Set to <code>true</code> if you want the Log instance name to be
* included in output messages. Defaults to <code>false</code>.</li>
* <li><code>org.apache.commons.logging.simplelog.showShortLogname</code> -
* Set to <code>true</code> if you want the last component of the name to be
* included in output messages. Defaults to <code>true</code>.</li>
* <li><code>org.apache.commons.logging.simplelog.showdatetime</code> -
* Set to <code>true</code> if you want the current date and time
* to be included in output messages. Default is <code>false</code>.</li>
* <li><code>org.apache.commons.logging.simplelog.dateTimeFormat</code> -
* The date and time format to be used in the output messages.
* The pattern describing the date and time format is the same that is
* used in <code>java.text.SimpleDateFormat</code>. If the format is not
* specified or is invalid, the default format is used.
* The default format is <code>yyyy/MM/dd HH:mm:ss:SSS zzz</code>.</li>
* </ul>
* <p>
* In addition to looking for system properties with the names specified
* above, this implementation also checks for a class loader resource named
* <code>"simplelog.properties"</code>, and includes any matching definitions
* from this resource (if it exists).
*
* @version $Id$
*/
public class SimpleLog implements Log, Serializable {
/** Serializable version identifier. */
private static final long serialVersionUID = 136942970684951178L;
// ------------------------------------------------------- Class Attributes
/** All system properties used by <code>SimpleLog</code> start with this */
static protected final String systemPrefix = "org.apache.commons.logging.simplelog.";
/** Properties loaded from simplelog.properties */
static protected final Properties simpleLogProps = new Properties();
/** The default format to use when formating dates */
static protected final String DEFAULT_DATE_TIME_FORMAT = "yyyy/MM/dd HH:mm:ss:SSS zzz";
/** Include the instance name in the log message? */
static protected boolean showLogName = false;
/** Include the short name ( last component ) of the logger in the log
* message. Defaults to true - otherwise we'll be lost in a flood of
* messages without knowing who sends them.
*/
static protected boolean showShortName = true;
/** Include the current time in the log message */
static protected boolean showDateTime = false;
/** The date and time format to use in the log message */
static protected String dateTimeFormat = DEFAULT_DATE_TIME_FORMAT;
/**
* Used to format times.
* <p>
* Any code that accesses this object should first obtain a lock on it,
* ie use synchronized(dateFormatter); this requirement was introduced
* in 1.1.1 to fix an existing thread safety bug (SimpleDateFormat.format
* is not thread-safe).
*/
static protected DateFormat dateFormatter = null;
// ---------------------------------------------------- Log Level Constants
/** "Trace" level logging. */
public static final int LOG_LEVEL_TRACE = 1;
/** "Debug" level logging. */
public static final int LOG_LEVEL_DEBUG = 2;
/** "Info" level logging. */
public static final int LOG_LEVEL_INFO = 3;
/** "Warn" level logging. */
public static final int LOG_LEVEL_WARN = 4;
/** "Error" level logging. */
public static final int LOG_LEVEL_ERROR = 5;
/** "Fatal" level logging. */
public static final int LOG_LEVEL_FATAL = 6;
/** Enable all logging levels */
public static final int LOG_LEVEL_ALL = LOG_LEVEL_TRACE - 1;
/** Enable no logging levels */
public static final int LOG_LEVEL_OFF = LOG_LEVEL_FATAL + 1;
// ------------------------------------------------------------ Initializer
private static String getStringProperty(String name) {
String prop = null;
try {
prop = System.getProperty(name);
} catch (SecurityException e) {
// Ignore
}
return prop == null ? simpleLogProps.getProperty(name) : prop;
}
private static String getStringProperty(String name, String dephault) {
String prop = getStringProperty(name);
return prop == null ? dephault : prop;
}
private static boolean getBooleanProperty(String name, boolean dephault) {
String prop = getStringProperty(name);
return prop == null ? dephault : "true".equalsIgnoreCase(prop);
}
// Initialize class attributes.
// Load properties file, if found.
// Override with system properties.
static {
// Add props from the resource simplelog.properties
InputStream in = getResourceAsStream("simplelog.properties");
if(null != in) {
try {
simpleLogProps.load(in);
in.close();
} catch(java.io.IOException e) {
// ignored
}
}
showLogName = getBooleanProperty(systemPrefix + "showlogname", showLogName);
showShortName = getBooleanProperty(systemPrefix + "showShortLogname", showShortName);
showDateTime = getBooleanProperty(systemPrefix + "showdatetime", showDateTime);
if(showDateTime) {
dateTimeFormat = getStringProperty(systemPrefix + "dateTimeFormat",
dateTimeFormat);
try {
dateFormatter = new SimpleDateFormat(dateTimeFormat);
} catch(IllegalArgumentException e) {
// If the format pattern is invalid - use the default format
dateTimeFormat = DEFAULT_DATE_TIME_FORMAT;
dateFormatter = new SimpleDateFormat(dateTimeFormat);
}
}
}
// ------------------------------------------------------------- Attributes
/** The name of this simple log instance */
protected String logName = null;
/** The current log level */
protected int currentLogLevel;
/** The short name of this simple log instance */
private String shortLogName = null;
// ------------------------------------------------------------ Constructor
/**
* Construct a simple log with given name.
*
* @param name log name
*/
public SimpleLog(String name) {
logName = name;
// Set initial log level
// Used to be: set default log level to ERROR
// IMHO it should be lower, but at least info ( costin ).
setLevel(SimpleLog.LOG_LEVEL_INFO);
// Set log level from properties
String lvl = getStringProperty(systemPrefix + "log." + logName);
int i = String.valueOf(name).lastIndexOf(".");
while(null == lvl && i > -1) {
name = name.substring(0,i);
lvl = getStringProperty(systemPrefix + "log." + name);
i = String.valueOf(name).lastIndexOf(".");
}
if(null == lvl) {
lvl = getStringProperty(systemPrefix + "defaultlog");
}
if("all".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_ALL);
} else if("trace".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_TRACE);
} else if("debug".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_DEBUG);
} else if("info".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_INFO);
} else if("warn".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_WARN);
} else if("error".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_ERROR);
} else if("fatal".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_FATAL);
} else if("off".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_OFF);
}
}
// -------------------------------------------------------- Properties
/**
* Set logging level.
*
* @param currentLogLevel new logging level
*/
public void setLevel(int currentLogLevel) {
this.currentLogLevel = currentLogLevel;
}
/**
* Get logging level.
*/
public int getLevel() {
return currentLogLevel;
}
// -------------------------------------------------------- Logging Methods
/**
* Do the actual logging.
* <p>
* This method assembles the message and then calls <code>write()</code>
* to cause it to be written.
*
* @param type One of the LOG_LEVEL_XXX constants defining the log level
* @param message The message itself (typically a String)
* @param t The exception whose stack trace should be logged
*/
protected void log(int type, Object message, Throwable t) {
// Use a string buffer for better performance
final StringBuffer buf = new StringBuffer();
// Append date-time if so configured
if(showDateTime) {
final Date now = new Date();
String dateText;
synchronized(dateFormatter) {
dateText = dateFormatter.format(now);
}
buf.append(dateText);
buf.append(" ");
}
// Append a readable representation of the log level
switch(type) {
case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break;
case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break;
case SimpleLog.LOG_LEVEL_INFO: buf.append("[INFO] "); break;
case SimpleLog.LOG_LEVEL_WARN: buf.append("[WARN] "); break;
case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break;
case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break;
}
// Append the name of the log instance if so configured
if(showShortName) {
if(shortLogName == null) {
// Cut all but the last component of the name for both styles
final String slName = logName.substring(logName.lastIndexOf(".") + 1);
shortLogName = slName.substring(slName.lastIndexOf("/") + 1);
}
buf.append(String.valueOf(shortLogName)).append(" - ");
} else if(showLogName) {
buf.append(String.valueOf(logName)).append(" - ");
}
// Append the message
buf.append(String.valueOf(message));
// Append stack trace if not null
if(t != null) {
buf.append(" <");
buf.append(t.toString());
buf.append(">");
final java.io.StringWriter sw = new java.io.StringWriter(1024);
final java.io.PrintWriter pw = new java.io.PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
buf.append(sw.toString());
}
// Print to the appropriate destination
write(buf);
}
/**
* Write the content of the message accumulated in the specified
* <code>StringBuffer</code> to the appropriate output destination. The
* default implementation writes to <code>System.err</code>.
*
* @param buffer A <code>StringBuffer</code> containing the accumulated
* text to be logged
*/
protected void write(StringBuffer buffer) {
System.err.println(buffer.toString());
}
/**
* Is the given log level currently enabled?
*
* @param logLevel is this level enabled?
*/
protected boolean isLevelEnabled(int logLevel) {
// log level are numerically ordered so can use simple numeric
// comparison
return logLevel >= currentLogLevel;
}
// -------------------------------------------------------- Log Implementation
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public final void debug(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
log(SimpleLog.LOG_LEVEL_DEBUG, message, null);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public final void debug(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
log(SimpleLog.LOG_LEVEL_DEBUG, message, t);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public final void trace(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
log(SimpleLog.LOG_LEVEL_TRACE, message, null);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public final void trace(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
log(SimpleLog.LOG_LEVEL_TRACE, message, t);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public final void info(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
log(SimpleLog.LOG_LEVEL_INFO,message,null);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public final void info(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
log(SimpleLog.LOG_LEVEL_INFO, message, t);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public final void warn(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
log(SimpleLog.LOG_LEVEL_WARN, message, null);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public final void warn(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
log(SimpleLog.LOG_LEVEL_WARN, message, t);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public final void error(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
log(SimpleLog.LOG_LEVEL_ERROR, message, null);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public final void error(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
log(SimpleLog.LOG_LEVEL_ERROR, message, t);
}
}
/**
* Log a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public final void fatal(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
log(SimpleLog.LOG_LEVEL_FATAL, message, null);
}
}
/**
* Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public final void fatal(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
log(SimpleLog.LOG_LEVEL_FATAL, message, t);
}
}
/**
* Are debug messages currently enabled?
* <p>
* This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger.
*/
public final boolean isDebugEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
}
/**
* Are error messages currently enabled?
* <p>
* This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger.
*/
public final boolean isErrorEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
}
/**
* Are fatal messages currently enabled?
* <p>
* This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger.
*/
public final boolean isFatalEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
}
/**
* Are info messages currently enabled?
* <p>
* This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger.
*/
public final boolean isInfoEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
}
/**
* Are trace messages currently enabled?
* <p>
* This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger.
*/
public final boolean isTraceEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
}
/**
* Are warn messages currently enabled?
* <p>
* This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger.
*/
public final boolean isWarnEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
}
/**
* Return the thread context class loader if available.
* Otherwise return null.
*
* The thread context class loader is available for JDK 1.2
* or later, if certain security conditions are met.
*
* @exception LogConfigurationException if a suitable class loader
* cannot be identified.
*/
private static ClassLoader getContextClassLoader() {
ClassLoader classLoader = null;
try {
// Are we running on a JDK 1.2 or later system?
final Method method = Thread.class.getMethod("getContextClassLoader", (Class[]) null);
// Get the thread context class loader (if there is one)
try {
classLoader = (ClassLoader)method.invoke(Thread.currentThread(), (Class[]) null);
} catch (IllegalAccessException e) {
// ignore
} catch (InvocationTargetException e) {
/**
* InvocationTargetException is thrown by 'invoke' when
* the method being invoked (getContextClassLoader) throws
* an exception.
*
* getContextClassLoader() throws SecurityException when
* the context class loader isn't an ancestor of the
* calling class's class loader, or if security
* permissions are restricted.
*
* In the first case (not related), we want to ignore and
* keep going. We cannot help but also ignore the second
* with the logic below, but other calls elsewhere (to
* obtain a class loader) will trigger this exception where
* we can make a distinction.
*/
if (e.getTargetException() instanceof SecurityException) {
// ignore
} else {
// Capture 'e.getTargetException()' exception for details
// alternate: log 'e.getTargetException()', and pass back 'e'.
throw new LogConfigurationException
("Unexpected InvocationTargetException", e.getTargetException());
}
}
} catch (NoSuchMethodException e) {
// Assume we are running on JDK 1.1
// ignore
}
if (classLoader == null) {
classLoader = SimpleLog.class.getClassLoader();
}
// Return the selected class loader
return classLoader;
}
private static InputStream getResourceAsStream(final String name) {
return (InputStream)AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
ClassLoader threadCL = getContextClassLoader();
if (threadCL != null) {
return threadCL.getResourceAsStream(name);
} else {
return ClassLoader.getSystemResourceAsStream(name);
}
}
});
}
}

View File

@@ -0,0 +1,471 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Implementation of <code>Hashtable</code> that uses <code>WeakReference</code>'s
* to hold its keys thus allowing them to be reclaimed by the garbage collector.
* The associated values are retained using strong references.
* <p>
* This class follows the semantics of <code>Hashtable</code> as closely as
* possible. It therefore does not accept null values or keys.
* <p>
* <strong>Note:</strong>
* This is <em>not</em> intended to be a general purpose hash table replacement.
* This implementation is also tuned towards a particular purpose: for use as a replacement
* for <code>Hashtable</code> in <code>LogFactory</code>. This application requires
* good liveliness for <code>get</code> and <code>put</code>. Various tradeoffs
* have been made with this in mind.
* <p>
* <strong>Usage:</strong> typical use case is as a drop-in replacement
* for the <code>Hashtable</code> used in <code>LogFactory</code> for J2EE environments
* running 1.3+ JVMs. Use of this class <i>in most cases</i> (see below) will
* allow classloaders to be collected by the garbage collector without the need
* to call {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release(ClassLoader)}.
* <p>
* <code>org.apache.commons.logging.LogFactory</code> checks whether this class
* can be supported by the current JVM, and if so then uses it to store
* references to the <code>LogFactory</code> implementation it loads
* (rather than using a standard Hashtable instance).
* Having this class used instead of <code>Hashtable</code> solves
* certain issues related to dynamic reloading of applications in J2EE-style
* environments. However this class requires java 1.3 or later (due to its use
* of <code>java.lang.ref.WeakReference</code> and associates).
* And by the way, this extends <code>Hashtable</code> rather than <code>HashMap</code>
* for backwards compatibility reasons. See the documentation
* for method <code>LogFactory.createFactoryStore</code> for more details.
* <p>
* The reason all this is necessary is due to a issue which
* arises during hot deploy in a J2EE-like containers.
* Each component running in the container owns one or more classloaders; when
* the component loads a LogFactory instance via the component classloader
* a reference to it gets stored in the static LogFactory.factories member,
* keyed by the component's classloader so different components don't
* stomp on each other. When the component is later unloaded, the container
* sets the component's classloader to null with the intent that all the
* component's classes get garbage-collected. However there's still a
* reference to the component's classloader from a key in the "global"
* <code>LogFactory</code>'s factories member! If <code>LogFactory.release()</code>
* is called whenever component is unloaded, the classloaders will be correctly
* garbage collected; this <i>should</i> be done by any container that
* bundles commons-logging by default. However, holding the classloader
* references weakly ensures that the classloader will be garbage collected
* without the container performing this step.
* <p>
* <strong>Limitations:</strong>
* There is still one (unusual) scenario in which a component will not
* be correctly unloaded without an explicit release. Though weak references
* are used for its keys, it is necessary to use strong references for its values.
* <p>
* If the abstract class <code>LogFactory</code> is
* loaded by the container classloader but a subclass of
* <code>LogFactory</code> [LogFactory1] is loaded by the component's
* classloader and an instance stored in the static map associated with the
* base LogFactory class, then there is a strong reference from the LogFactory
* class to the LogFactory1 instance (as normal) and a strong reference from
* the LogFactory1 instance to the component classloader via
* <code>getClass().getClassLoader()</code>. This chain of references will prevent
* collection of the child classloader.
* <p>
* Such a situation occurs when the commons-logging.jar is
* loaded by a parent classloader (e.g. a server level classloader in a
* servlet container) and a custom <code>LogFactory</code> implementation is
* loaded by a child classloader (e.g. a web app classloader).
* <p>
* To avoid this scenario, ensure
* that any custom LogFactory subclass is loaded by the same classloader as
* the base <code>LogFactory</code>. Creating custom LogFactory subclasses is,
* however, rare. The standard LogFactoryImpl class should be sufficient
* for most or all users.
*
* @version $Id$
* @since 1.1
*/
public final class WeakHashtable extends Hashtable {
/** Serializable version identifier. */
private static final long serialVersionUID = -1546036869799732453L;
/**
* The maximum number of times put() or remove() can be called before
* the map will be purged of all cleared entries.
*/
private static final int MAX_CHANGES_BEFORE_PURGE = 100;
/**
* The maximum number of times put() or remove() can be called before
* the map will be purged of one cleared entry.
*/
private static final int PARTIAL_PURGE_COUNT = 10;
/* ReferenceQueue we check for gc'd keys */
private final ReferenceQueue queue = new ReferenceQueue();
/* Counter used to control how often we purge gc'd entries */
private int changeCount = 0;
/**
* Constructs a WeakHashtable with the Hashtable default
* capacity and load factor.
*/
public WeakHashtable() {}
/**
*@see Hashtable
*/
public boolean containsKey(Object key) {
// purge should not be required
Referenced referenced = new Referenced(key);
return super.containsKey(referenced);
}
/**
*@see Hashtable
*/
public Enumeration elements() {
purge();
return super.elements();
}
/**
*@see Hashtable
*/
public Set entrySet() {
purge();
Set referencedEntries = super.entrySet();
Set unreferencedEntries = new HashSet();
for (Iterator it=referencedEntries.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Referenced referencedKey = (Referenced) entry.getKey();
Object key = referencedKey.getValue();
Object value = entry.getValue();
if (key != null) {
Entry dereferencedEntry = new Entry(key, value);
unreferencedEntries.add(dereferencedEntry);
}
}
return unreferencedEntries;
}
/**
*@see Hashtable
*/
public Object get(Object key) {
// for performance reasons, no purge
Referenced referenceKey = new Referenced(key);
return super.get(referenceKey);
}
/**
*@see Hashtable
*/
public Enumeration keys() {
purge();
final Enumeration enumer = super.keys();
return new Enumeration() {
public boolean hasMoreElements() {
return enumer.hasMoreElements();
}
public Object nextElement() {
Referenced nextReference = (Referenced) enumer.nextElement();
return nextReference.getValue();
}
};
}
/**
*@see Hashtable
*/
public Set keySet() {
purge();
Set referencedKeys = super.keySet();
Set unreferencedKeys = new HashSet();
for (Iterator it=referencedKeys.iterator(); it.hasNext();) {
Referenced referenceKey = (Referenced) it.next();
Object keyValue = referenceKey.getValue();
if (keyValue != null) {
unreferencedKeys.add(keyValue);
}
}
return unreferencedKeys;
}
/**
*@see Hashtable
*/
public Object put(Object key, Object value) {
// check for nulls, ensuring semantics match superclass
if (key == null) {
throw new NullPointerException("Null keys are not allowed");
}
if (value == null) {
throw new NullPointerException("Null values are not allowed");
}
// for performance reasons, only purge every
// MAX_CHANGES_BEFORE_PURGE times
if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) {
purge();
changeCount = 0;
}
// do a partial purge more often
else if (changeCount % PARTIAL_PURGE_COUNT == 0) {
purgeOne();
}
Referenced keyRef = new Referenced(key, queue);
return super.put(keyRef, value);
}
/**
*@see Hashtable
*/
public void putAll(Map t) {
if (t != null) {
Set entrySet = t.entrySet();
for (Iterator it=entrySet.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
put(entry.getKey(), entry.getValue());
}
}
}
/**
*@see Hashtable
*/
public Collection values() {
purge();
return super.values();
}
/**
*@see Hashtable
*/
public Object remove(Object key) {
// for performance reasons, only purge every
// MAX_CHANGES_BEFORE_PURGE times
if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) {
purge();
changeCount = 0;
}
// do a partial purge more often
else if (changeCount % PARTIAL_PURGE_COUNT == 0) {
purgeOne();
}
return super.remove(new Referenced(key));
}
/**
*@see Hashtable
*/
public boolean isEmpty() {
purge();
return super.isEmpty();
}
/**
*@see Hashtable
*/
public int size() {
purge();
return super.size();
}
/**
*@see Hashtable
*/
public String toString() {
purge();
return super.toString();
}
/**
* @see Hashtable
*/
protected void rehash() {
// purge here to save the effort of rehashing dead entries
purge();
super.rehash();
}
/**
* Purges all entries whose wrapped keys
* have been garbage collected.
*/
private void purge() {
synchronized (queue) {
WeakKey key;
while ((key = (WeakKey) queue.poll()) != null) {
super.remove(key.getReferenced());
}
}
}
/**
* Purges one entry whose wrapped key
* has been garbage collected.
*/
private void purgeOne() {
synchronized (queue) {
WeakKey key = (WeakKey) queue.poll();
if (key != null) {
super.remove(key.getReferenced());
}
}
}
/** Entry implementation */
private final static class Entry implements Map.Entry {
private final Object key;
private final Object value;
private Entry(Object key, Object value) {
this.key = key;
this.value = value;
}
public boolean equals(Object o) {
boolean result = false;
if (o != null && o instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) o;
result = (getKey()==null ?
entry.getKey() == null :
getKey().equals(entry.getKey())) &&
(getValue()==null ?
entry.getValue() == null :
getValue().equals(entry.getValue()));
}
return result;
}
public int hashCode() {
return (getKey()==null ? 0 : getKey().hashCode()) ^
(getValue()==null ? 0 : getValue().hashCode());
}
public Object setValue(Object value) {
throw new UnsupportedOperationException("Entry.setValue is not supported.");
}
public Object getValue() {
return value;
}
public Object getKey() {
return key;
}
}
/** Wrapper giving correct symantics for equals and hashcode */
private final static class Referenced {
private final WeakReference reference;
private final int hashCode;
/**
*
* @throws NullPointerException if referant is <code>null</code>
*/
private Referenced(Object referant) {
reference = new WeakReference(referant);
// Calc a permanent hashCode so calls to Hashtable.remove()
// work if the WeakReference has been cleared
hashCode = referant.hashCode();
}
/**
*
* @throws NullPointerException if key is <code>null</code>
*/
private Referenced(Object key, ReferenceQueue queue) {
reference = new WeakKey(key, queue, this);
// Calc a permanent hashCode so calls to Hashtable.remove()
// work if the WeakReference has been cleared
hashCode = key.hashCode();
}
public int hashCode() {
return hashCode;
}
private Object getValue() {
return reference.get();
}
public boolean equals(Object o) {
boolean result = false;
if (o instanceof Referenced) {
Referenced otherKey = (Referenced) o;
Object thisKeyValue = getValue();
Object otherKeyValue = otherKey.getValue();
if (thisKeyValue == null) {
result = otherKeyValue == null;
// Since our hashcode was calculated from the original
// non-null referant, the above check breaks the
// hashcode/equals contract, as two cleared Referenced
// objects could test equal but have different hashcodes.
// We can reduce (not eliminate) the chance of this
// happening by comparing hashcodes.
result = result && this.hashCode() == otherKey.hashCode();
// In any case, as our c'tor does not allow null referants
// and Hashtable does not do equality checks between
// existing keys, normal hashtable operations should never
// result in an equals comparison between null referants
}
else
{
result = thisKeyValue.equals(otherKeyValue);
}
}
return result;
}
}
/**
* WeakReference subclass that holds a hard reference to an
* associated <code>value</code> and also makes accessible
* the Referenced object holding it.
*/
private final static class WeakKey extends WeakReference {
private final Referenced referenced;
private WeakKey(Object key,
ReferenceQueue queue,
Referenced referenced) {
super(key, queue);
this.referenced = referenced;
}
private Referenced getReferenced() {
return referenced;
}
}
}

View File

@@ -0,0 +1,22 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<body>
<p>Concrete implementations of commons-logging wrapper APIs.</p>
</body>

View File

@@ -0,0 +1,255 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<body>
<p>Simple wrapper API around multiple logging APIs.</p>
<h3>Overview</h3>
<p>This package provides an API for logging in server-based applications that
can be used around a variety of different logging implementations, including
prebuilt support for the following:</p>
<ul>
<li><a href="http://logging.apache.org/log4j/">Log4J</a> (version 1.2 or later)
from Apache's Logging project. Each named <a href="Log.html">Log</a>
instance is connected to a corresponding Log4J Logger.</li>
<li><a href="http://java.sun.com/j2se/1.4/docs/guide/util/logging/index.html">
JDK Logging API</a>, included in JDK 1.4 or later systems. Each named
<a href="Log.html">Log</a> instance is connected to a corresponding
<code>java.util.logging.Logger</code> instance.</li>
<li><a href="http://avalon.apache.org/logkit/">LogKit</a> from Apache's
Avalon project. Each named <a href="Log.html">Log</a> instance is
connected to a corresponding LogKit <code>Logger</code>.</li>
<li><a href="impl/NoOpLog.html">NoOpLog</a> implementation that simply swallows
all log output, for all named <a href="Log.html">Log</a> instances.</li>
<li><a href="impl/SimpleLog.html">SimpleLog</a> implementation that writes all
log output, for all named <a href="Log.html">Log</a> instances, to
System.err.</li>
</ul>
<h3>Quick Start Guide</h3>
<p>For those impatient to just get on with it, the following example
illustrates the typical declaration and use of a logger that is named (by
convention) after the calling class:
<pre>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Foo {
private Log log = LogFactory.getLog(Foo.class);
public void foo() {
...
try {
if (log.isDebugEnabled()) {
log.debug("About to do something to object " + name);
}
name.bar();
} catch (IllegalStateException e) {
log.error("Something bad happened to " + name, e);
}
...
}
</pre>
<p>Unless you configure things differently, all log output will be written
to System.err. Therefore, you really will want to review the remainder of
this page in order to understand how to configure logging for your
application.</p>
<h3>Configuring the Commons Logging Package</h3>
<h4>Choosing a <code>LogFactory</code> Implementation</h4>
<p>From an application perspective, the first requirement is to retrieve an
object reference to the <code>LogFactory</code> instance that will be used
to create <code><a href="Log.html">Log</a></code> instances for this
application. This is normally accomplished by calling the static
<code>getFactory()</code> method. This method implements the following
discovery algorithm to select the name of the <code>LogFactory</code>
implementation class this application wants to use:</p>
<ul>
<li>Check for a system property named
<code>org.apache.commons.logging.LogFactory</code>.</li>
<li>Use the JDK 1.3 JAR Services Discovery mechanism (see
<a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html">
http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html</a> for
more information) to look for a resource named
<code>META-INF/services/org.apache.commons.logging.LogFactory</code>
whose first line is assumed to contain the desired class name.</li>
<li>Look for a properties file named <code>commons-logging.properties</code>
visible in the application class path, with a property named
<code>org.apache.commons.logging.LogFactory</code> defining the
desired implementation class name.</li>
<li>Fall back to a default implementation, which is described
further below.</li>
</ul>
<p>If a <code>commons-logging.properties</code> file is found, all of the
properties defined there are also used to set configuration attributes on
the instantiated <code>LogFactory</code> instance.</p>
<p>Once an implementation class name is selected, the corresponding class is
loaded from the current Thread context class loader (if there is one), or
from the class loader that loaded the <code>LogFactory</code> class itself
otherwise. This allows a copy of <code>commons-logging.jar</code> to be
shared in a multiple class loader environment (such as a servlet container),
but still allow each web application to provide its own <code>LogFactory</code>
implementation, if it so desires. An instance of this class will then be
created, and cached per class loader.
<h4>The Default <code>LogFactory</code> Implementation</h4>
<p>The Logging Package APIs include a default <code>LogFactory</code>
implementation class (<a href="impl/LogFactoryImpl.html">
org.apache.commons.logging.impl.LogFactoryImpl</a>) that is selected if no
other implementation class name can be discovered. Its primary purpose is
to create (as necessary) and return <a href="Log.html">Log</a> instances
in response to calls to the <code>getInstance()</code> method. The default
implementation uses the following rules:</p>
<ul>
<li>At most one <code>Log</code> instance of the same name will be created.
Subsequent <code>getInstance()</code> calls to the same
<code>LogFactory</code> instance, with the same name or <code>Class</code>
parameter, will return the same <code>Log</code> instance.</li>
<li>When a new <code>Log</code> instance must be created, the default
<code>LogFactory</code> implementation uses the following discovery
process:
<ul>
<li>Look for a configuration attribute of this factory named
<code>org.apache.commons.logging.Log</code> (for backwards
compatibility to pre-1.0 versions of this API, an attribute
<code>org.apache.commons.logging.log</code> is also consulted).</li>
<li>Look for a system property named
<code>org.apache.commons.logging.Log</code> (for backwards
compatibility to pre-1.0 versions of this API, a system property
<code>org.apache.commons.logging.log</code> is also consulted).</li>
<li>If the Log4J logging system is available in the application
class path, use the corresponding wrapper class
(<a href="impl/Log4JLogger.html">Log4JLogger</a>).</li>
<li>If the application is executing on a JDK 1.4 system, use
the corresponding wrapper class
(<a href="impl/Jdk14Logger.html">Jdk14Logger</a>).</li>
<li>Fall back to the default simple logging implementation
(<a href="impl/SimpleLog.html">SimpleLog</a>).</li>
</ul></li>
<li>Load the class of the specified name from the thread context class
loader (if any), or from the class loader that loaded the
<code>LogFactory</code> class otherwise.</li>
<li>Instantiate an instance of the selected <code>Log</code>
implementation class, passing the specified name as the single
argument to its constructor.</li>
</ul>
<p>See the <a href="impl/SimpleLog.html">SimpleLog</a> JavaDocs for detailed
configuration information for this default implementation.</p>
<h4>Configuring the Underlying Logging System</h4>
<p>The basic principle is that the user is totally responsible for the
configuration of the underlying logging system.
Commons-logging should not change the existing configuration.</p>
<p>Each individual <a href="Log.html">Log</a> implementation may
support its own configuration properties. These will be documented in the
class descriptions for the corresponding implementation class.</p>
<p>Finally, some <code>Log</code> implementations (such as the one for Log4J)
require an external configuration file for the entire logging environment.
This file should be prepared in a manner that is specific to the actual logging
technology being used.</p>
<h3>Using the Logging Package APIs</h3>
<p>Use of the Logging Package APIs, from the perspective of an application
component, consists of the following steps:</p>
<ol>
<li>Acquire a reference to an instance of
<a href="Log.html">org.apache.commons.logging.Log</a>, by calling the
factory method
<a href="LogFactory.html#getInstance(java.lang.String)">
LogFactory.getInstance(String name)</a>. Your application can contain
references to multiple loggers that are used for different
purposes. A typical scenario for a server application is to have each
major component of the server use its own Log instance.</li>
<li>Cause messages to be logged (if the corresponding detail level is enabled)
by calling appropriate methods (<code>trace()</code>, <code>debug()</code>,
<code>info()</code>, <code>warn()</code>, <code>error</code>, and
<code>fatal()</code>).</li>
</ol>
<p>For convenience, <code>LogFactory</code> also offers a static method
<code>getLog()</code> that combines the typical two-step pattern:</p>
<pre>
Log log = LogFactory.getFactory().getInstance(Foo.class);
</pre>
<p>into a single method call:</p>
<pre>
Log log = LogFactory.getLog(Foo.class);
</pre>
<p>For example, you might use the following technique to initialize and
use a <a href="Log.html">Log</a> instance in an application component:</p>
<pre>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyComponent {
protected Log log =
LogFactory.getLog(MyComponent.class);
// Called once at startup time
public void start() {
...
log.info("MyComponent started");
...
}
// Called once at shutdown time
public void stop() {
...
log.info("MyComponent stopped");
...
}
// Called repeatedly to process a particular argument value
// which you want logged if debugging is enabled
public void process(String value) {
...
// Do the string concatenation only if logging is enabled
if (log.isDebugEnabled())
log.debug("MyComponent processing " + value);
...
}
}
</pre>
</body>

View File

@@ -0,0 +1,35 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<title>Overview Documentation for COMMONS-LOGGING</title>
</head>
<body bgcolor="white">
<p>The <em>Logging Wrapper Library</em> component of the Apache Commons
subproject offers wrappers around an extensible set of concrete logging
implementations, so that application code based on it does not need to be
modified in order to select a different logging implementation.</p>
<p>See the
<a href="org/apache/commons/logging/package-summary.html#package_description">
Package Description</a> for the <code>org.apache.commons.logging</code>
package for more information.</p>
</body>
</html>