Sort members
This commit is contained in:
@@ -27,6 +27,11 @@ public class LogConfigurationException extends RuntimeException {
|
|||||||
/** Serializable version identifier. */
|
/** Serializable version identifier. */
|
||||||
private static final long serialVersionUID = 8486587136871052495L;
|
private static final long serialVersionUID = 8486587136871052495L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The underlying cause of this exception.
|
||||||
|
*/
|
||||||
|
protected Throwable cause;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new exception with {@code null} as its detail message.
|
* Construct a new exception with {@code null} as its detail message.
|
||||||
*/
|
*/
|
||||||
@@ -42,16 +47,6 @@ public class LogConfigurationException extends RuntimeException {
|
|||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new exception with the specified cause and a derived
|
|
||||||
* detail message.
|
|
||||||
*
|
|
||||||
* @param cause The underlying cause
|
|
||||||
*/
|
|
||||||
public LogConfigurationException(final Throwable cause) {
|
|
||||||
this(cause == null ? null : cause.toString(), cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new exception with the specified detail message and cause.
|
* Construct a new exception with the specified detail message and cause.
|
||||||
*
|
*
|
||||||
@@ -64,9 +59,14 @@ public class LogConfigurationException extends RuntimeException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The underlying cause of this exception.
|
* Construct a new exception with the specified cause and a derived
|
||||||
|
* detail message.
|
||||||
|
*
|
||||||
|
* @param cause The underlying cause
|
||||||
*/
|
*/
|
||||||
protected Throwable cause;
|
public LogConfigurationException(final Throwable cause) {
|
||||||
|
this(cause == null ? null : cause.toString(), cause);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the underlying cause of this exception (if any).
|
* Return the underlying cause of this exception (if any).
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -134,55 +134,18 @@ public class LogSource {
|
|||||||
|
|
||||||
// ------------------------------------------------------------ Constructor
|
// ------------------------------------------------------------ Constructor
|
||||||
|
|
||||||
/** Don't allow others to create instances. */
|
/**
|
||||||
private LogSource() {
|
* Get a {@code Log} instance by class.
|
||||||
|
*
|
||||||
|
* @param clazz a Class.
|
||||||
|
* @return a {@code Log} instance.
|
||||||
|
*/
|
||||||
|
static public Log getInstance(final Class clazz) {
|
||||||
|
return getInstance(clazz.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------- Class Methods
|
// ---------------------------------------------------------- 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).
|
|
||||||
*
|
|
||||||
* @param className class name.
|
|
||||||
* @throws LinkageError if there is missing dependency.
|
|
||||||
* @throws NoSuchMethodException if a matching method is not found.
|
|
||||||
* @throws SecurityException If a security manager, <i>s</i>, is present and the caller's class loader is not the same as or an ancestor of the class
|
|
||||||
* loader for the current class and invocation of {@link SecurityManager#checkPackageAccess s.checkPackageAccess()} denies
|
|
||||||
* access to the package of this class.
|
|
||||||
* @throws ClassNotFoundException if the class cannot be located
|
|
||||||
*/
|
|
||||||
static public void setLogImplementation(final String className)
|
|
||||||
throws LinkageError, NoSuchMethodException, SecurityException, ClassNotFoundException {
|
|
||||||
try {
|
|
||||||
final Class logclass = Class.forName(className);
|
|
||||||
final Class[] argtypes = new Class[1];
|
|
||||||
argtypes[0] = "".getClass();
|
|
||||||
logImplctor = logclass.getConstructor(argtypes);
|
|
||||||
} catch (final 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).
|
|
||||||
*
|
|
||||||
* @param logclass class.
|
|
||||||
* @throws LinkageError if there is missing dependency.
|
|
||||||
* @throws ExceptionInInitializerError unexpected exception has occurred in a static initializer.
|
|
||||||
* @throws NoSuchMethodException if a matching method is not found.
|
|
||||||
* @throws SecurityException If a security manager, <i>s</i>, is present and the caller's class loader is not the same as or an ancestor of the
|
|
||||||
* class loader for the current class and invocation of {@link SecurityManager#checkPackageAccess
|
|
||||||
* s.checkPackageAccess()} denies access to the package of this class.
|
|
||||||
*/
|
|
||||||
static public void setLogImplementation(final Class logclass)
|
|
||||||
throws LinkageError, ExceptionInInitializerError, NoSuchMethodException, SecurityException {
|
|
||||||
final Class[] argtypes = new Class[1];
|
|
||||||
argtypes[0] = "".getClass();
|
|
||||||
logImplctor = logclass.getConstructor(argtypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a {@code Log} instance by class name.
|
* Get a {@code Log} instance by class name.
|
||||||
*
|
*
|
||||||
@@ -194,13 +157,14 @@ public class LogSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a {@code Log} instance by class.
|
* Returns a {@link String} array containing the names of
|
||||||
|
* all logs known to me.
|
||||||
*
|
*
|
||||||
* @param clazz a Class.
|
* @return a {@link String} array containing the names of
|
||||||
* @return a {@code Log} instance.
|
* all logs known to me.
|
||||||
*/
|
*/
|
||||||
static public Log getInstance(final Class clazz) {
|
static public String[] getLogNames() {
|
||||||
return getInstance(clazz.getName());
|
return (String[]) logs.keySet().toArray(EMPTY_STRING_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,13 +200,49 @@ public class LogSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link String} array containing the names of
|
* Set the log implementation/log implementation factory by class. The given class must implement {@link Log}, and provide a constructor that takes a single
|
||||||
* all logs known to me.
|
* {@link String} argument (containing the name of the log).
|
||||||
*
|
*
|
||||||
* @return a {@link String} array containing the names of
|
* @param logclass class.
|
||||||
* all logs known to me.
|
* @throws LinkageError if there is missing dependency.
|
||||||
|
* @throws ExceptionInInitializerError unexpected exception has occurred in a static initializer.
|
||||||
|
* @throws NoSuchMethodException if a matching method is not found.
|
||||||
|
* @throws SecurityException If a security manager, <i>s</i>, is present and the caller's class loader is not the same as or an ancestor of the
|
||||||
|
* class loader for the current class and invocation of {@link SecurityManager#checkPackageAccess
|
||||||
|
* s.checkPackageAccess()} denies access to the package of this class.
|
||||||
*/
|
*/
|
||||||
static public String[] getLogNames() {
|
static public void setLogImplementation(final Class logclass)
|
||||||
return (String[]) logs.keySet().toArray(EMPTY_STRING_ARRAY);
|
throws LinkageError, ExceptionInInitializerError, NoSuchMethodException, SecurityException {
|
||||||
|
final Class[] argtypes = new Class[1];
|
||||||
|
argtypes[0] = "".getClass();
|
||||||
|
logImplctor = logclass.getConstructor(argtypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
* @param className class name.
|
||||||
|
* @throws LinkageError if there is missing dependency.
|
||||||
|
* @throws NoSuchMethodException if a matching method is not found.
|
||||||
|
* @throws SecurityException If a security manager, <i>s</i>, is present and the caller's class loader is not the same as or an ancestor of the class
|
||||||
|
* loader for the current class and invocation of {@link SecurityManager#checkPackageAccess s.checkPackageAccess()} denies
|
||||||
|
* access to the package of this class.
|
||||||
|
* @throws ClassNotFoundException if the class cannot be located
|
||||||
|
*/
|
||||||
|
static public void setLogImplementation(final String className)
|
||||||
|
throws LinkageError, NoSuchMethodException, SecurityException, ClassNotFoundException {
|
||||||
|
try {
|
||||||
|
final Class logclass = Class.forName(className);
|
||||||
|
final Class[] argtypes = new Class[1];
|
||||||
|
argtypes[0] = "".getClass();
|
||||||
|
logImplctor = logclass.getConstructor(argtypes);
|
||||||
|
} catch (final Throwable t) {
|
||||||
|
logImplctor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Don't allow others to create instances. */
|
||||||
|
private LogSource() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,16 @@ public class AvalonLogger implements Log {
|
|||||||
/** Ancestral Avalon logger. */
|
/** Ancestral Avalon logger. */
|
||||||
private static volatile Logger defaultLogger;
|
private static volatile Logger defaultLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(final Logger logger) {
|
||||||
|
defaultLogger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
/** Avalon logger used to perform log. */
|
/** Avalon logger used to perform log. */
|
||||||
private final transient Logger logger;
|
private final transient Logger logger;
|
||||||
|
|
||||||
@@ -82,22 +92,16 @@ public class AvalonLogger implements Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Avalon logger implementation used to perform logging.
|
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.debug}.
|
||||||
*
|
*
|
||||||
* @return avalon logger implementation
|
* @param message to log.
|
||||||
|
* @see org.apache.commons.logging.Log#debug(Object)
|
||||||
*/
|
*/
|
||||||
public Logger getLogger() {
|
@Override
|
||||||
return logger;
|
public void debug(final Object message) {
|
||||||
|
if (getLogger().isDebugEnabled()) {
|
||||||
|
getLogger().debug(String.valueOf(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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(final Logger logger) {
|
|
||||||
defaultLogger = logger;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,15 +119,15 @@ public class AvalonLogger implements Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.debug}.
|
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.error}.
|
||||||
*
|
*
|
||||||
* @param message to log.
|
* @param message to log
|
||||||
* @see org.apache.commons.logging.Log#debug(Object)
|
* @see org.apache.commons.logging.Log#error(Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void debug(final Object message) {
|
public void error(final Object message) {
|
||||||
if (getLogger().isDebugEnabled()) {
|
if (getLogger().isErrorEnabled()) {
|
||||||
getLogger().debug(String.valueOf(message));
|
getLogger().error(String.valueOf(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,15 +146,15 @@ public class AvalonLogger implements Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.error}.
|
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.fatalError}.
|
||||||
*
|
*
|
||||||
* @param message to log
|
* @param message to log
|
||||||
* @see org.apache.commons.logging.Log#error(Object)
|
* @see org.apache.commons.logging.Log#fatal(Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void error(final Object message) {
|
public void fatal(final Object message) {
|
||||||
if (getLogger().isErrorEnabled()) {
|
if (getLogger().isFatalErrorEnabled()) {
|
||||||
getLogger().error(String.valueOf(message));
|
getLogger().fatalError(String.valueOf(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,15 +173,24 @@ public class AvalonLogger implements Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.fatalError}.
|
* Gets the Avalon logger implementation used to perform logging.
|
||||||
|
*
|
||||||
|
* @return avalon logger implementation
|
||||||
|
*/
|
||||||
|
public Logger getLogger() {
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.info}.
|
||||||
*
|
*
|
||||||
* @param message to log
|
* @param message to log
|
||||||
* @see org.apache.commons.logging.Log#fatal(Object)
|
* @see org.apache.commons.logging.Log#info(Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void fatal(final Object message) {
|
public void info(final Object message) {
|
||||||
if (getLogger().isFatalErrorEnabled()) {
|
if (getLogger().isInfoEnabled()) {
|
||||||
getLogger().fatalError(String.valueOf(message));
|
getLogger().info(String.valueOf(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,19 +208,6 @@ public class AvalonLogger implements Log {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.info}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#info(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void info(final Object message) {
|
|
||||||
if (getLogger().isInfoEnabled()) {
|
|
||||||
getLogger().info(String.valueOf(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is logging to {@code org.apache.avalon.framework.logger.Logger.debug} enabled?
|
* Is logging to {@code org.apache.avalon.framework.logger.Logger.debug} enabled?
|
||||||
* @see org.apache.commons.logging.Log#isDebugEnabled()
|
* @see org.apache.commons.logging.Log#isDebugEnabled()
|
||||||
@@ -262,6 +262,19 @@ public class AvalonLogger implements Log {
|
|||||||
return getLogger().isWarnEnabled();
|
return getLogger().isWarnEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.debug}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#trace(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void trace(final Object message) {
|
||||||
|
if (getLogger().isDebugEnabled()) {
|
||||||
|
getLogger().debug(String.valueOf(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.debug}.
|
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.debug}.
|
||||||
*
|
*
|
||||||
@@ -277,15 +290,15 @@ public class AvalonLogger implements Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.debug}.
|
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.warn}.
|
||||||
*
|
*
|
||||||
* @param message to log
|
* @param message to log
|
||||||
* @see org.apache.commons.logging.Log#trace(Object)
|
* @see org.apache.commons.logging.Log#warn(Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void trace(final Object message) {
|
public void warn(final Object message) {
|
||||||
if (getLogger().isDebugEnabled()) {
|
if (getLogger().isWarnEnabled()) {
|
||||||
getLogger().debug(String.valueOf(message));
|
getLogger().warn(String.valueOf(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,17 +315,4 @@ public class AvalonLogger implements Log {
|
|||||||
getLogger().warn(String.valueOf(message), t);
|
getLogger().warn(String.valueOf(message), t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.avalon.framework.logger.Logger.warn}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#warn(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void warn(final Object message) {
|
|
||||||
if (getLogger().isWarnEnabled()) {
|
|
||||||
getLogger().warn(String.valueOf(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,14 @@ public class Jdk13LumberjackLogger implements Log, Serializable {
|
|||||||
|
|
||||||
// ----------------------------------------------------- Instance Variables
|
// ----------------------------------------------------- Instance Variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This member variable simply ensures that any attempt to initialize
|
||||||
|
* 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The underlying Logger implementation we are using.
|
* The underlying Logger implementation we are using.
|
||||||
*/
|
*/
|
||||||
@@ -62,14 +70,6 @@ public class Jdk13LumberjackLogger implements Log, Serializable {
|
|||||||
/** Class and method found flag. */
|
/** Class and method found flag. */
|
||||||
private boolean classAndMethodFound;
|
private boolean classAndMethodFound;
|
||||||
|
|
||||||
/**
|
|
||||||
* This member variable simply ensures that any attempt to initialize
|
|
||||||
* 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
|
// ----------------------------------------------------------- Constructors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,55 +84,6 @@ public class Jdk13LumberjackLogger implements Log, Serializable {
|
|||||||
|
|
||||||
// --------------------------------------------------------- Public Methods
|
// --------------------------------------------------------- Public Methods
|
||||||
|
|
||||||
private void log( final Level level, final String msg, final Throwable ex ) {
|
|
||||||
if ( getLogger().isLoggable(level) ) {
|
|
||||||
final 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 {
|
|
||||||
final Throwable throwable = new Throwable();
|
|
||||||
throwable.fillInStackTrace();
|
|
||||||
final StringWriter stringWriter = new StringWriter();
|
|
||||||
final PrintWriter printWriter = new PrintWriter( stringWriter );
|
|
||||||
throwable.printStackTrace( printWriter );
|
|
||||||
final String traceString = stringWriter.getBuffer().toString();
|
|
||||||
final StringTokenizer tokenizer =
|
|
||||||
new StringTokenizer( traceString, "\n" );
|
|
||||||
tokenizer.nextToken();
|
|
||||||
String line = tokenizer.nextToken();
|
|
||||||
while (!line.contains(this.getClass().getName())) {
|
|
||||||
line = tokenizer.nextToken();
|
|
||||||
}
|
|
||||||
while (line.contains(this.getClass().getName())) {
|
|
||||||
line = tokenizer.nextToken();
|
|
||||||
}
|
|
||||||
final int start = line.indexOf( "at " ) + 3;
|
|
||||||
final int end = line.indexOf( '(' );
|
|
||||||
final String temp = line.substring( start, end );
|
|
||||||
final int lastPeriod = temp.lastIndexOf( '.' );
|
|
||||||
sourceClassName = temp.substring( 0, lastPeriod );
|
|
||||||
sourceMethodName = temp.substring( lastPeriod + 1 );
|
|
||||||
} catch ( final Exception ex ) {
|
|
||||||
// ignore - leave class and methodname unknown
|
|
||||||
}
|
|
||||||
classAndMethodFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code java.util.logging.Level.FINE}.
|
* Logs a message with {@code java.util.logging.Level.FINE}.
|
||||||
*
|
*
|
||||||
@@ -202,6 +153,40 @@ public class Jdk13LumberjackLogger implements Log, Serializable {
|
|||||||
log(Level.SEVERE, String.valueOf(message), exception);
|
log(Level.SEVERE, String.valueOf(message), exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the class and method by looking at the stack trace for the
|
||||||
|
* first entry that is not this class.
|
||||||
|
*/
|
||||||
|
private void getClassAndMethod() {
|
||||||
|
try {
|
||||||
|
final Throwable throwable = new Throwable();
|
||||||
|
throwable.fillInStackTrace();
|
||||||
|
final StringWriter stringWriter = new StringWriter();
|
||||||
|
final PrintWriter printWriter = new PrintWriter( stringWriter );
|
||||||
|
throwable.printStackTrace( printWriter );
|
||||||
|
final String traceString = stringWriter.getBuffer().toString();
|
||||||
|
final StringTokenizer tokenizer =
|
||||||
|
new StringTokenizer( traceString, "\n" );
|
||||||
|
tokenizer.nextToken();
|
||||||
|
String line = tokenizer.nextToken();
|
||||||
|
while (!line.contains(this.getClass().getName())) {
|
||||||
|
line = tokenizer.nextToken();
|
||||||
|
}
|
||||||
|
while (line.contains(this.getClass().getName())) {
|
||||||
|
line = tokenizer.nextToken();
|
||||||
|
}
|
||||||
|
final int start = line.indexOf( "at " ) + 3;
|
||||||
|
final int end = line.indexOf( '(' );
|
||||||
|
final String temp = line.substring( start, end );
|
||||||
|
final int lastPeriod = temp.lastIndexOf( '.' );
|
||||||
|
sourceClassName = temp.substring( 0, lastPeriod );
|
||||||
|
sourceMethodName = temp.substring( lastPeriod + 1 );
|
||||||
|
} catch ( final Exception ex ) {
|
||||||
|
// ignore - leave class and methodname unknown
|
||||||
|
}
|
||||||
|
classAndMethodFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the native Logger instance we are using.
|
* Return the native Logger instance we are using.
|
||||||
*
|
*
|
||||||
@@ -285,6 +270,21 @@ public class Jdk13LumberjackLogger implements Log, Serializable {
|
|||||||
return getLogger().isLoggable(Level.WARNING);
|
return getLogger().isLoggable(Level.WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void log( final Level level, final String msg, final Throwable ex ) {
|
||||||
|
if ( getLogger().isLoggable(level) ) {
|
||||||
|
final LogRecord record = new LogRecord(level, msg);
|
||||||
|
if ( !classAndMethodFound ) {
|
||||||
|
getClassAndMethod();
|
||||||
|
}
|
||||||
|
record.setSourceClassName(sourceClassName);
|
||||||
|
record.setSourceMethodName(sourceMethodName);
|
||||||
|
if ( ex != null ) {
|
||||||
|
record.setThrown(ex);
|
||||||
|
}
|
||||||
|
getLogger().log(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code java.util.logging.Level.FINEST}.
|
* Logs a message with {@code java.util.logging.Level.FINEST}.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -43,16 +43,6 @@ public class Jdk14Logger implements Log, Serializable {
|
|||||||
|
|
||||||
// ----------------------------------------------------------- Constructors
|
// ----------------------------------------------------------- Constructors
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a named instance of this Logger.
|
|
||||||
*
|
|
||||||
* @param name Name of the logger to be constructed
|
|
||||||
*/
|
|
||||||
public Jdk14Logger(final String name) {
|
|
||||||
this.name = name;
|
|
||||||
logger = getLogger();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The underlying Logger implementation we are using.
|
* The underlying Logger implementation we are using.
|
||||||
*/
|
*/
|
||||||
@@ -64,31 +54,13 @@ public class Jdk14Logger implements Log, Serializable {
|
|||||||
protected String name;
|
protected String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message at the given level.
|
* Construct a named instance of this Logger.
|
||||||
* @param level The level.
|
*
|
||||||
* @param msg The message.
|
* @param name Name of the logger to be constructed
|
||||||
* @param ex The exception.
|
|
||||||
*/
|
*/
|
||||||
protected void log(final Level level, final String msg, final Throwable ex) {
|
public Jdk14Logger(final String name) {
|
||||||
final Logger logger = getLogger();
|
this.name = name;
|
||||||
if (logger.isLoggable(level)) {
|
logger = getLogger();
|
||||||
// Hack (?) to get the stack trace.
|
|
||||||
final Throwable dummyException = new Throwable();
|
|
||||||
final StackTraceElement[] locations = dummyException.getStackTrace();
|
|
||||||
// LOGGING-132: use the provided logger name instead of the class name
|
|
||||||
final String cname = name;
|
|
||||||
String method = "unknown";
|
|
||||||
// Caller will be the third element
|
|
||||||
if (locations != null && locations.length > 2) {
|
|
||||||
final StackTraceElement caller = locations[2];
|
|
||||||
method = caller.getMethodName();
|
|
||||||
}
|
|
||||||
if (ex == null) {
|
|
||||||
logger.logp(level, cname, method, msg);
|
|
||||||
} else {
|
|
||||||
logger.logp(level, cname, method, msg, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -243,6 +215,34 @@ public class Jdk14Logger implements Log, Serializable {
|
|||||||
return getLogger().isLoggable(Level.WARNING);
|
return getLogger().isLoggable(Level.WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message at the given level.
|
||||||
|
* @param level The level.
|
||||||
|
* @param msg The message.
|
||||||
|
* @param ex The exception.
|
||||||
|
*/
|
||||||
|
protected void log(final Level level, final String msg, final Throwable ex) {
|
||||||
|
final Logger logger = getLogger();
|
||||||
|
if (logger.isLoggable(level)) {
|
||||||
|
// Hack (?) to get the stack trace.
|
||||||
|
final Throwable dummyException = new Throwable();
|
||||||
|
final StackTraceElement[] locations = dummyException.getStackTrace();
|
||||||
|
// LOGGING-132: use the provided logger name instead of the class name
|
||||||
|
final String cname = name;
|
||||||
|
String method = "unknown";
|
||||||
|
// Caller will be the third element
|
||||||
|
if (locations != null && locations.length > 2) {
|
||||||
|
final StackTraceElement caller = locations[2];
|
||||||
|
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.FINEST}.
|
* Logs a message with {@code java.util.logging.Level.FINEST}.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -48,28 +48,8 @@ public class Log4JLogger implements Log, Serializable {
|
|||||||
/** The fully qualified name of the Log4JLogger class. */
|
/** The fully qualified name of the Log4JLogger class. */
|
||||||
private static final String FQCN = Log4JLogger.class.getName();
|
private static final String FQCN = Log4JLogger.class.getName();
|
||||||
|
|
||||||
/** Log to this logger */
|
|
||||||
private transient volatile Logger logger;
|
|
||||||
|
|
||||||
/** Logger name */
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
private static final Priority traceLevel;
|
private static final Priority traceLevel;
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
|
||||||
// Static Initializer.
|
|
||||||
//
|
|
||||||
// Note that this must come after the static variable declarations
|
|
||||||
// otherwise initializer 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 {
|
static {
|
||||||
if (!Priority.class.isAssignableFrom(Level.class)) {
|
if (!Priority.class.isAssignableFrom(Level.class)) {
|
||||||
// nope, this is log4j 1.3, so force an ExceptionInInitializerError
|
// nope, this is log4j 1.3, so force an ExceptionInInitializerError
|
||||||
@@ -90,6 +70,26 @@ public class Log4JLogger implements Log, Serializable {
|
|||||||
traceLevel = _traceLevel;
|
traceLevel = _traceLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Log to this logger */
|
||||||
|
private transient volatile Logger logger;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Static Initializer.
|
||||||
|
//
|
||||||
|
// Note that this must come after the static variable declarations
|
||||||
|
// otherwise initializer 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.
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Logger name */
|
||||||
|
private final String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new instance.
|
* Constructs a new instance.
|
||||||
*/
|
*/
|
||||||
@@ -97,16 +97,6 @@ public class Log4JLogger implements Log, Serializable {
|
|||||||
name = null;
|
name = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Base constructor.
|
|
||||||
*
|
|
||||||
* @param name name.
|
|
||||||
*/
|
|
||||||
public Log4JLogger(final String name) {
|
|
||||||
this.name = name;
|
|
||||||
this.logger = getLogger();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For use with a log4j factory.
|
* For use with a log4j factory.
|
||||||
*
|
*
|
||||||
@@ -122,30 +112,13 @@ public class Log4JLogger implements Log, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.log4j.Priority.TRACE}.
|
* Base constructor.
|
||||||
* When using a log4j version that does not support the {@code TRACE}
|
|
||||||
* level, the message will be logged at the {@code DEBUG} level.
|
|
||||||
*
|
*
|
||||||
* @param message to log
|
* @param name name.
|
||||||
* @see org.apache.commons.logging.Log#trace(Object)
|
|
||||||
*/
|
*/
|
||||||
@Override
|
public Log4JLogger(final String name) {
|
||||||
public void trace(final Object message) {
|
this.name = name;
|
||||||
getLogger().log(FQCN, traceLevel, message, null);
|
this.logger = getLogger();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log4j.Priority.TRACE}.
|
|
||||||
* When using a log4j version that does not support the {@code TRACE}
|
|
||||||
* level, the message will be logged at the {@code DEBUG} level.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void trace(final Object message, final Throwable t) {
|
|
||||||
getLogger().log(FQCN, traceLevel, message, t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -171,52 +144,6 @@ public class Log4JLogger implements Log, Serializable {
|
|||||||
getLogger().log(FQCN, Level.DEBUG, message, t);
|
getLogger().log(FQCN, Level.DEBUG, message, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log4j.Priority.INFO}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#info(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void info(final Object message) {
|
|
||||||
getLogger().log(FQCN, Level.INFO, message, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log4j.Priority.INFO}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#info(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void info(final Object message, final Throwable t) {
|
|
||||||
getLogger().log(FQCN, Level.INFO, message, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log4j.Priority.WARN}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#warn(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void warn(final Object message) {
|
|
||||||
getLogger().log(FQCN, Level.WARN, message, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log4j.Priority.WARN}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void warn(final Object message, final Throwable t) {
|
|
||||||
getLogger().log(FQCN, Level.WARN, message, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.log4j.Priority.ERROR}.
|
* Logs a message with {@code org.apache.log4j.Priority.ERROR}.
|
||||||
*
|
*
|
||||||
@@ -281,6 +208,29 @@ public class Log4JLogger implements Log, Serializable {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log4j.Priority.INFO}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#info(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void info(final Object message) {
|
||||||
|
getLogger().log(FQCN, Level.INFO, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log4j.Priority.INFO}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#info(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void info(final Object message, final Throwable t) {
|
||||||
|
getLogger().log(FQCN, Level.INFO, message, t);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether the Log4j Logger used is enabled for {@code DEBUG} priority.
|
* Tests whether the Log4j Logger used is enabled for {@code DEBUG} priority.
|
||||||
*/
|
*/
|
||||||
@@ -330,4 +280,54 @@ public class Log4JLogger implements Log, Serializable {
|
|||||||
public boolean isWarnEnabled() {
|
public boolean isWarnEnabled() {
|
||||||
return getLogger().isEnabledFor(Level.WARN);
|
return getLogger().isEnabledFor(Level.WARN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log4j.Priority.TRACE}.
|
||||||
|
* When using a log4j version that does not support the {@code TRACE}
|
||||||
|
* level, the message will be logged at the {@code DEBUG} level.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#trace(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void trace(final Object message) {
|
||||||
|
getLogger().log(FQCN, traceLevel, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log4j.Priority.TRACE}.
|
||||||
|
* When using a log4j version that does not support the {@code TRACE}
|
||||||
|
* level, the message will be logged at the {@code DEBUG} level.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void trace(final Object message, final Throwable t) {
|
||||||
|
getLogger().log(FQCN, traceLevel, message, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log4j.Priority.WARN}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#warn(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void warn(final Object message) {
|
||||||
|
getLogger().log(FQCN, Level.WARN, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log4j.Priority.WARN}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void warn(final Object message, final Throwable t) {
|
||||||
|
getLogger().log(FQCN, Level.WARN, message, t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -62,49 +62,6 @@ public class LogKitLogger implements Log, Serializable {
|
|||||||
|
|
||||||
// --------------------------------------------------------- Public Methods
|
// --------------------------------------------------------- Public Methods
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the underlying Logger we are using.
|
|
||||||
*
|
|
||||||
* @return the underlying Logger we are using.
|
|
||||||
*/
|
|
||||||
public Logger getLogger() {
|
|
||||||
Logger result = logger;
|
|
||||||
if (result == null) {
|
|
||||||
synchronized(this) {
|
|
||||||
result = logger;
|
|
||||||
if (result == null) {
|
|
||||||
logger = result = Hierarchy.getDefaultHierarchy().getLoggerFor(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------- Log Implementation
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log.Priority.DEBUG}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#trace(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void trace(final Object message) {
|
|
||||||
debug(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log.Priority.DEBUG}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void trace(final Object message, final Throwable t) {
|
|
||||||
debug(message, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.log.Priority.DEBUG}.
|
* Logs a message with {@code org.apache.log.Priority.DEBUG}.
|
||||||
*
|
*
|
||||||
@@ -118,6 +75,8 @@ public class LogKitLogger implements Log, Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Log Implementation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.log.Priority.DEBUG}.
|
* Logs a message with {@code org.apache.log.Priority.DEBUG}.
|
||||||
*
|
*
|
||||||
@@ -132,60 +91,6 @@ public class LogKitLogger implements Log, Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log.Priority.INFO}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#info(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void info(final Object message) {
|
|
||||||
if (message != null) {
|
|
||||||
getLogger().info(String.valueOf(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log.Priority.INFO}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#info(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void info(final Object message, final Throwable t) {
|
|
||||||
if (message != null) {
|
|
||||||
getLogger().info(String.valueOf(message), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log.Priority.WARN}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#warn(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void warn(final Object message) {
|
|
||||||
if (message != null) {
|
|
||||||
getLogger().warn(String.valueOf(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message with {@code org.apache.log.Priority.WARN}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void warn(final Object message, final Throwable t) {
|
|
||||||
if (message != null) {
|
|
||||||
getLogger().warn(String.valueOf(message), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message with {@code org.apache.log.Priority.ERROR}.
|
* Logs a message with {@code org.apache.log.Priority.ERROR}.
|
||||||
*
|
*
|
||||||
@@ -240,6 +145,51 @@ public class LogKitLogger implements Log, Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the underlying Logger we are using.
|
||||||
|
*
|
||||||
|
* @return the underlying Logger we are using.
|
||||||
|
*/
|
||||||
|
public Logger getLogger() {
|
||||||
|
Logger result = logger;
|
||||||
|
if (result == null) {
|
||||||
|
synchronized(this) {
|
||||||
|
result = logger;
|
||||||
|
if (result == null) {
|
||||||
|
logger = result = Hierarchy.getDefaultHierarchy().getLoggerFor(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log.Priority.INFO}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#info(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void info(final Object message) {
|
||||||
|
if (message != null) {
|
||||||
|
getLogger().info(String.valueOf(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log.Priority.INFO}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#info(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void info(final Object message, final Throwable t) {
|
||||||
|
if (message != null) {
|
||||||
|
getLogger().info(String.valueOf(message), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the {@code LogKit} logger will log messages of priority {@code DEBUG}.
|
* Checks whether the {@code LogKit} logger will log messages of priority {@code DEBUG}.
|
||||||
*/
|
*/
|
||||||
@@ -287,4 +237,54 @@ public class LogKitLogger implements Log, Serializable {
|
|||||||
public boolean isWarnEnabled() {
|
public boolean isWarnEnabled() {
|
||||||
return getLogger().isWarnEnabled();
|
return getLogger().isWarnEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log.Priority.DEBUG}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#trace(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void trace(final Object message) {
|
||||||
|
debug(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log.Priority.DEBUG}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void trace(final Object message, final Throwable t) {
|
||||||
|
debug(message, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log.Priority.WARN}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#warn(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void warn(final Object message) {
|
||||||
|
if (message != null) {
|
||||||
|
getLogger().warn(String.valueOf(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.log.Priority.WARN}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void warn(final Object message, final Throwable t) {
|
||||||
|
if (message != null) {
|
||||||
|
getLogger().warn(String.valueOf(message), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,16 +40,6 @@ public class NoOpLog implements Log, Serializable {
|
|||||||
public NoOpLog(final String name) {
|
public NoOpLog(final String name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Do nothing */
|
|
||||||
@Override
|
|
||||||
public void trace(final Object message) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Do nothing */
|
|
||||||
@Override
|
|
||||||
public void trace(final Object message, final Throwable t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Do nothing */
|
/** Do nothing */
|
||||||
@Override
|
@Override
|
||||||
public void debug(final Object message) {
|
public void debug(final Object message) {
|
||||||
@@ -60,26 +50,6 @@ public class NoOpLog implements Log, Serializable {
|
|||||||
public void debug(final Object message, final Throwable t) {
|
public void debug(final Object message, final Throwable t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Do nothing */
|
|
||||||
@Override
|
|
||||||
public void info(final Object message) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Do nothing */
|
|
||||||
@Override
|
|
||||||
public void info(final Object message, final Throwable t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Do nothing */
|
|
||||||
@Override
|
|
||||||
public void warn(final Object message) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Do nothing */
|
|
||||||
@Override
|
|
||||||
public void warn(final Object message, final Throwable t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Do nothing */
|
/** Do nothing */
|
||||||
@Override
|
@Override
|
||||||
public void error(final Object message) {
|
public void error(final Object message) {
|
||||||
@@ -100,6 +70,16 @@ public class NoOpLog implements Log, Serializable {
|
|||||||
public void fatal(final Object message, final Throwable t) {
|
public void fatal(final Object message, final Throwable t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Do nothing */
|
||||||
|
@Override
|
||||||
|
public void info(final Object message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Do nothing */
|
||||||
|
@Override
|
||||||
|
public void info(final Object message, final Throwable t) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug is never enabled.
|
* Debug is never enabled.
|
||||||
*
|
*
|
||||||
@@ -159,4 +139,24 @@ public class NoOpLog implements Log, Serializable {
|
|||||||
public final boolean isWarnEnabled() {
|
public final boolean isWarnEnabled() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Do nothing */
|
||||||
|
@Override
|
||||||
|
public void trace(final Object message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Do nothing */
|
||||||
|
@Override
|
||||||
|
public void trace(final Object message, final Throwable t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Do nothing */
|
||||||
|
@Override
|
||||||
|
public void warn(final Object message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Do nothing */
|
||||||
|
@Override
|
||||||
|
public void warn(final Object message, final Throwable t) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,26 +133,6 @@ public class SimpleLog implements Log, Serializable {
|
|||||||
|
|
||||||
// ------------------------------------------------------------ Initializer
|
// ------------------------------------------------------------ Initializer
|
||||||
|
|
||||||
private static String getStringProperty(final String name) {
|
|
||||||
String prop = null;
|
|
||||||
try {
|
|
||||||
prop = System.getProperty(name);
|
|
||||||
} catch (final SecurityException e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
return prop == null ? simpleLogProps.getProperty(name) : prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getStringProperty(final String name, final String dephault) {
|
|
||||||
final String prop = getStringProperty(name);
|
|
||||||
return prop == null ? dephault : prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean getBooleanProperty(final String name, final boolean dephault) {
|
|
||||||
final String prop = getStringProperty(name);
|
|
||||||
return prop == null ? dephault : "true".equalsIgnoreCase(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize class attributes.
|
// Initialize class attributes.
|
||||||
// Load properties file, if found.
|
// Load properties file, if found.
|
||||||
// Override with system properties.
|
// Override with system properties.
|
||||||
@@ -190,423 +170,9 @@ public class SimpleLog implements Log, Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------- Attributes
|
private static boolean getBooleanProperty(final String name, final boolean dephault) {
|
||||||
|
final String prop = getStringProperty(name);
|
||||||
/** The name of this simple log instance */
|
return prop == null ? dephault : "true".equalsIgnoreCase(prop);
|
||||||
protected volatile String logName;
|
|
||||||
/** The current log level */
|
|
||||||
protected volatile int currentLogLevel;
|
|
||||||
/** The short name of this simple log instance */
|
|
||||||
private volatile String shortLogName;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------ 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(final int currentLogLevel) {
|
|
||||||
this.currentLogLevel = currentLogLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get logging level.
|
|
||||||
*
|
|
||||||
* @return logging level.
|
|
||||||
*/
|
|
||||||
public int getLevel() {
|
|
||||||
return currentLogLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------- Logging Methods
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do the actual logging.
|
|
||||||
* <p>
|
|
||||||
* This method assembles the message and then calls {@code write()}
|
|
||||||
* 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(final int type, final Object message, final Throwable t) {
|
|
||||||
// Use a string buffer for better performance
|
|
||||||
final StringBuilder buf = new StringBuilder();
|
|
||||||
|
|
||||||
// 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 StringWriter sw = new StringWriter(1024);
|
|
||||||
final PrintWriter pw = new 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} to the appropriate output destination. The
|
|
||||||
* default implementation writes to {@code System.err}.
|
|
||||||
*
|
|
||||||
* @param buffer A {@code StringBuffer} containing the accumulated
|
|
||||||
* text to be logged
|
|
||||||
*/
|
|
||||||
protected void write(final StringBuffer buffer) {
|
|
||||||
System.err.println(buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the content of the message accumulated in the specified
|
|
||||||
* {@code StringBuffer} to the appropriate output destination. The
|
|
||||||
* default implementation writes to {@code System.err}.
|
|
||||||
*
|
|
||||||
* @param buffer A {@code StringBuffer} containing the accumulated
|
|
||||||
* text to be logged
|
|
||||||
*/
|
|
||||||
private void write(final Object buffer) {
|
|
||||||
System.err.println(buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests whether the given log level currently enabled.
|
|
||||||
*
|
|
||||||
* @param logLevel is this level enabled?
|
|
||||||
* @return whether the given log level currently enabled.
|
|
||||||
*/
|
|
||||||
protected boolean isLevelEnabled(final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#debug(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void debug(final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void debug(final Object message, final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#trace(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void trace(final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void trace(final Object message, final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#info(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void info(final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#info(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void info(final Object message, final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#warn(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void warn(final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void warn(final Object message, final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#error(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void error(final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#error(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void error(final Object message, final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @see org.apache.commons.logging.Log#fatal(Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void fatal(final 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}.
|
|
||||||
*
|
|
||||||
* @param message to log
|
|
||||||
* @param t log this cause
|
|
||||||
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void fatal(final Object message, final 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}
|
|
||||||
* concatenation to be avoided when the message will be ignored by the
|
|
||||||
* logger.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean isDebugEnabled() {
|
|
||||||
return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Are error messages currently enabled?
|
|
||||||
* <p>
|
|
||||||
* This allows expensive operations such as {@code String}
|
|
||||||
* concatenation to be avoided when the message will be ignored by the
|
|
||||||
* logger.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean isErrorEnabled() {
|
|
||||||
return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Are fatal messages currently enabled?
|
|
||||||
* <p>
|
|
||||||
* This allows expensive operations such as {@code String}
|
|
||||||
* concatenation to be avoided when the message will be ignored by the
|
|
||||||
* logger.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean isFatalEnabled() {
|
|
||||||
return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Are info messages currently enabled?
|
|
||||||
* <p>
|
|
||||||
* This allows expensive operations such as {@code String}
|
|
||||||
* concatenation to be avoided when the message will be ignored by the
|
|
||||||
* logger.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean isInfoEnabled() {
|
|
||||||
return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Are trace messages currently enabled?
|
|
||||||
* <p>
|
|
||||||
* This allows expensive operations such as {@code String}
|
|
||||||
* concatenation to be avoided when the message will be ignored by the
|
|
||||||
* logger.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean isTraceEnabled() {
|
|
||||||
return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Are warn messages currently enabled?
|
|
||||||
* <p>
|
|
||||||
* This allows expensive operations such as {@code String}
|
|
||||||
* concatenation to be avoided when the message will be ignored by the
|
|
||||||
* logger.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean isWarnEnabled() {
|
|
||||||
return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -682,5 +248,439 @@ public class SimpleLog implements Log, Serializable {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------- Attributes
|
||||||
|
|
||||||
|
private static String getStringProperty(final String name) {
|
||||||
|
String prop = null;
|
||||||
|
try {
|
||||||
|
prop = System.getProperty(name);
|
||||||
|
} catch (final SecurityException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
return prop == null ? simpleLogProps.getProperty(name) : prop;
|
||||||
|
}
|
||||||
|
private static String getStringProperty(final String name, final String dephault) {
|
||||||
|
final String prop = getStringProperty(name);
|
||||||
|
return prop == null ? dephault : prop;
|
||||||
|
}
|
||||||
|
/** The name of this simple log instance */
|
||||||
|
protected volatile String logName;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------ Constructor
|
||||||
|
|
||||||
|
/** The current log level */
|
||||||
|
protected volatile int currentLogLevel;
|
||||||
|
|
||||||
|
// -------------------------------------------------------- Properties
|
||||||
|
|
||||||
|
/** The short name of this simple log instance */
|
||||||
|
private volatile String shortLogName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------- Logging Methods
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with
|
||||||
|
* {@code org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#debug(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void debug(final 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}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void debug(final Object message, final 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_ERROR}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#error(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void error(final 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}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#error(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void error(final Object message, final Throwable t) {
|
||||||
|
if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
|
||||||
|
log(SimpleLog.LOG_LEVEL_ERROR, message, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------- Log Implementation
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message with {@code org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#fatal(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void fatal(final 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}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void fatal(final Object message, final Throwable t) {
|
||||||
|
if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
|
||||||
|
log(SimpleLog.LOG_LEVEL_FATAL, message, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get logging level.
|
||||||
|
*
|
||||||
|
* @return logging level.
|
||||||
|
*/
|
||||||
|
public int getLevel() {
|
||||||
|
return currentLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#info(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void info(final 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}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#info(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void info(final Object message, final Throwable t) {
|
||||||
|
if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
|
||||||
|
log(SimpleLog.LOG_LEVEL_INFO, message, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are debug messages currently enabled?
|
||||||
|
* <p>
|
||||||
|
* This allows expensive operations such as {@code String}
|
||||||
|
* concatenation to be avoided when the message will be ignored by the
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean isDebugEnabled() {
|
||||||
|
return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are error messages currently enabled?
|
||||||
|
* <p>
|
||||||
|
* This allows expensive operations such as {@code String}
|
||||||
|
* concatenation to be avoided when the message will be ignored by the
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean isErrorEnabled() {
|
||||||
|
return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are fatal messages currently enabled?
|
||||||
|
* <p>
|
||||||
|
* This allows expensive operations such as {@code String}
|
||||||
|
* concatenation to be avoided when the message will be ignored by the
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean isFatalEnabled() {
|
||||||
|
return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are info messages currently enabled?
|
||||||
|
* <p>
|
||||||
|
* This allows expensive operations such as {@code String}
|
||||||
|
* concatenation to be avoided when the message will be ignored by the
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean isInfoEnabled() {
|
||||||
|
return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether the given log level currently enabled.
|
||||||
|
*
|
||||||
|
* @param logLevel is this level enabled?
|
||||||
|
* @return whether the given log level currently enabled.
|
||||||
|
*/
|
||||||
|
protected boolean isLevelEnabled(final int logLevel) {
|
||||||
|
// log level are numerically ordered so can use simple numeric
|
||||||
|
// comparison
|
||||||
|
return logLevel >= currentLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are trace messages currently enabled?
|
||||||
|
* <p>
|
||||||
|
* This allows expensive operations such as {@code String}
|
||||||
|
* concatenation to be avoided when the message will be ignored by the
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean isTraceEnabled() {
|
||||||
|
return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are warn messages currently enabled?
|
||||||
|
* <p>
|
||||||
|
* This allows expensive operations such as {@code String}
|
||||||
|
* concatenation to be avoided when the message will be ignored by the
|
||||||
|
* logger.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean isWarnEnabled() {
|
||||||
|
return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do the actual logging.
|
||||||
|
* <p>
|
||||||
|
* This method assembles the message and then calls {@code write()}
|
||||||
|
* 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(final int type, final Object message, final Throwable t) {
|
||||||
|
// Use a string buffer for better performance
|
||||||
|
final StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
// 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 StringWriter sw = new StringWriter(1024);
|
||||||
|
final PrintWriter pw = new PrintWriter(sw);
|
||||||
|
t.printStackTrace(pw);
|
||||||
|
pw.close();
|
||||||
|
buf.append(sw.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print to the appropriate destination
|
||||||
|
write(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set logging level.
|
||||||
|
*
|
||||||
|
* @param currentLogLevel new logging level
|
||||||
|
*/
|
||||||
|
public void setLevel(final int currentLogLevel) {
|
||||||
|
this.currentLogLevel = currentLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with {@code org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#trace(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void trace(final 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}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void trace(final Object message, final 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_WARN}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @see org.apache.commons.logging.Log#warn(Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void warn(final 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}.
|
||||||
|
*
|
||||||
|
* @param message to log
|
||||||
|
* @param t log this cause
|
||||||
|
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void warn(final Object message, final Throwable t) {
|
||||||
|
if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
|
||||||
|
log(SimpleLog.LOG_LEVEL_WARN, message, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the content of the message accumulated in the specified
|
||||||
|
* {@code StringBuffer} to the appropriate output destination. The
|
||||||
|
* default implementation writes to {@code System.err}.
|
||||||
|
*
|
||||||
|
* @param buffer A {@code StringBuffer} containing the accumulated
|
||||||
|
* text to be logged
|
||||||
|
*/
|
||||||
|
private void write(final Object buffer) {
|
||||||
|
System.err.println(buffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the content of the message accumulated in the specified
|
||||||
|
* {@code StringBuffer} to the appropriate output destination. The
|
||||||
|
* default implementation writes to {@code System.err}.
|
||||||
|
*
|
||||||
|
* @param buffer A {@code StringBuffer} containing the accumulated
|
||||||
|
* text to be logged
|
||||||
|
*/
|
||||||
|
protected void write(final StringBuffer buffer) {
|
||||||
|
System.err.println(buffer.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,144 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public final class WeakHashtable extends Hashtable {
|
public final class WeakHashtable extends Hashtable {
|
||||||
|
|
||||||
|
/** Entry implementation */
|
||||||
|
private final static class Entry implements Map.Entry {
|
||||||
|
|
||||||
|
private final Object key;
|
||||||
|
private final Object value;
|
||||||
|
|
||||||
|
private Entry(final Object key, final Object value) {
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
boolean result = false;
|
||||||
|
if (o instanceof Map.Entry) {
|
||||||
|
final 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return (getKey()==null ? 0 : getKey().hashCode()) ^
|
||||||
|
(getValue()==null ? 0 : getValue().hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object setValue(final Object value) {
|
||||||
|
throw new UnsupportedOperationException("Entry.setValue is not supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Wrapper giving correct symantics for equals and hash code */
|
||||||
|
private final static class Referenced {
|
||||||
|
|
||||||
|
private final WeakReference reference;
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if referant is {@code null}
|
||||||
|
*/
|
||||||
|
private Referenced(final 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}
|
||||||
|
*/
|
||||||
|
private Referenced(final Object key, final 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();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
boolean result = false;
|
||||||
|
if (o instanceof Referenced) {
|
||||||
|
final Referenced otherKey = (Referenced) o;
|
||||||
|
final Object thisKeyValue = getValue();
|
||||||
|
final Object otherKeyValue = otherKey.getValue();
|
||||||
|
if (thisKeyValue == null) {
|
||||||
|
result = otherKeyValue == null;
|
||||||
|
|
||||||
|
// Since our hash code was calculated from the original
|
||||||
|
// non-null referant, the above check breaks the
|
||||||
|
// hash code/equals contract, as two cleared Referenced
|
||||||
|
// objects could test equal but have different hash codes.
|
||||||
|
// We can reduce (not eliminate) the chance of this
|
||||||
|
// happening by comparing hash codes.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getValue() {
|
||||||
|
return reference.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WeakReference subclass that holds a hard reference to an
|
||||||
|
* associated {@code value} and also makes accessible
|
||||||
|
* the Referenced object holding it.
|
||||||
|
*/
|
||||||
|
private final static class WeakKey extends WeakReference {
|
||||||
|
|
||||||
|
private final Referenced referenced;
|
||||||
|
|
||||||
|
private WeakKey(final Object key,
|
||||||
|
final ReferenceQueue queue,
|
||||||
|
final Referenced referenced) {
|
||||||
|
super(key, queue);
|
||||||
|
this.referenced = referenced;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Referenced getReferenced() {
|
||||||
|
return referenced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Serializable version identifier. */
|
/** Serializable version identifier. */
|
||||||
private static final long serialVersionUID = -1546036869799732453L;
|
private static final long serialVersionUID = -1546036869799732453L;
|
||||||
|
|
||||||
@@ -186,6 +324,15 @@ public final class WeakHashtable extends Hashtable {
|
|||||||
return super.get(referenceKey);
|
return super.get(referenceKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@see Hashtable
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
purge();
|
||||||
|
return super.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*@see Hashtable
|
*@see Hashtable
|
||||||
*/
|
*/
|
||||||
@@ -224,6 +371,41 @@ public final class WeakHashtable extends Hashtable {
|
|||||||
return unreferencedKeys;
|
return unreferencedKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purges all entries whose wrapped keys
|
||||||
|
* have been garbage collected.
|
||||||
|
*/
|
||||||
|
private void purge() {
|
||||||
|
final List toRemove = new ArrayList();
|
||||||
|
synchronized (queue) {
|
||||||
|
WeakKey key;
|
||||||
|
while ((key = (WeakKey) queue.poll()) != null) {
|
||||||
|
toRemove.add(key.getReferenced());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOGGING-119: do the actual removal of the keys outside the sync block
|
||||||
|
// to prevent deadlock scenarios as purge() may be called from
|
||||||
|
// non-synchronized methods too
|
||||||
|
final int size = toRemove.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
super.remove(toRemove.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purges one entry whose wrapped key
|
||||||
|
* has been garbage collected.
|
||||||
|
*/
|
||||||
|
private void purgeOne() {
|
||||||
|
synchronized (queue) {
|
||||||
|
final WeakKey key = (WeakKey) queue.poll();
|
||||||
|
if (key != null) {
|
||||||
|
super.remove(key.getReferenced());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*@see Hashtable
|
*@see Hashtable
|
||||||
*/
|
*/
|
||||||
@@ -266,9 +448,10 @@ public final class WeakHashtable extends Hashtable {
|
|||||||
* @see Hashtable
|
* @see Hashtable
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Collection values() {
|
protected void rehash() {
|
||||||
|
// purge here to save the effort of rehashing dead entries
|
||||||
purge();
|
purge();
|
||||||
return super.values();
|
super.rehash();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -289,15 +472,6 @@ public final class WeakHashtable extends Hashtable {
|
|||||||
return super.remove(new Referenced(key));
|
return super.remove(new Referenced(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*@see Hashtable
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
purge();
|
|
||||||
return super.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*@see Hashtable
|
*@see Hashtable
|
||||||
*/
|
*/
|
||||||
@@ -320,182 +494,8 @@ public final class WeakHashtable extends Hashtable {
|
|||||||
*@see Hashtable
|
*@see Hashtable
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void rehash() {
|
public Collection values() {
|
||||||
// purge here to save the effort of rehashing dead entries
|
|
||||||
purge();
|
purge();
|
||||||
super.rehash();
|
return super.values();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Purges all entries whose wrapped keys
|
|
||||||
* have been garbage collected.
|
|
||||||
*/
|
|
||||||
private void purge() {
|
|
||||||
final List toRemove = new ArrayList();
|
|
||||||
synchronized (queue) {
|
|
||||||
WeakKey key;
|
|
||||||
while ((key = (WeakKey) queue.poll()) != null) {
|
|
||||||
toRemove.add(key.getReferenced());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LOGGING-119: do the actual removal of the keys outside the sync block
|
|
||||||
// to prevent deadlock scenarios as purge() may be called from
|
|
||||||
// non-synchronized methods too
|
|
||||||
final int size = toRemove.size();
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
super.remove(toRemove.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Purges one entry whose wrapped key
|
|
||||||
* has been garbage collected.
|
|
||||||
*/
|
|
||||||
private void purgeOne() {
|
|
||||||
synchronized (queue) {
|
|
||||||
final 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(final Object key, final Object value) {
|
|
||||||
this.key = key;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
boolean result = false;
|
|
||||||
if (o instanceof Map.Entry) {
|
|
||||||
final 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return (getKey()==null ? 0 : getKey().hashCode()) ^
|
|
||||||
(getValue()==null ? 0 : getValue().hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object setValue(final Object value) {
|
|
||||||
throw new UnsupportedOperationException("Entry.setValue is not supported.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Wrapper giving correct symantics for equals and hash code */
|
|
||||||
private final static class Referenced {
|
|
||||||
|
|
||||||
private final WeakReference reference;
|
|
||||||
private final int hashCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @throws NullPointerException if referant is {@code null}
|
|
||||||
*/
|
|
||||||
private Referenced(final 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}
|
|
||||||
*/
|
|
||||||
private Referenced(final Object key, final 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();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object getValue() {
|
|
||||||
return reference.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
boolean result = false;
|
|
||||||
if (o instanceof Referenced) {
|
|
||||||
final Referenced otherKey = (Referenced) o;
|
|
||||||
final Object thisKeyValue = getValue();
|
|
||||||
final Object otherKeyValue = otherKey.getValue();
|
|
||||||
if (thisKeyValue == null) {
|
|
||||||
result = otherKeyValue == null;
|
|
||||||
|
|
||||||
// Since our hash code was calculated from the original
|
|
||||||
// non-null referant, the above check breaks the
|
|
||||||
// hash code/equals contract, as two cleared Referenced
|
|
||||||
// objects could test equal but have different hash codes.
|
|
||||||
// We can reduce (not eliminate) the chance of this
|
|
||||||
// happening by comparing hash codes.
|
|
||||||
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} and also makes accessible
|
|
||||||
* the Referenced object holding it.
|
|
||||||
*/
|
|
||||||
private final static class WeakKey extends WeakReference {
|
|
||||||
|
|
||||||
private final Referenced referenced;
|
|
||||||
|
|
||||||
private WeakKey(final Object key,
|
|
||||||
final ReferenceQueue queue,
|
|
||||||
final Referenced referenced) {
|
|
||||||
super(key, queue);
|
|
||||||
this.referenced = referenced;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Referenced getReferenced() {
|
|
||||||
return referenced;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,21 +60,6 @@ public class AltHashtableTestCase extends TestCase {
|
|||||||
AltHashtable.class.getName());
|
AltHashtable.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that initialising the LogFactory class will cause it
|
|
||||||
* to instantiate an object of type specified in system property
|
|
||||||
* "org.apache.commons.logging.LogFactory.HashtableImpl".
|
|
||||||
*/
|
|
||||||
public void testType() {
|
|
||||||
// Here, the reference to the LogFactory class should cause the
|
|
||||||
// class to be loaded and initialized. It will see the property
|
|
||||||
// set and use the AltHashtable class. If other tests in this
|
|
||||||
// class have already been run within the same classloader then
|
|
||||||
// LogFactory will already have been initialized, but that
|
|
||||||
// doesn't change the effectiveness of this test.
|
|
||||||
assertTrue(LogFactory.factories instanceof AltHashtable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that when LogFactory sees a context-classloader for the
|
* Verify that when LogFactory sees a context-classloader for the
|
||||||
* first time that it creates a new entry in the LogFactory.factories
|
* first time that it creates a new entry in the LogFactory.factories
|
||||||
@@ -91,4 +76,19 @@ public class AltHashtableTestCase extends TestCase {
|
|||||||
assertEquals(contextLoader, AltHashtable.lastKey);
|
assertEquals(contextLoader, AltHashtable.lastKey);
|
||||||
assertNotNull(AltHashtable.lastValue);
|
assertNotNull(AltHashtable.lastValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that initialising the LogFactory class will cause it
|
||||||
|
* to instantiate an object of type specified in system property
|
||||||
|
* "org.apache.commons.logging.LogFactory.HashtableImpl".
|
||||||
|
*/
|
||||||
|
public void testType() {
|
||||||
|
// Here, the reference to the LogFactory class should cause the
|
||||||
|
// class to be loaded and initialized. It will see the property
|
||||||
|
// set and use the AltHashtable class. If other tests in this
|
||||||
|
// class have already been run within the same classloader then
|
||||||
|
// LogFactory will already have been initialized, but that
|
||||||
|
// doesn't change the effectiveness of this test.
|
||||||
|
assertTrue(LogFactory.factories instanceof AltHashtable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ import java.util.Hashtable;
|
|||||||
*/
|
*/
|
||||||
public class BadHashtablePropertyTestCase extends TestCase {
|
public class BadHashtablePropertyTestCase extends TestCase {
|
||||||
|
|
||||||
public void testType() {
|
|
||||||
assertTrue(LogFactory.factories instanceof Hashtable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testPutCalled() throws Exception {
|
public void testPutCalled() throws Exception {
|
||||||
LogFactory.getLog(BadHashtablePropertyTestCase.class);
|
LogFactory.getLog(BadHashtablePropertyTestCase.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testType() {
|
||||||
|
assertTrue(LogFactory.factories instanceof Hashtable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,18 +27,6 @@ import junit.framework.TestCase;
|
|||||||
*/
|
*/
|
||||||
public class BasicOperationsTestCase extends TestCase
|
public class BasicOperationsTestCase extends TestCase
|
||||||
{
|
{
|
||||||
public void testIsEnabledClassLog()
|
|
||||||
{
|
|
||||||
final Log log = LogFactory.getLog(BasicOperationsTestCase.class);
|
|
||||||
executeIsEnabledTest(log);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testIsEnabledNamedLog()
|
|
||||||
{
|
|
||||||
final Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
|
|
||||||
executeIsEnabledTest(log);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void executeIsEnabledTest(final Log log)
|
public void executeIsEnabledTest(final Log log)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -57,16 +45,22 @@ public class BasicOperationsTestCase extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMessageWithoutExceptionClassLog()
|
public void executeMessageWithExceptionTest(final Log log)
|
||||||
{
|
{
|
||||||
final Log log = LogFactory.getLog(BasicOperationsTestCase.class);
|
try
|
||||||
executeMessageWithoutExceptionTest(log);
|
{
|
||||||
|
log.trace("Hello, Mum", new ArithmeticException());
|
||||||
|
log.debug("Hello, Mum", new ArithmeticException());
|
||||||
|
log.info("Hello, Mum", new ArithmeticException());
|
||||||
|
log.warn("Hello, Mum", new ArithmeticException());
|
||||||
|
log.error("Hello, Mum", new ArithmeticException());
|
||||||
|
log.fatal("Hello, Mum", new ArithmeticException());
|
||||||
}
|
}
|
||||||
|
catch (final Throwable t)
|
||||||
public void testMessageWithoutExceptionNamedLog()
|
|
||||||
{
|
{
|
||||||
final Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
|
t.printStackTrace();
|
||||||
executeMessageWithoutExceptionTest(log);
|
fail("Exception thrown: " + t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeMessageWithoutExceptionTest(final Log log)
|
public void executeMessageWithoutExceptionTest(final Log log)
|
||||||
@@ -87,6 +81,18 @@ public class BasicOperationsTestCase extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIsEnabledClassLog()
|
||||||
|
{
|
||||||
|
final Log log = LogFactory.getLog(BasicOperationsTestCase.class);
|
||||||
|
executeIsEnabledTest(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIsEnabledNamedLog()
|
||||||
|
{
|
||||||
|
final Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
|
||||||
|
executeIsEnabledTest(log);
|
||||||
|
}
|
||||||
|
|
||||||
public void testMessageWithExceptionClassLog()
|
public void testMessageWithExceptionClassLog()
|
||||||
{
|
{
|
||||||
final Log log = LogFactory.getLog(BasicOperationsTestCase.class);
|
final Log log = LogFactory.getLog(BasicOperationsTestCase.class);
|
||||||
@@ -99,21 +105,15 @@ public class BasicOperationsTestCase extends TestCase
|
|||||||
executeMessageWithExceptionTest(log);
|
executeMessageWithExceptionTest(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeMessageWithExceptionTest(final Log log)
|
public void testMessageWithoutExceptionClassLog()
|
||||||
{
|
{
|
||||||
try
|
final Log log = LogFactory.getLog(BasicOperationsTestCase.class);
|
||||||
|
executeMessageWithoutExceptionTest(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMessageWithoutExceptionNamedLog()
|
||||||
{
|
{
|
||||||
log.trace("Hello, Mum", new ArithmeticException());
|
final Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
|
||||||
log.debug("Hello, Mum", new ArithmeticException());
|
executeMessageWithoutExceptionTest(log);
|
||||||
log.info("Hello, Mum", new ArithmeticException());
|
|
||||||
log.warn("Hello, Mum", new ArithmeticException());
|
|
||||||
log.error("Hello, Mum", new ArithmeticException());
|
|
||||||
log.fatal("Hello, Mum", new ArithmeticException());
|
|
||||||
}
|
|
||||||
catch (final Throwable t)
|
|
||||||
{
|
|
||||||
t.printStackTrace();
|
|
||||||
fail("Exception thrown: " + t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,23 +27,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
// after: https://github.com/apache/logging-log4j2/blob/c47e98423b461731f7791fcb9ea1079cd451f365/log4j-core/src/test/java/org/apache/logging/log4j/core/GarbageCollectionHelper.java
|
// after: https://github.com/apache/logging-log4j2/blob/c47e98423b461731f7791fcb9ea1079cd451f365/log4j-core/src/test/java/org/apache/logging/log4j/core/GarbageCollectionHelper.java
|
||||||
public final class GarbageCollectionHelper implements Closeable, Runnable {
|
public final class GarbageCollectionHelper implements Closeable, Runnable {
|
||||||
private static final OutputStream SINK = new OutputStream() {
|
|
||||||
@Override
|
|
||||||
public void write(int b) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(byte[] b) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(byte[] b, int off, int len) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private final AtomicBoolean running = new AtomicBoolean();
|
|
||||||
private final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
private final Thread gcThread = new Thread(new GcTask());
|
|
||||||
|
|
||||||
class GcTask implements Runnable {
|
class GcTask implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -64,13 +47,23 @@ public final class GarbageCollectionHelper implements Closeable, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static final OutputStream SINK = new OutputStream() {
|
||||||
|
@Override
|
||||||
|
public void write(byte[] b) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void write(byte[] b, int off, int len) {
|
||||||
if (running.compareAndSet(false, true)) {
|
|
||||||
gcThread.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) {
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
private final AtomicBoolean running = new AtomicBoolean();
|
||||||
|
private final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
private final Thread gcThread = new Thread(new GcTask());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
@@ -82,5 +75,12 @@ public final class GarbageCollectionHelper implements Closeable, Runnable {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (running.compareAndSet(false, true)) {
|
||||||
|
gcThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ import junit.framework.TestCase;
|
|||||||
* test to emulate container and application isolated from container
|
* test to emulate container and application isolated from container
|
||||||
*/
|
*/
|
||||||
public class LoadTestCase extends TestCase{
|
public class LoadTestCase extends TestCase{
|
||||||
//TODO: need some way to add service provider packages
|
|
||||||
static private String[] LOG_PCKG = {"org.apache.commons.logging",
|
|
||||||
"org.apache.commons.logging.impl"};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom classloader which "duplicates" logging classes available
|
* A custom classloader which "duplicates" logging classes available
|
||||||
* in the parent classloader into itself.
|
* in the parent classloader into itself.
|
||||||
@@ -92,6 +88,41 @@ public class LoadTestCase extends TestCase{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: need some way to add service provider packages
|
||||||
|
static private String[] LOG_PCKG = {"org.apache.commons.logging",
|
||||||
|
"org.apache.commons.logging.impl"};
|
||||||
|
|
||||||
|
|
||||||
|
private ClassLoader origContextClassLoader;
|
||||||
|
|
||||||
|
private void execute(final Class cls) throws Exception {
|
||||||
|
cls.getConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load class UserClass via a temporary classloader which is a child of
|
||||||
|
* the classloader used to load this test class.
|
||||||
|
*/
|
||||||
|
private Class reload() throws Exception {
|
||||||
|
Class testObjCls = null;
|
||||||
|
final AppClassLoader appLoader = new AppClassLoader(this.getClass().getClassLoader());
|
||||||
|
try {
|
||||||
|
|
||||||
|
testObjCls = appLoader.loadClass(UserClass.class.getName());
|
||||||
|
|
||||||
|
} catch (final ClassNotFoundException cnfe) {
|
||||||
|
throw cnfe;
|
||||||
|
} catch (final Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
fail("AppClassLoader failed ");
|
||||||
|
}
|
||||||
|
|
||||||
|
assertSame("app isolated", testObjCls.getClassLoader(), appLoader);
|
||||||
|
|
||||||
|
return testObjCls;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call the static setAllowFlawedContext method on the specified class
|
* Call the static setAllowFlawedContext method on the specified class
|
||||||
@@ -104,6 +135,18 @@ public class LoadTestCase extends TestCase{
|
|||||||
m.invoke(null, state);
|
m.invoke(null, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() {
|
||||||
|
// save state before test starts so we can restore it when test ends
|
||||||
|
origContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tearDown() {
|
||||||
|
// restore original state so a test can't stuff up later tests.
|
||||||
|
Thread.currentThread().setContextClassLoader(origContextClassLoader);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test what happens when we play various classloader tricks like those
|
* Test what happens when we play various classloader tricks like those
|
||||||
* that happen in web and j2ee containers.
|
* that happen in web and j2ee containers.
|
||||||
@@ -170,47 +213,4 @@ public class LoadTestCase extends TestCase{
|
|||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load class UserClass via a temporary classloader which is a child of
|
|
||||||
* the classloader used to load this test class.
|
|
||||||
*/
|
|
||||||
private Class reload() throws Exception {
|
|
||||||
Class testObjCls = null;
|
|
||||||
final AppClassLoader appLoader = new AppClassLoader(this.getClass().getClassLoader());
|
|
||||||
try {
|
|
||||||
|
|
||||||
testObjCls = appLoader.loadClass(UserClass.class.getName());
|
|
||||||
|
|
||||||
} catch (final ClassNotFoundException cnfe) {
|
|
||||||
throw cnfe;
|
|
||||||
} catch (final Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
fail("AppClassLoader failed ");
|
|
||||||
}
|
|
||||||
|
|
||||||
assertSame("app isolated", testObjCls.getClassLoader(), appLoader);
|
|
||||||
|
|
||||||
return testObjCls;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void execute(final Class cls) throws Exception {
|
|
||||||
cls.getConstructor().newInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() {
|
|
||||||
// save state before test starts so we can restore it when test ends
|
|
||||||
origContextClassLoader = Thread.currentThread().getContextClassLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tearDown() {
|
|
||||||
// restore original state so a test can't stuff up later tests.
|
|
||||||
Thread.currentThread().setContextClassLoader(origContextClassLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader origContextClassLoader;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,94 +96,6 @@ public class PathableClassLoader extends URLClassLoader {
|
|||||||
super(NO_URLS, parent);
|
super(NO_URLS, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow caller to explicitly add paths. Generally this not a good idea;
|
|
||||||
* use addLogicalLib instead, then define the location for that logical
|
|
||||||
* library in the build.xml file.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void addURL(final URL url) {
|
|
||||||
super.addURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify whether this classloader should ask the parent classloader
|
|
||||||
* to resolve a class first, before trying to resolve it via its own
|
|
||||||
* classpath.
|
|
||||||
* <p>
|
|
||||||
* Checking with the parent first is the normal approach for java, but
|
|
||||||
* components within containers such as servlet engines can use
|
|
||||||
* child-first lookup instead, to allow the components to override libs
|
|
||||||
* which are visible in shared classloaders provided by the container.
|
|
||||||
* <p>
|
|
||||||
* Note that the method getResources always behaves as if parentFirst=true,
|
|
||||||
* because of limitations in java 1.4; see the javadoc for method
|
|
||||||
* getResourcesInOrder for details.
|
|
||||||
* <p>
|
|
||||||
* This value defaults to true.
|
|
||||||
*/
|
|
||||||
public void setParentFirst(final boolean state) {
|
|
||||||
parentFirst = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For classes with the specified prefix, get them from the system
|
|
||||||
* classpath <i>which is active at the point this method is called</i>.
|
|
||||||
* <p>
|
|
||||||
* This method is just a shortcut for
|
|
||||||
* <pre>
|
|
||||||
* useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
* Of course, this assumes that the classes of interest are already
|
|
||||||
* in the classpath of the system classloader.
|
|
||||||
*/
|
|
||||||
public void useSystemLoader(final String prefix) {
|
|
||||||
useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify a classloader to use for specific java packages.
|
|
||||||
* <p>
|
|
||||||
* The specified classloader is normally a loader that is NOT
|
|
||||||
* an ancestor of this classloader. In particular, this loader
|
|
||||||
* may have the bootloader as its parent, but be configured to
|
|
||||||
* see specific other classes (eg the junit library loaded
|
|
||||||
* via the system classloader).
|
|
||||||
* <p>
|
|
||||||
* The differences between using this method, and using
|
|
||||||
* addLogicalLib are:
|
|
||||||
* <ul>
|
|
||||||
* <li>If code calls getClassLoader on a class loaded via
|
|
||||||
* "lookaside", then traces up its inheritance chain, it
|
|
||||||
* will see the "real" classloaders. When the class is remapped
|
|
||||||
* into this classloader via addLogicalLib, the classloader
|
|
||||||
* chain seen is this object plus ancestors.
|
|
||||||
* <li>If two different jars contain classes in the same
|
|
||||||
* package, then it is not possible to load both jars into
|
|
||||||
* the same "lookaside" classloader (eg the system classloader)
|
|
||||||
* then map one of those subsets from here. Of course they could
|
|
||||||
* be loaded into two different "lookaside" classloaders and
|
|
||||||
* then a prefix used to map from here to one of those classloaders.
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public void useExplicitLoader(final String prefix, final ClassLoader loader) {
|
|
||||||
if (lookasides == null) {
|
|
||||||
lookasides = new HashMap();
|
|
||||||
}
|
|
||||||
lookasides.put(prefix, loader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify a collection of logical libraries. See addLogicalLib.
|
|
||||||
*/
|
|
||||||
public void addLogicalLib(final String[] logicalLibs) {
|
|
||||||
for (final String logicalLib : logicalLibs) {
|
|
||||||
addLogicalLib(logicalLib);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify a logical library to be included in the classpath used to
|
* Specify a logical library to be included in the classpath used to
|
||||||
* locate classes.
|
* locate classes.
|
||||||
@@ -231,6 +143,101 @@ public class PathableClassLoader extends URLClassLoader {
|
|||||||
+ " as a System property.");
|
+ " as a System property.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a collection of logical libraries. See addLogicalLib.
|
||||||
|
*/
|
||||||
|
public void addLogicalLib(final String[] logicalLibs) {
|
||||||
|
for (final String logicalLib : logicalLibs) {
|
||||||
|
addLogicalLib(logicalLib);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow caller to explicitly add paths. Generally this not a good idea;
|
||||||
|
* use addLogicalLib instead, then define the location for that logical
|
||||||
|
* library in the build.xml file.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addURL(final URL url) {
|
||||||
|
super.addURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as parent class method except that when parentFirst is false
|
||||||
|
* the resource is looked for in the local classpath before the parent
|
||||||
|
* loader is consulted.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getResource(final String name) {
|
||||||
|
if (parentFirst) {
|
||||||
|
return super.getResource(name);
|
||||||
|
}
|
||||||
|
final URL local = super.findResource(name);
|
||||||
|
if (local != null) {
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
return super.getResource(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as parent class method except that when parentFirst is false
|
||||||
|
* the resource is looked for in the local classpath before the parent
|
||||||
|
* loader is consulted.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public InputStream getResourceAsStream(final String name) {
|
||||||
|
if (parentFirst) {
|
||||||
|
return super.getResourceAsStream(name);
|
||||||
|
}
|
||||||
|
final URL local = super.findResource(name);
|
||||||
|
if (local != null) {
|
||||||
|
try {
|
||||||
|
return local.openStream();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
// TODO: check if this is right or whether we should
|
||||||
|
// fall back to trying parent. The javadoc doesn't say...
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.getResourceAsStream(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emulate a proper implementation of getResources which respects the
|
||||||
|
* setting for parentFirst.
|
||||||
|
* <p>
|
||||||
|
* Note that it's not possible to override the inherited getResources, as
|
||||||
|
* it's declared final in java1.4 (thought that's been removed for 1.5).
|
||||||
|
* The inherited implementation always behaves as if parentFirst=true.
|
||||||
|
*/
|
||||||
|
public Enumeration getResourcesInOrder(final String name) throws IOException {
|
||||||
|
if (parentFirst) {
|
||||||
|
return super.getResources(name);
|
||||||
|
}
|
||||||
|
final Enumeration localUrls = super.findResources(name);
|
||||||
|
|
||||||
|
final ClassLoader parent = getParent();
|
||||||
|
if (parent == null) {
|
||||||
|
// Alas, there is no method to get matching resources
|
||||||
|
// from a null (BOOT) parent classloader. Calling
|
||||||
|
// ClassLoader.getSystemClassLoader isn't right. Maybe
|
||||||
|
// calling Class.class.getResources(name) would do?
|
||||||
|
//
|
||||||
|
// However for the purposes of unit tests, we can
|
||||||
|
// simply assume that no relevant resources are
|
||||||
|
// loadable from the parent; unit tests will never be
|
||||||
|
// putting any of their resources in a "boot" classloader
|
||||||
|
// path!
|
||||||
|
return localUrls;
|
||||||
|
}
|
||||||
|
final Enumeration parentUrls = parent.getResources(name);
|
||||||
|
|
||||||
|
final ArrayList localItems = toList(localUrls);
|
||||||
|
final ArrayList parentItems = toList(parentUrls);
|
||||||
|
localItems.addAll(parentItems);
|
||||||
|
return Collections.enumeration(localItems);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the classloader that loaded this class has this logical lib in its
|
* If the classloader that loaded this class has this logical lib in its
|
||||||
* path, then return the matching URL otherwise return null.
|
* path, then return the matching URL otherwise return null.
|
||||||
@@ -328,56 +335,23 @@ public class PathableClassLoader extends URLClassLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as parent class method except that when parentFirst is false
|
* Specify whether this classloader should ask the parent classloader
|
||||||
* the resource is looked for in the local classpath before the parent
|
* to resolve a class first, before trying to resolve it via its own
|
||||||
* loader is consulted.
|
* classpath.
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public URL getResource(final String name) {
|
|
||||||
if (parentFirst) {
|
|
||||||
return super.getResource(name);
|
|
||||||
}
|
|
||||||
final URL local = super.findResource(name);
|
|
||||||
if (local != null) {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
return super.getResource(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emulate a proper implementation of getResources which respects the
|
|
||||||
* setting for parentFirst.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Note that it's not possible to override the inherited getResources, as
|
* Checking with the parent first is the normal approach for java, but
|
||||||
* it's declared final in java1.4 (thought that's been removed for 1.5).
|
* components within containers such as servlet engines can use
|
||||||
* The inherited implementation always behaves as if parentFirst=true.
|
* child-first lookup instead, to allow the components to override libs
|
||||||
|
* which are visible in shared classloaders provided by the container.
|
||||||
|
* <p>
|
||||||
|
* Note that the method getResources always behaves as if parentFirst=true,
|
||||||
|
* because of limitations in java 1.4; see the javadoc for method
|
||||||
|
* getResourcesInOrder for details.
|
||||||
|
* <p>
|
||||||
|
* This value defaults to true.
|
||||||
*/
|
*/
|
||||||
public Enumeration getResourcesInOrder(final String name) throws IOException {
|
public void setParentFirst(final boolean state) {
|
||||||
if (parentFirst) {
|
parentFirst = state;
|
||||||
return super.getResources(name);
|
|
||||||
}
|
|
||||||
final Enumeration localUrls = super.findResources(name);
|
|
||||||
|
|
||||||
final ClassLoader parent = getParent();
|
|
||||||
if (parent == null) {
|
|
||||||
// Alas, there is no method to get matching resources
|
|
||||||
// from a null (BOOT) parent classloader. Calling
|
|
||||||
// ClassLoader.getSystemClassLoader isn't right. Maybe
|
|
||||||
// calling Class.class.getResources(name) would do?
|
|
||||||
//
|
|
||||||
// However for the purposes of unit tests, we can
|
|
||||||
// simply assume that no relevant resources are
|
|
||||||
// loadable from the parent; unit tests will never be
|
|
||||||
// putting any of their resources in a "boot" classloader
|
|
||||||
// path!
|
|
||||||
return localUrls;
|
|
||||||
}
|
|
||||||
final Enumeration parentUrls = parent.getResources(name);
|
|
||||||
|
|
||||||
final ArrayList localItems = toList(localUrls);
|
|
||||||
final ArrayList parentItems = toList(parentUrls);
|
|
||||||
localItems.addAll(parentItems);
|
|
||||||
return Collections.enumeration(localItems);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -400,25 +374,51 @@ public class PathableClassLoader extends URLClassLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as parent class method except that when parentFirst is false
|
* Specify a classloader to use for specific java packages.
|
||||||
* the resource is looked for in the local classpath before the parent
|
* <p>
|
||||||
* loader is consulted.
|
* The specified classloader is normally a loader that is NOT
|
||||||
|
* an ancestor of this classloader. In particular, this loader
|
||||||
|
* may have the bootloader as its parent, but be configured to
|
||||||
|
* see specific other classes (eg the junit library loaded
|
||||||
|
* via the system classloader).
|
||||||
|
* <p>
|
||||||
|
* The differences between using this method, and using
|
||||||
|
* addLogicalLib are:
|
||||||
|
* <ul>
|
||||||
|
* <li>If code calls getClassLoader on a class loaded via
|
||||||
|
* "lookaside", then traces up its inheritance chain, it
|
||||||
|
* will see the "real" classloaders. When the class is remapped
|
||||||
|
* into this classloader via addLogicalLib, the classloader
|
||||||
|
* chain seen is this object plus ancestors.
|
||||||
|
* <li>If two different jars contain classes in the same
|
||||||
|
* package, then it is not possible to load both jars into
|
||||||
|
* the same "lookaside" classloader (eg the system classloader)
|
||||||
|
* then map one of those subsets from here. Of course they could
|
||||||
|
* be loaded into two different "lookaside" classloaders and
|
||||||
|
* then a prefix used to map from here to one of those classloaders.
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@Override
|
public void useExplicitLoader(final String prefix, final ClassLoader loader) {
|
||||||
public InputStream getResourceAsStream(final String name) {
|
if (lookasides == null) {
|
||||||
if (parentFirst) {
|
lookasides = new HashMap();
|
||||||
return super.getResourceAsStream(name);
|
|
||||||
}
|
}
|
||||||
final URL local = super.findResource(name);
|
lookasides.put(prefix, loader);
|
||||||
if (local != null) {
|
}
|
||||||
try {
|
|
||||||
return local.openStream();
|
/**
|
||||||
} catch (final IOException e) {
|
* For classes with the specified prefix, get them from the system
|
||||||
// TODO: check if this is right or whether we should
|
* classpath <i>which is active at the point this method is called</i>.
|
||||||
// fall back to trying parent. The javadoc doesn't say...
|
* <p>
|
||||||
return null;
|
* This method is just a shortcut for
|
||||||
}
|
* <pre>
|
||||||
}
|
* useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
|
||||||
return super.getResourceAsStream(name);
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* Of course, this assumes that the classes of interest are already
|
||||||
|
* in the classpath of the system classloader.
|
||||||
|
*/
|
||||||
|
public void useSystemLoader(final String prefix) {
|
||||||
|
useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,22 +31,39 @@ import junit.framework.TestCase;
|
|||||||
|
|
||||||
public class WeakHashtableTestCase extends TestCase {
|
public class WeakHashtableTestCase extends TestCase {
|
||||||
|
|
||||||
|
public static class StupidThread extends Thread {
|
||||||
|
|
||||||
|
public StupidThread(final String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (int i = 0; i < RUN_LOOPS; i++) {
|
||||||
|
hashtable.put("key" + ":" + i % 10, Boolean.TRUE);
|
||||||
|
if (i % 50 == 0) {
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private static final int WAIT_FOR_THREAD_COMPLETION = 5000; // 5 seconds
|
private static final int WAIT_FOR_THREAD_COMPLETION = 5000; // 5 seconds
|
||||||
private static final int RUN_LOOPS = 3000;
|
private static final int RUN_LOOPS = 3000;
|
||||||
private static final int OUTER_LOOP = 400;
|
private static final int OUTER_LOOP = 400;
|
||||||
|
|
||||||
private static final int THREAD_COUNT = 10;
|
private static final int THREAD_COUNT = 10;
|
||||||
|
|
||||||
private static WeakHashtable hashtable;
|
private static WeakHashtable hashtable;
|
||||||
|
|
||||||
/** Maximum number of iterations before our test fails */
|
/** Maximum number of iterations before our test fails */
|
||||||
private static final int MAX_GC_ITERATIONS = 50;
|
private static final int MAX_GC_ITERATIONS = 50;
|
||||||
|
|
||||||
private WeakHashtable weakHashtable;
|
private WeakHashtable weakHashtable;
|
||||||
private Long keyOne;
|
private Long keyOne;
|
||||||
private Long keyTwo;
|
private Long keyTwo;
|
||||||
private Long keyThree;
|
private Long keyThree;
|
||||||
private Long valueOne;
|
private Long valueOne;
|
||||||
private Long valueTwo;
|
private Long valueTwo;
|
||||||
|
|
||||||
private Long valueThree;
|
private Long valueThree;
|
||||||
|
|
||||||
public WeakHashtableTestCase(final String testName) {
|
public WeakHashtableTestCase(final String testName) {
|
||||||
@@ -162,6 +179,33 @@ public class WeakHashtableTestCase extends TestCase {
|
|||||||
assertTrue(keySet.contains(keyThree));
|
assertTrue(keySet.contains(keyThree));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testLOGGING_119() throws Exception {
|
||||||
|
final Thread [] t = new Thread[THREAD_COUNT];
|
||||||
|
for (int j=1; j <= OUTER_LOOP; j++) {
|
||||||
|
hashtable = new WeakHashtable();
|
||||||
|
for (int i = 0; i < t.length; i++) {
|
||||||
|
t[i] = new StupidThread("Thread:" + i);
|
||||||
|
t[i].setDaemon(true); // Otherwise we cannot exit
|
||||||
|
t[i].start();
|
||||||
|
}
|
||||||
|
for (final Thread element : t) {
|
||||||
|
element.join(WAIT_FOR_THREAD_COMPLETION);
|
||||||
|
if (element.isAlive()) {
|
||||||
|
break; // at least one thread is stuck
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int active=0;
|
||||||
|
for (final Thread element : t) {
|
||||||
|
if (element.isAlive()) {
|
||||||
|
active++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (active > 0) {
|
||||||
|
fail("Attempt: " + j + " Stuck threads: " + active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Tests public Object put(Object key, Object value) */
|
/** Tests public Object put(Object key, Object value) */
|
||||||
public void testPut() throws Exception {
|
public void testPut() throws Exception {
|
||||||
final Long anotherKey = new Long(2004);
|
final Long anotherKey = new Long(2004);
|
||||||
@@ -266,48 +310,4 @@ public class WeakHashtableTestCase extends TestCase {
|
|||||||
// Test that the released objects are not taking space in the table
|
// Test that the released objects are not taking space in the table
|
||||||
assertEquals("underlying table not emptied", 0, weakHashtable.size());
|
assertEquals("underlying table not emptied", 0, weakHashtable.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StupidThread extends Thread {
|
|
||||||
|
|
||||||
public StupidThread(final String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (int i = 0; i < RUN_LOOPS; i++) {
|
|
||||||
hashtable.put("key" + ":" + i % 10, Boolean.TRUE);
|
|
||||||
if (i % 50 == 0) {
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testLOGGING_119() throws Exception {
|
|
||||||
final Thread [] t = new Thread[THREAD_COUNT];
|
|
||||||
for (int j=1; j <= OUTER_LOOP; j++) {
|
|
||||||
hashtable = new WeakHashtable();
|
|
||||||
for (int i = 0; i < t.length; i++) {
|
|
||||||
t[i] = new StupidThread("Thread:" + i);
|
|
||||||
t[i].setDaemon(true); // Otherwise we cannot exit
|
|
||||||
t[i].start();
|
|
||||||
}
|
|
||||||
for (final Thread element : t) {
|
|
||||||
element.join(WAIT_FOR_THREAD_COMPLETION);
|
|
||||||
if (element.isAlive()) {
|
|
||||||
break; // at least one thread is stuck
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int active=0;
|
|
||||||
for (final Thread element : t) {
|
|
||||||
if (element.isAlive()) {
|
|
||||||
active++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (active > 0) {
|
|
||||||
fail("Attempt: " + j + " Stuck threads: " + active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,6 @@ import org.apache.commons.logging.PathableTestSuite;
|
|||||||
|
|
||||||
public class CustomConfigAPITestCase extends CustomConfigTestCase {
|
public class CustomConfigAPITestCase extends CustomConfigTestCase {
|
||||||
|
|
||||||
public CustomConfigAPITestCase(final String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
*/
|
*/
|
||||||
@@ -58,4 +54,8 @@ public class CustomConfigAPITestCase extends CustomConfigTestCase {
|
|||||||
final Class testClass = child.loadClass(CustomConfigAPITestCase.class.getName());
|
final Class testClass = child.loadClass(CustomConfigAPITestCase.class.getName());
|
||||||
return new PathableTestSuite(testClass, child);
|
return new PathableTestSuite(testClass, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CustomConfigAPITestCase(final String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,6 @@ import org.apache.commons.logging.PathableClassLoader;
|
|||||||
public class CustomConfigFullTestCase extends CustomConfigTestCase {
|
public class CustomConfigFullTestCase extends CustomConfigTestCase {
|
||||||
|
|
||||||
|
|
||||||
public CustomConfigFullTestCase(final String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
*/
|
*/
|
||||||
@@ -60,4 +55,9 @@ public class CustomConfigFullTestCase extends CustomConfigTestCase {
|
|||||||
final Class testClass = child.loadClass(CustomConfigFullTestCase.class.getName());
|
final Class testClass = child.loadClass(CustomConfigFullTestCase.class.getName());
|
||||||
return new PathableTestSuite(testClass, child);
|
return new PathableTestSuite(testClass, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public CustomConfigFullTestCase(final String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,82 +48,6 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
// ----------------------------------------------------------- Constructors
|
// ----------------------------------------------------------- Constructors
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Construct a new instance of this test case.</p>
|
|
||||||
*
|
|
||||||
* @param name Name of the test case
|
|
||||||
*/
|
|
||||||
public CustomConfigTestCase(final String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- Instance Variables
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The customized {@code Handler} we will be using.</p>
|
|
||||||
*/
|
|
||||||
protected TestHandler handler;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The underlying {@code Handler}s we will be using.</p>
|
|
||||||
*/
|
|
||||||
protected Handler handlers[];
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The underlying {@code Logger} we will be using.</p>
|
|
||||||
*/
|
|
||||||
protected Logger logger;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The underlying {@code LogManager} we will be using.</p>
|
|
||||||
*/
|
|
||||||
protected LogManager manager;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The message levels that should have been logged.</p>
|
|
||||||
*/
|
|
||||||
protected Level[] testLevels =
|
|
||||||
{ Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The message strings that should have been logged.</p>
|
|
||||||
*/
|
|
||||||
protected String[] testMessages =
|
|
||||||
{ "debug", "info", "warn", "error", "fatal" };
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------- JUnit Infrastructure Methods
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the name of a class that is somewhere in the classpath of the provided
|
|
||||||
* classloader, return the contents of the corresponding .class file.
|
|
||||||
*/
|
|
||||||
protected static byte[] readClass(final String name, final ClassLoader srcCL) throws Exception {
|
|
||||||
final String resName = name.replace('.', '/') + ".class";
|
|
||||||
System.err.println("Trying to load resource [" + resName + "]");
|
|
||||||
final InputStream is = srcCL.getResourceAsStream(resName);
|
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
System.err.println("Reading resource [" + resName + "]");
|
|
||||||
final byte[] buf = new byte[1000];
|
|
||||||
for(;;) {
|
|
||||||
final int read = is.read(buf);
|
|
||||||
if (read <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
baos.write(buf, 0, read);
|
|
||||||
}
|
|
||||||
is.close();
|
|
||||||
return baos.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a class available in the system classloader even when its classfile is
|
* Make a class available in the system classloader even when its classfile is
|
||||||
* not present in the classpath configured for that classloader. This only
|
* not present in the classpath configured for that classloader. This only
|
||||||
@@ -159,17 +83,30 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Instance Variables
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up instance variables required by this test case.
|
* Given the name of a class that is somewhere in the classpath of the provided
|
||||||
|
* classloader, return the contents of the corresponding .class file.
|
||||||
*/
|
*/
|
||||||
@Override
|
protected static byte[] readClass(final String name, final ClassLoader srcCL) throws Exception {
|
||||||
public void setUp() throws Exception {
|
final String resName = name.replace('.', '/') + ".class";
|
||||||
setUpManager
|
System.err.println("Trying to load resource [" + resName + "]");
|
||||||
("org/apache/commons/logging/jdk14/CustomConfig.properties");
|
final InputStream is = srcCL.getResourceAsStream(resName);
|
||||||
setUpLogger(this.getClass().getName());
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
setUpHandlers();
|
System.err.println("Reading resource [" + resName + "]");
|
||||||
setUpFactory();
|
final byte[] buf = new byte[1000];
|
||||||
setUpLog(this.getClass().getName());
|
for(;;) {
|
||||||
|
final int read = is.read(buf);
|
||||||
|
if (read <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
baos.write(buf, 0, read);
|
||||||
|
}
|
||||||
|
is.close();
|
||||||
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -195,6 +132,198 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
return new PathableTestSuite(testClass, cl);
|
return new PathableTestSuite(testClass, cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The customized {@code Handler} we will be using.</p>
|
||||||
|
*/
|
||||||
|
protected TestHandler handler;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The underlying {@code Handler}s we will be using.</p>
|
||||||
|
*/
|
||||||
|
protected Handler handlers[];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The underlying {@code Logger} we will be using.</p>
|
||||||
|
*/
|
||||||
|
protected Logger logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The underlying {@code LogManager} we will be using.</p>
|
||||||
|
*/
|
||||||
|
protected LogManager manager;
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------- JUnit Infrastructure Methods
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The message levels that should have been logged.</p>
|
||||||
|
*/
|
||||||
|
protected Level[] testLevels =
|
||||||
|
{ Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The message strings that should have been logged.</p>
|
||||||
|
*/
|
||||||
|
protected String[] testMessages =
|
||||||
|
{ "debug", "info", "warn", "error", "fatal" };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Construct a new instance of this test case.</p>
|
||||||
|
*
|
||||||
|
* @param name Name of the test case
|
||||||
|
*/
|
||||||
|
public CustomConfigTestCase(final String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check the log instance
|
||||||
|
@Override
|
||||||
|
protected void checkLog() {
|
||||||
|
|
||||||
|
assertNotNull("Log exists", log);
|
||||||
|
assertEquals("Log class",
|
||||||
|
"org.apache.commons.logging.impl.Jdk14Logger",
|
||||||
|
log.getClass().getName());
|
||||||
|
|
||||||
|
// Assert which logging levels have been enabled
|
||||||
|
assertTrue(log.isFatalEnabled());
|
||||||
|
assertTrue(log.isErrorEnabled());
|
||||||
|
assertTrue(log.isWarnEnabled());
|
||||||
|
assertTrue(log.isInfoEnabled());
|
||||||
|
assertTrue(log.isDebugEnabled());
|
||||||
|
assertFalse(log.isTraceEnabled());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the recorded messages
|
||||||
|
protected void checkLogRecords(final boolean thrown) {
|
||||||
|
final Iterator records = handler.records();
|
||||||
|
for (int i = 0; i < testMessages.length; i++) {
|
||||||
|
assertTrue(records.hasNext());
|
||||||
|
final LogRecord record = (LogRecord) records.next();
|
||||||
|
assertEquals("LogRecord level",
|
||||||
|
testLevels[i], record.getLevel());
|
||||||
|
assertEquals("LogRecord message",
|
||||||
|
testMessages[i], record.getMessage());
|
||||||
|
assertTrue("LogRecord class",
|
||||||
|
record.getSourceClassName().startsWith(
|
||||||
|
"org.apache.commons.logging.jdk14.CustomConfig"));
|
||||||
|
if (thrown) {
|
||||||
|
assertEquals("LogRecord method",
|
||||||
|
"logExceptionMessages",
|
||||||
|
record.getSourceMethodName());
|
||||||
|
} else {
|
||||||
|
assertEquals("LogRecord method",
|
||||||
|
"logPlainMessages",
|
||||||
|
record.getSourceMethodName());
|
||||||
|
}
|
||||||
|
if (thrown) {
|
||||||
|
assertNotNull("LogRecord thrown", record.getThrown());
|
||||||
|
assertTrue("LogRecord thrown type",
|
||||||
|
record.getThrown() instanceof DummyException);
|
||||||
|
} else {
|
||||||
|
assertNull("LogRecord thrown",
|
||||||
|
record.getThrown());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertFalse(records.hasNext());
|
||||||
|
handler.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------- Test Methods
|
||||||
|
|
||||||
|
|
||||||
|
// Log the messages with exceptions
|
||||||
|
protected void logExceptionMessages() {
|
||||||
|
final Throwable t = new DummyException();
|
||||||
|
log.trace("trace", t); // Should not actually get logged
|
||||||
|
log.debug("debug", t);
|
||||||
|
log.info("info", t);
|
||||||
|
log.warn("warn", t);
|
||||||
|
log.error("error", t);
|
||||||
|
log.fatal("fatal", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Log the plain messages
|
||||||
|
protected void logPlainMessages() {
|
||||||
|
log.trace("trace"); // Should not actually get logged
|
||||||
|
log.debug("debug");
|
||||||
|
log.info("info");
|
||||||
|
log.warn("warn");
|
||||||
|
log.error("error");
|
||||||
|
log.fatal("fatal");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up instance variables required by this test case.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
setUpManager
|
||||||
|
("org/apache/commons/logging/jdk14/CustomConfig.properties");
|
||||||
|
setUpLogger(this.getClass().getName());
|
||||||
|
setUpHandlers();
|
||||||
|
setUpFactory();
|
||||||
|
setUpLog(this.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set up handlers instance
|
||||||
|
protected void setUpHandlers() throws Exception {
|
||||||
|
Logger parent = logger;
|
||||||
|
while (parent.getParent() != null) {
|
||||||
|
parent = parent.getParent();
|
||||||
|
}
|
||||||
|
handlers = parent.getHandlers();
|
||||||
|
|
||||||
|
// The CustomConfig.properties file explicitly defines one handler class
|
||||||
|
// to be attached to the root logger, so if it isn't there then
|
||||||
|
// something is badly wrong...
|
||||||
|
//
|
||||||
|
// Yes this testing is also done in testPristineHandlers but
|
||||||
|
// unfortunately:
|
||||||
|
// * we need to set up the handlers variable here,
|
||||||
|
// * we don't want that to be set up incorrectly, as that can
|
||||||
|
// produce weird error messages in other tests, and
|
||||||
|
// * we can't rely on testPristineHandlers being the first
|
||||||
|
// test to run.
|
||||||
|
// so we need to test things here too.
|
||||||
|
assertNotNull("No Handlers defined for JDK14 logging", handlers);
|
||||||
|
assertEquals("Unexpected number of handlers for JDK14 logging", 1, handlers.length);
|
||||||
|
assertNotNull("Handler is null", handlers[0]);
|
||||||
|
assertTrue("Handler not of expected type", handlers[0] instanceof TestHandler);
|
||||||
|
handler = (TestHandler) handlers[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set up logger instance
|
||||||
|
protected void setUpLogger(final String name) throws Exception {
|
||||||
|
logger = Logger.getLogger(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------- Support Methods
|
||||||
|
|
||||||
|
|
||||||
|
// Set up LogManager instance
|
||||||
|
protected void setUpManager(final String config) throws Exception {
|
||||||
|
manager = LogManager.getLogManager();
|
||||||
|
final InputStream is =
|
||||||
|
this.getClass().getClassLoader().getResourceAsStream(config);
|
||||||
|
manager.readConfiguration(is);
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tear down instance variables required by this test case.
|
* Tear down instance variables required by this test case.
|
||||||
*/
|
*/
|
||||||
@@ -207,9 +336,6 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------- Test Methods
|
|
||||||
|
|
||||||
|
|
||||||
// Test logging message strings with exceptions
|
// Test logging message strings with exceptions
|
||||||
public void testExceptionMessages() throws Exception {
|
public void testExceptionMessages() throws Exception {
|
||||||
|
|
||||||
@@ -267,130 +393,4 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------- Support Methods
|
|
||||||
|
|
||||||
|
|
||||||
// Check the log instance
|
|
||||||
@Override
|
|
||||||
protected void checkLog() {
|
|
||||||
|
|
||||||
assertNotNull("Log exists", log);
|
|
||||||
assertEquals("Log class",
|
|
||||||
"org.apache.commons.logging.impl.Jdk14Logger",
|
|
||||||
log.getClass().getName());
|
|
||||||
|
|
||||||
// Assert which logging levels have been enabled
|
|
||||||
assertTrue(log.isFatalEnabled());
|
|
||||||
assertTrue(log.isErrorEnabled());
|
|
||||||
assertTrue(log.isWarnEnabled());
|
|
||||||
assertTrue(log.isInfoEnabled());
|
|
||||||
assertTrue(log.isDebugEnabled());
|
|
||||||
assertFalse(log.isTraceEnabled());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Check the recorded messages
|
|
||||||
protected void checkLogRecords(final boolean thrown) {
|
|
||||||
final Iterator records = handler.records();
|
|
||||||
for (int i = 0; i < testMessages.length; i++) {
|
|
||||||
assertTrue(records.hasNext());
|
|
||||||
final LogRecord record = (LogRecord) records.next();
|
|
||||||
assertEquals("LogRecord level",
|
|
||||||
testLevels[i], record.getLevel());
|
|
||||||
assertEquals("LogRecord message",
|
|
||||||
testMessages[i], record.getMessage());
|
|
||||||
assertTrue("LogRecord class",
|
|
||||||
record.getSourceClassName().startsWith(
|
|
||||||
"org.apache.commons.logging.jdk14.CustomConfig"));
|
|
||||||
if (thrown) {
|
|
||||||
assertEquals("LogRecord method",
|
|
||||||
"logExceptionMessages",
|
|
||||||
record.getSourceMethodName());
|
|
||||||
} else {
|
|
||||||
assertEquals("LogRecord method",
|
|
||||||
"logPlainMessages",
|
|
||||||
record.getSourceMethodName());
|
|
||||||
}
|
|
||||||
if (thrown) {
|
|
||||||
assertNotNull("LogRecord thrown", record.getThrown());
|
|
||||||
assertTrue("LogRecord thrown type",
|
|
||||||
record.getThrown() instanceof DummyException);
|
|
||||||
} else {
|
|
||||||
assertNull("LogRecord thrown",
|
|
||||||
record.getThrown());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertFalse(records.hasNext());
|
|
||||||
handler.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Log the messages with exceptions
|
|
||||||
protected void logExceptionMessages() {
|
|
||||||
final Throwable t = new DummyException();
|
|
||||||
log.trace("trace", t); // Should not actually get logged
|
|
||||||
log.debug("debug", t);
|
|
||||||
log.info("info", t);
|
|
||||||
log.warn("warn", t);
|
|
||||||
log.error("error", t);
|
|
||||||
log.fatal("fatal", t);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Log the plain messages
|
|
||||||
protected void logPlainMessages() {
|
|
||||||
log.trace("trace"); // Should not actually get logged
|
|
||||||
log.debug("debug");
|
|
||||||
log.info("info");
|
|
||||||
log.warn("warn");
|
|
||||||
log.error("error");
|
|
||||||
log.fatal("fatal");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set up handlers instance
|
|
||||||
protected void setUpHandlers() throws Exception {
|
|
||||||
Logger parent = logger;
|
|
||||||
while (parent.getParent() != null) {
|
|
||||||
parent = parent.getParent();
|
|
||||||
}
|
|
||||||
handlers = parent.getHandlers();
|
|
||||||
|
|
||||||
// The CustomConfig.properties file explicitly defines one handler class
|
|
||||||
// to be attached to the root logger, so if it isn't there then
|
|
||||||
// something is badly wrong...
|
|
||||||
//
|
|
||||||
// Yes this testing is also done in testPristineHandlers but
|
|
||||||
// unfortunately:
|
|
||||||
// * we need to set up the handlers variable here,
|
|
||||||
// * we don't want that to be set up incorrectly, as that can
|
|
||||||
// produce weird error messages in other tests, and
|
|
||||||
// * we can't rely on testPristineHandlers being the first
|
|
||||||
// test to run.
|
|
||||||
// so we need to test things here too.
|
|
||||||
assertNotNull("No Handlers defined for JDK14 logging", handlers);
|
|
||||||
assertEquals("Unexpected number of handlers for JDK14 logging", 1, handlers.length);
|
|
||||||
assertNotNull("Handler is null", handlers[0]);
|
|
||||||
assertTrue("Handler not of expected type", handlers[0] instanceof TestHandler);
|
|
||||||
handler = (TestHandler) handlers[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set up logger instance
|
|
||||||
protected void setUpLogger(final String name) throws Exception {
|
|
||||||
logger = Logger.getLogger(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set up LogManager instance
|
|
||||||
protected void setUpManager(final String config) throws Exception {
|
|
||||||
manager = LogManager.getLogManager();
|
|
||||||
final InputStream is =
|
|
||||||
this.getClass().getClassLoader().getResourceAsStream(config);
|
|
||||||
manager.readConfiguration(is);
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,34 +39,6 @@ import org.apache.commons.logging.PathableTestSuite;
|
|||||||
*/
|
*/
|
||||||
public class DefaultConfigTestCase extends TestCase {
|
public class DefaultConfigTestCase extends TestCase {
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Construct a new instance of this test case.</p>
|
|
||||||
*
|
|
||||||
* @param name Name of the test case
|
|
||||||
*/
|
|
||||||
public DefaultConfigTestCase(final String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The {@link LogFactory} implementation we have selected.</p>
|
|
||||||
*/
|
|
||||||
protected LogFactory factory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The {@link Log} implementation we have selected.</p>
|
|
||||||
*/
|
|
||||||
protected Log log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up instance variables required by this test case.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
setUpFactory();
|
|
||||||
setUpLog("TestLogger");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
*/
|
*/
|
||||||
@@ -81,50 +53,22 @@ public class DefaultConfigTestCase extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tear down instance variables required by this test case.
|
* <p>The {@link LogFactory} implementation we have selected.</p>
|
||||||
*/
|
*/
|
||||||
@Override
|
protected LogFactory factory;
|
||||||
public void tearDown() {
|
|
||||||
log = null;
|
|
||||||
factory = null;
|
|
||||||
LogFactory.releaseAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test pristine Log instance
|
/**
|
||||||
public void testPristineLog() {
|
* <p>The {@link Log} implementation we have selected.</p>
|
||||||
checkLog();
|
*/
|
||||||
}
|
protected Log log;
|
||||||
|
|
||||||
// Test pristine LogFactory instance
|
|
||||||
public void testPristineFactory() {
|
|
||||||
assertNotNull("LogFactory exists", factory);
|
|
||||||
assertEquals("LogFactory class",
|
|
||||||
"org.apache.commons.logging.impl.LogFactoryImpl",
|
|
||||||
factory.getClass().getName());
|
|
||||||
|
|
||||||
final String[] names = factory.getAttributeNames();
|
|
||||||
assertNotNull("Names exists", names);
|
|
||||||
assertEquals("Names empty", 0, names.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Test Serializability of Log instance
|
|
||||||
public void testSerializable() throws Exception {
|
|
||||||
|
|
||||||
// Serialize and deserialize the instance
|
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
final ObjectOutputStream oos = new ObjectOutputStream(baos);
|
|
||||||
oos.writeObject(log);
|
|
||||||
oos.close();
|
|
||||||
final ByteArrayInputStream bais =
|
|
||||||
new ByteArrayInputStream(baos.toByteArray());
|
|
||||||
final ObjectInputStream ois = new ObjectInputStream(bais);
|
|
||||||
log = (Log) ois.readObject();
|
|
||||||
ois.close();
|
|
||||||
|
|
||||||
// Check the characteristics of the resulting object
|
|
||||||
checkLog();
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Construct a new instance of this test case.</p>
|
||||||
|
*
|
||||||
|
* @param name Name of the test case
|
||||||
|
*/
|
||||||
|
public DefaultConfigTestCase(final String name) {
|
||||||
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the log instance
|
// Check the log instance
|
||||||
@@ -145,6 +89,15 @@ public class DefaultConfigTestCase extends TestCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up instance variables required by this test case.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
setUpFactory();
|
||||||
|
setUpLog("TestLogger");
|
||||||
|
}
|
||||||
|
|
||||||
// Set up factory instance
|
// Set up factory instance
|
||||||
protected void setUpFactory() throws Exception {
|
protected void setUpFactory() throws Exception {
|
||||||
factory = LogFactory.getFactory();
|
factory = LogFactory.getFactory();
|
||||||
@@ -155,4 +108,51 @@ public class DefaultConfigTestCase extends TestCase {
|
|||||||
log = LogFactory.getLog(name);
|
log = LogFactory.getLog(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tear down instance variables required by this test case.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void tearDown() {
|
||||||
|
log = null;
|
||||||
|
factory = null;
|
||||||
|
LogFactory.releaseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test pristine LogFactory instance
|
||||||
|
public void testPristineFactory() {
|
||||||
|
assertNotNull("LogFactory exists", factory);
|
||||||
|
assertEquals("LogFactory class",
|
||||||
|
"org.apache.commons.logging.impl.LogFactoryImpl",
|
||||||
|
factory.getClass().getName());
|
||||||
|
|
||||||
|
final String[] names = factory.getAttributeNames();
|
||||||
|
assertNotNull("Names exists", names);
|
||||||
|
assertEquals("Names empty", 0, names.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test pristine Log instance
|
||||||
|
public void testPristineLog() {
|
||||||
|
checkLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Serializability of Log instance
|
||||||
|
public void testSerializable() throws Exception {
|
||||||
|
|
||||||
|
// Serialize and deserialize the instance
|
||||||
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
final ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
|
oos.writeObject(log);
|
||||||
|
oos.close();
|
||||||
|
final ByteArrayInputStream bais =
|
||||||
|
new ByteArrayInputStream(baos.toByteArray());
|
||||||
|
final ObjectInputStream ois = new ObjectInputStream(bais);
|
||||||
|
log = (Log) ois.readObject();
|
||||||
|
ois.close();
|
||||||
|
|
||||||
|
// Check the characteristics of the resulting object
|
||||||
|
checkLog();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ public class TestHandler extends Handler {
|
|||||||
// The set of logged records for this handler
|
// The set of logged records for this handler
|
||||||
private final List records = new ArrayList();
|
private final List records = new ArrayList();
|
||||||
|
|
||||||
public Iterator records() {
|
|
||||||
return records.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
}
|
}
|
||||||
@@ -50,4 +46,8 @@ public class TestHandler extends Handler {
|
|||||||
records.add(record);
|
records.add(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Iterator records() {
|
||||||
|
return records.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,91 +51,6 @@ public abstract class StandardTests extends TestCase {
|
|||||||
public Throwable throwable;
|
public Throwable throwable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up instance variables required by this test case.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
LogFactory.releaseAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tear down instance variables required by this test case.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void tearDown() {
|
|
||||||
LogFactory.releaseAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Modify log4j's setup so that all messages actually logged get redirected
|
|
||||||
* into the specified list.
|
|
||||||
* <p>
|
|
||||||
* This method also sets the logging level to INFO so that we
|
|
||||||
* can test whether messages are getting properly filtered.
|
|
||||||
*/
|
|
||||||
public abstract void setUpTestAppender(List logEvents) throws Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that a LogFactory gets created as expected.
|
|
||||||
*/
|
|
||||||
public void testCreateFactory() {
|
|
||||||
final LogFactory factory = LogFactory.getFactory();
|
|
||||||
assertNotNull("LogFactory exists", factory);
|
|
||||||
assertEquals("LogFactory class",
|
|
||||||
"org.apache.commons.logging.impl.LogFactoryImpl",
|
|
||||||
factory.getClass().getName());
|
|
||||||
|
|
||||||
final String[] names = factory.getAttributeNames();
|
|
||||||
assertNotNull("Names exists", names);
|
|
||||||
assertEquals("Names empty", 0, names.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that we can log messages without exceptions.
|
|
||||||
*/
|
|
||||||
public void testPlainMessages() throws Exception {
|
|
||||||
final List logEvents = new ArrayList();
|
|
||||||
setUpTestAppender(logEvents);
|
|
||||||
final Log log = LogFactory.getLog("test-category");
|
|
||||||
logPlainMessages(log);
|
|
||||||
checkLoggingEvents(logEvents, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that we can log exception messages.
|
|
||||||
*/
|
|
||||||
public void testExceptionMessages() throws Exception {
|
|
||||||
final List logEvents = new ArrayList();
|
|
||||||
setUpTestAppender(logEvents);
|
|
||||||
final Log log = LogFactory.getLog("test-category");
|
|
||||||
logExceptionMessages(log);
|
|
||||||
checkLoggingEvents(logEvents, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test Serializability of Log instance
|
|
||||||
*/
|
|
||||||
public void testSerializable() throws Exception {
|
|
||||||
final List logEvents = new ArrayList();
|
|
||||||
setUpTestAppender(logEvents);
|
|
||||||
final Log log = LogFactory.getLog("test-category");
|
|
||||||
|
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
final ObjectOutputStream oos = new ObjectOutputStream(baos);
|
|
||||||
oos.writeObject(log);
|
|
||||||
oos.close();
|
|
||||||
final ByteArrayInputStream bais =
|
|
||||||
new ByteArrayInputStream(baos.toByteArray());
|
|
||||||
final ObjectInputStream ois = new ObjectInputStream(bais);
|
|
||||||
final Log newLog = (Log) ois.readObject();
|
|
||||||
ois.close();
|
|
||||||
|
|
||||||
// Check the characteristics of the resulting object
|
|
||||||
logExceptionMessages(newLog);
|
|
||||||
checkLoggingEvents(logEvents, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that the TestAppender has received the expected
|
* Verify that the TestAppender has received the expected
|
||||||
* number of messages. This assumes that:
|
* number of messages. This assumes that:
|
||||||
@@ -178,6 +93,18 @@ public abstract class StandardTests extends TestCase {
|
|||||||
assertEquals("Exception data incorrect", ev.throwable!=null, thrown);
|
assertEquals("Exception data incorrect", ev.throwable!=null, thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log messages with exceptions
|
||||||
|
*/
|
||||||
|
private void logExceptionMessages(final Log log) {
|
||||||
|
final Throwable t = new DummyException();
|
||||||
|
log.trace("trace", t); // Should not actually get logged
|
||||||
|
log.debug("debug", t); // Should not actually get logged
|
||||||
|
log.info("info", t);
|
||||||
|
log.warn("warn", t);
|
||||||
|
log.error("error", t);
|
||||||
|
log.fatal("fatal", t);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log plain messages.
|
* Log plain messages.
|
||||||
@@ -192,15 +119,88 @@ public abstract class StandardTests extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log messages with exceptions
|
* Set up instance variables required by this test case.
|
||||||
*/
|
*/
|
||||||
private void logExceptionMessages(final Log log) {
|
@Override
|
||||||
final Throwable t = new DummyException();
|
public void setUp() throws Exception {
|
||||||
log.trace("trace", t); // Should not actually get logged
|
LogFactory.releaseAll();
|
||||||
log.debug("debug", t); // Should not actually get logged
|
}
|
||||||
log.info("info", t);
|
|
||||||
log.warn("warn", t);
|
/**
|
||||||
log.error("error", t);
|
* Modify log4j's setup so that all messages actually logged get redirected
|
||||||
log.fatal("fatal", t);
|
* into the specified list.
|
||||||
|
* <p>
|
||||||
|
* This method also sets the logging level to INFO so that we
|
||||||
|
* can test whether messages are getting properly filtered.
|
||||||
|
*/
|
||||||
|
public abstract void setUpTestAppender(List logEvents) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tear down instance variables required by this test case.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void tearDown() {
|
||||||
|
LogFactory.releaseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that a LogFactory gets created as expected.
|
||||||
|
*/
|
||||||
|
public void testCreateFactory() {
|
||||||
|
final LogFactory factory = LogFactory.getFactory();
|
||||||
|
assertNotNull("LogFactory exists", factory);
|
||||||
|
assertEquals("LogFactory class",
|
||||||
|
"org.apache.commons.logging.impl.LogFactoryImpl",
|
||||||
|
factory.getClass().getName());
|
||||||
|
|
||||||
|
final String[] names = factory.getAttributeNames();
|
||||||
|
assertNotNull("Names exists", names);
|
||||||
|
assertEquals("Names empty", 0, names.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that we can log exception messages.
|
||||||
|
*/
|
||||||
|
public void testExceptionMessages() throws Exception {
|
||||||
|
final List logEvents = new ArrayList();
|
||||||
|
setUpTestAppender(logEvents);
|
||||||
|
final Log log = LogFactory.getLog("test-category");
|
||||||
|
logExceptionMessages(log);
|
||||||
|
checkLoggingEvents(logEvents, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that we can log messages without exceptions.
|
||||||
|
*/
|
||||||
|
public void testPlainMessages() throws Exception {
|
||||||
|
final List logEvents = new ArrayList();
|
||||||
|
setUpTestAppender(logEvents);
|
||||||
|
final Log log = LogFactory.getLog("test-category");
|
||||||
|
logPlainMessages(log);
|
||||||
|
checkLoggingEvents(logEvents, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Serializability of Log instance
|
||||||
|
*/
|
||||||
|
public void testSerializable() throws Exception {
|
||||||
|
final List logEvents = new ArrayList();
|
||||||
|
setUpTestAppender(logEvents);
|
||||||
|
final Log log = LogFactory.getLog("test-category");
|
||||||
|
|
||||||
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
final ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
|
oos.writeObject(log);
|
||||||
|
oos.close();
|
||||||
|
final ByteArrayInputStream bais =
|
||||||
|
new ByteArrayInputStream(baos.toByteArray());
|
||||||
|
final ObjectInputStream ois = new ObjectInputStream(bais);
|
||||||
|
final Log newLog = (Log) ois.readObject();
|
||||||
|
ois.close();
|
||||||
|
|
||||||
|
// Check the characteristics of the resulting object
|
||||||
|
logExceptionMessages(newLog);
|
||||||
|
checkLoggingEvents(logEvents, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ import org.apache.log4j.spi.LoggingEvent;
|
|||||||
|
|
||||||
public class TestAppender extends AppenderSkeleton {
|
public class TestAppender extends AppenderSkeleton {
|
||||||
|
|
||||||
|
// The set of logged events for this appender
|
||||||
|
private final List events;
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Instance Variables
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
@@ -40,12 +46,6 @@ public class TestAppender extends AppenderSkeleton {
|
|||||||
events = logEvents;
|
events = logEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------- Instance Variables
|
|
||||||
|
|
||||||
|
|
||||||
// The set of logged events for this appender
|
|
||||||
private final List events;
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------- Appender Methods
|
// ------------------------------------------------------- Appender Methods
|
||||||
|
|
||||||
|
|||||||
@@ -42,21 +42,6 @@ public class StandardTestCase extends AbstractLogTest {
|
|||||||
// ----------------------------------------------------- Instance Variables
|
// ----------------------------------------------------- Instance Variables
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The {@link LogFactory} implementation we have selected.</p>
|
|
||||||
*/
|
|
||||||
protected LogFactory factory;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The {@link Log} implementation we have selected.</p>
|
|
||||||
*/
|
|
||||||
protected Log log;
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------- JUnit Infrastructure Methods
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
*/
|
*/
|
||||||
@@ -73,6 +58,51 @@ public class StandardTestCase extends AbstractLogTest {
|
|||||||
return new PathableTestSuite(testClass, loader);
|
return new PathableTestSuite(testClass, loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The {@link LogFactory} implementation we have selected.</p>
|
||||||
|
*/
|
||||||
|
protected LogFactory factory;
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------- JUnit Infrastructure Methods
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The {@link Log} implementation we have selected.</p>
|
||||||
|
*/
|
||||||
|
protected Log log;
|
||||||
|
|
||||||
|
// Check the standard log instance
|
||||||
|
protected void checkStandard() {
|
||||||
|
|
||||||
|
assertNotNull("Log exists", log);
|
||||||
|
assertEquals("Log class",
|
||||||
|
"org.apache.commons.logging.impl.LogKitLogger",
|
||||||
|
log.getClass().getName());
|
||||||
|
|
||||||
|
// Can we call level checkers with no exceptions?
|
||||||
|
// Note that by default *everything* is enabled for LogKit
|
||||||
|
assertTrue(log.isTraceEnabled());
|
||||||
|
assertTrue(log.isDebugEnabled());
|
||||||
|
assertTrue(log.isInfoEnabled());
|
||||||
|
assertTrue(log.isWarnEnabled());
|
||||||
|
assertTrue(log.isErrorEnabled());
|
||||||
|
assertTrue(log.isFatalEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the abstract method from the parent class so that the
|
||||||
|
* inherited tests can access the right Log object type.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Log getLogObject()
|
||||||
|
{
|
||||||
|
return new LogKitLogger(this.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------- Test Methods
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up instance variables required by this test case.
|
* Set up instance variables required by this test case.
|
||||||
*/
|
*/
|
||||||
@@ -98,18 +128,6 @@ public class StandardTestCase extends AbstractLogTest {
|
|||||||
LogFactory.releaseAll();
|
LogFactory.releaseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------- Test Methods
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the abstract method from the parent class so that the
|
|
||||||
* inherited tests can access the right Log object type.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Log getLogObject()
|
|
||||||
{
|
|
||||||
return new LogKitLogger(this.getClass().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test pristine LogFactory instance
|
// Test pristine LogFactory instance
|
||||||
public void testPristineFactory() {
|
public void testPristineFactory() {
|
||||||
|
|
||||||
@@ -128,6 +146,9 @@ public class StandardTestCase extends AbstractLogTest {
|
|||||||
checkStandard();
|
checkStandard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------- Support Methods
|
||||||
|
|
||||||
// Test Serializability of standard instance
|
// Test Serializability of standard instance
|
||||||
public void testSerializable() throws Exception {
|
public void testSerializable() throws Exception {
|
||||||
checkStandard();
|
checkStandard();
|
||||||
@@ -145,25 +166,4 @@ public class StandardTestCase extends AbstractLogTest {
|
|||||||
|
|
||||||
checkStandard();
|
checkStandard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------- Support Methods
|
|
||||||
|
|
||||||
// Check the standard log instance
|
|
||||||
protected void checkStandard() {
|
|
||||||
|
|
||||||
assertNotNull("Log exists", log);
|
|
||||||
assertEquals("Log class",
|
|
||||||
"org.apache.commons.logging.impl.LogKitLogger",
|
|
||||||
log.getClass().getName());
|
|
||||||
|
|
||||||
// Can we call level checkers with no exceptions?
|
|
||||||
// Note that by default *everything* is enabled for LogKit
|
|
||||||
assertTrue(log.isTraceEnabled());
|
|
||||||
assertTrue(log.isDebugEnabled());
|
|
||||||
assertTrue(log.isInfoEnabled());
|
|
||||||
assertTrue(log.isWarnEnabled());
|
|
||||||
assertTrue(log.isErrorEnabled());
|
|
||||||
assertTrue(log.isFatalEnabled());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,33 @@ import org.apache.commons.logging.AbstractLogTest;
|
|||||||
*/
|
*/
|
||||||
public class NoOpLogTestCase extends AbstractLogTest
|
public class NoOpLogTestCase extends AbstractLogTest
|
||||||
{
|
{
|
||||||
|
private void checkLog(final Log log) {
|
||||||
|
|
||||||
|
assertNotNull("Log exists", log);
|
||||||
|
assertEquals("Log class",
|
||||||
|
"org.apache.commons.logging.impl.NoOpLog",
|
||||||
|
log.getClass().getName());
|
||||||
|
|
||||||
|
// Can we call level checkers with no exceptions?
|
||||||
|
// Note that *everything* is permanently disabled for NoOpLog
|
||||||
|
assertFalse(log.isTraceEnabled());
|
||||||
|
assertFalse(log.isDebugEnabled());
|
||||||
|
assertFalse(log.isInfoEnabled());
|
||||||
|
assertFalse(log.isWarnEnabled());
|
||||||
|
assertFalse(log.isErrorEnabled());
|
||||||
|
assertFalse(log.isFatalEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the abstract method from the parent class so that the
|
||||||
|
* inherited tests can access the right Log object type.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Log getLogObject()
|
||||||
|
{
|
||||||
|
return new NoOpLog(this.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up instance variables required by this test case.
|
* Set up instance variables required by this test case.
|
||||||
*/
|
*/
|
||||||
@@ -55,15 +82,8 @@ public class NoOpLogTestCase extends AbstractLogTest
|
|||||||
System.getProperties().remove("org.apache.commons.logging.Log");
|
System.getProperties().remove("org.apache.commons.logging.Log");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the abstract method from the parent class so that the
|
// -------------------------------------------------------- Support Methods
|
||||||
* inherited tests can access the right Log object type.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Log getLogObject()
|
|
||||||
{
|
|
||||||
return new NoOpLog(this.getClass().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test Serializability of standard instance
|
// Test Serializability of standard instance
|
||||||
public void testSerializable() throws Exception {
|
public void testSerializable() throws Exception {
|
||||||
@@ -83,24 +103,4 @@ public class NoOpLogTestCase extends AbstractLogTest
|
|||||||
|
|
||||||
checkLog(log);
|
checkLog(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------- Support Methods
|
|
||||||
|
|
||||||
private void checkLog(final Log log) {
|
|
||||||
|
|
||||||
assertNotNull("Log exists", log);
|
|
||||||
assertEquals("Log class",
|
|
||||||
"org.apache.commons.logging.impl.NoOpLog",
|
|
||||||
log.getClass().getName());
|
|
||||||
|
|
||||||
// Can we call level checkers with no exceptions?
|
|
||||||
// Note that *everything* is permanently disabled for NoOpLog
|
|
||||||
assertFalse(log.isTraceEnabled());
|
|
||||||
assertFalse(log.isDebugEnabled());
|
|
||||||
assertFalse(log.isInfoEnabled());
|
|
||||||
assertFalse(log.isWarnEnabled());
|
|
||||||
assertFalse(log.isErrorEnabled());
|
|
||||||
assertFalse(log.isFatalEnabled());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,19 @@ public class ChildFirstTestCase extends TestCase {
|
|||||||
return new PathableTestSuite(testClass, context);
|
return new PathableTestSuite(testClass, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method to convert an enumeration-of-URLs into an array of URLs.
|
||||||
|
*/
|
||||||
|
private static URL[] toURLArray(final Enumeration e) {
|
||||||
|
final ArrayList l = new ArrayList();
|
||||||
|
while (e.hasMoreElements()) {
|
||||||
|
final URL u = (URL) e.nextElement();
|
||||||
|
l.add(u);
|
||||||
|
}
|
||||||
|
final URL[] tmp = new URL[l.size()];
|
||||||
|
return (URL[]) l.toArray(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to return the set of all classloaders in the
|
* Utility method to return the set of all classloaders in the
|
||||||
* parent chain starting from the one that loaded the class for
|
* parent chain starting from the one that loaded the class for
|
||||||
@@ -220,6 +233,34 @@ public class ChildFirstTestCase extends TestCase {
|
|||||||
resource.toString().indexOf("/commons-logging-adapters-1.") > 0);
|
resource.toString().indexOf("/commons-logging-adapters-1.") > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that getResourceAsStream works.
|
||||||
|
*/
|
||||||
|
public void testResourceAsStream() throws Exception {
|
||||||
|
java.io.InputStream is;
|
||||||
|
|
||||||
|
// verify the classloader hierarchy
|
||||||
|
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
final ClassLoader childLoader = contextLoader.getParent();
|
||||||
|
final ClassLoader parentLoader = childLoader.getParent();
|
||||||
|
final ClassLoader bootLoader = parentLoader.getParent();
|
||||||
|
assertNull("Unexpected classloader hierarchy", bootLoader);
|
||||||
|
|
||||||
|
// getResourceAsStream where no instances exist
|
||||||
|
is = childLoader.getResourceAsStream("nosuchfile");
|
||||||
|
assertNull("Invalid resource returned non-null stream", is);
|
||||||
|
|
||||||
|
// getResourceAsStream where resource does exist
|
||||||
|
is = childLoader.getResourceAsStream("org/apache/commons/logging/Log.class");
|
||||||
|
assertNotNull("Null returned for valid resource", is);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
// It would be nice to test parent-first ordering here, but that would require
|
||||||
|
// having a resource with the same name in both the parent and child loaders,
|
||||||
|
// but with different contents. That's a little tricky to set up so we'll
|
||||||
|
// skip that for now.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the various flavours of ClassLoader.getResources work as expected.
|
* Test that the various flavours of ClassLoader.getResources work as expected.
|
||||||
*/
|
*/
|
||||||
@@ -273,45 +314,4 @@ public class ChildFirstTestCase extends TestCase {
|
|||||||
assertTrue("Incorrect source for Log4JLogger class",
|
assertTrue("Incorrect source for Log4JLogger class",
|
||||||
urlsToStrings[1].indexOf("/commons-logging-adapters-1.") > 0);
|
urlsToStrings[1].indexOf("/commons-logging-adapters-1.") > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility method to convert an enumeration-of-URLs into an array of URLs.
|
|
||||||
*/
|
|
||||||
private static URL[] toURLArray(final Enumeration e) {
|
|
||||||
final ArrayList l = new ArrayList();
|
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
final URL u = (URL) e.nextElement();
|
|
||||||
l.add(u);
|
|
||||||
}
|
|
||||||
final URL[] tmp = new URL[l.size()];
|
|
||||||
return (URL[]) l.toArray(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that getResourceAsStream works.
|
|
||||||
*/
|
|
||||||
public void testResourceAsStream() throws Exception {
|
|
||||||
java.io.InputStream is;
|
|
||||||
|
|
||||||
// verify the classloader hierarchy
|
|
||||||
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
|
||||||
final ClassLoader childLoader = contextLoader.getParent();
|
|
||||||
final ClassLoader parentLoader = childLoader.getParent();
|
|
||||||
final ClassLoader bootLoader = parentLoader.getParent();
|
|
||||||
assertNull("Unexpected classloader hierarchy", bootLoader);
|
|
||||||
|
|
||||||
// getResourceAsStream where no instances exist
|
|
||||||
is = childLoader.getResourceAsStream("nosuchfile");
|
|
||||||
assertNull("Invalid resource returned non-null stream", is);
|
|
||||||
|
|
||||||
// getResourceAsStream where resource does exist
|
|
||||||
is = childLoader.getResourceAsStream("org/apache/commons/logging/Log.class");
|
|
||||||
assertNotNull("Null returned for valid resource", is);
|
|
||||||
is.close();
|
|
||||||
|
|
||||||
// It would be nice to test parent-first ordering here, but that would require
|
|
||||||
// having a resource with the same name in both the parent and child loaders,
|
|
||||||
// but with different contents. That's a little tricky to set up so we'll
|
|
||||||
// skip that for now.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,31 @@ import org.apache.commons.logging.PathableTestSuite;
|
|||||||
|
|
||||||
public class GeneralTestCase extends TestCase {
|
public class GeneralTestCase extends TestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that the context classloader is a custom one, then reset it to
|
||||||
|
* a non-custom one.
|
||||||
|
*/
|
||||||
|
private static void checkAndSetContext() {
|
||||||
|
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
assertEquals("ContextLoader is of unexpected type",
|
||||||
|
contextLoader.getClass().getName(),
|
||||||
|
PathableClassLoader.class.getName());
|
||||||
|
|
||||||
|
final URL[] noUrls = new URL[0];
|
||||||
|
Thread.currentThread().setContextClassLoader(new URLClassLoader(noUrls));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that a certain system property is not set, then set it.
|
||||||
|
*/
|
||||||
|
private static void checkAndSetProperties() {
|
||||||
|
String prop = System.getProperty("no.such.property");
|
||||||
|
assertNull("no.such.property is unexpectedly defined", prop);
|
||||||
|
System.setProperty("no.such.property", "dummy value");
|
||||||
|
prop = System.getProperty("no.such.property");
|
||||||
|
assertNotNull("no.such.property is unexpectedly undefined", prop);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up a custom classloader hierarchy for this test case.
|
* Set up a custom classloader hierarchy for this test case.
|
||||||
*/
|
*/
|
||||||
@@ -49,53 +74,6 @@ public class GeneralTestCase extends TestCase {
|
|||||||
return new PathableTestSuite(testClass, loader);
|
return new PathableTestSuite(testClass, loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that a certain system property is not set, then set it.
|
|
||||||
*/
|
|
||||||
private static void checkAndSetProperties() {
|
|
||||||
String prop = System.getProperty("no.such.property");
|
|
||||||
assertNull("no.such.property is unexpectedly defined", prop);
|
|
||||||
System.setProperty("no.such.property", "dummy value");
|
|
||||||
prop = System.getProperty("no.such.property");
|
|
||||||
assertNotNull("no.such.property is unexpectedly undefined", prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that when a test method modifies the system properties they are
|
|
||||||
* reset before the next test is run.
|
|
||||||
* <p>
|
|
||||||
* This method works in conjunction with testResetProps2. There is no
|
|
||||||
* way of knowing which test method junit will run first, but it doesn't
|
|
||||||
* matter; whichever one of them runs first will modify the system properties.
|
|
||||||
* If the PathableTestSuite isn't resetting the system properties then whichever
|
|
||||||
* of them runs second will fail. Of course if other methods are run in-between
|
|
||||||
* then those methods might also fail...
|
|
||||||
*/
|
|
||||||
public void testResetProps1() {
|
|
||||||
checkAndSetProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See testResetProps1.
|
|
||||||
*/
|
|
||||||
public void testResetProps2() {
|
|
||||||
checkAndSetProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that the context classloader is a custom one, then reset it to
|
|
||||||
* a non-custom one.
|
|
||||||
*/
|
|
||||||
private static void checkAndSetContext() {
|
|
||||||
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
|
||||||
assertEquals("ContextLoader is of unexpected type",
|
|
||||||
contextLoader.getClass().getName(),
|
|
||||||
PathableClassLoader.class.getName());
|
|
||||||
|
|
||||||
final URL[] noUrls = new URL[0];
|
|
||||||
Thread.currentThread().setContextClassLoader(new URLClassLoader(noUrls));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that when a test method modifies the context classloader it is
|
* Verify that when a test method modifies the context classloader it is
|
||||||
* reset before the next test is run.
|
* reset before the next test is run.
|
||||||
@@ -117,4 +95,26 @@ public class GeneralTestCase extends TestCase {
|
|||||||
public void testResetContext2() {
|
public void testResetContext2() {
|
||||||
checkAndSetContext();
|
checkAndSetContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that when a test method modifies the system properties they are
|
||||||
|
* reset before the next test is run.
|
||||||
|
* <p>
|
||||||
|
* This method works in conjunction with testResetProps2. There is no
|
||||||
|
* way of knowing which test method junit will run first, but it doesn't
|
||||||
|
* matter; whichever one of them runs first will modify the system properties.
|
||||||
|
* If the PathableTestSuite isn't resetting the system properties then whichever
|
||||||
|
* of them runs second will fail. Of course if other methods are run in-between
|
||||||
|
* then those methods might also fail...
|
||||||
|
*/
|
||||||
|
public void testResetProps1() {
|
||||||
|
checkAndSetProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See testResetProps1.
|
||||||
|
*/
|
||||||
|
public void testResetProps2() {
|
||||||
|
checkAndSetProperties();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,19 @@ public class ParentFirstTestCase extends TestCase {
|
|||||||
return new PathableTestSuite(testClass, context);
|
return new PathableTestSuite(testClass, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method to convert an enumeration-of-URLs into an array of URLs.
|
||||||
|
*/
|
||||||
|
private static URL[] toURLArray(final Enumeration e) {
|
||||||
|
final ArrayList l = new ArrayList();
|
||||||
|
while (e.hasMoreElements()) {
|
||||||
|
final URL u = (URL) e.nextElement();
|
||||||
|
l.add(u);
|
||||||
|
}
|
||||||
|
final URL[] tmp = new URL[l.size()];
|
||||||
|
return (URL[]) l.toArray(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to return the set of all classloaders in the
|
* Utility method to return the set of all classloaders in the
|
||||||
* parent chain starting from the one that loaded the class for
|
* parent chain starting from the one that loaded the class for
|
||||||
@@ -218,6 +231,34 @@ public class ParentFirstTestCase extends TestCase {
|
|||||||
resource.toString().indexOf("/commons-logging-1.") > 0);
|
resource.toString().indexOf("/commons-logging-1.") > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that getResourceAsStream works.
|
||||||
|
*/
|
||||||
|
public void testResourceAsStream() throws Exception {
|
||||||
|
java.io.InputStream is;
|
||||||
|
|
||||||
|
// verify the classloader hierarchy
|
||||||
|
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
final ClassLoader childLoader = contextLoader.getParent();
|
||||||
|
final ClassLoader parentLoader = childLoader.getParent();
|
||||||
|
final ClassLoader bootLoader = parentLoader.getParent();
|
||||||
|
assertNull("Unexpected classloader hierarchy", bootLoader);
|
||||||
|
|
||||||
|
// getResourceAsStream where no instances exist
|
||||||
|
is = childLoader.getResourceAsStream("nosuchfile");
|
||||||
|
assertNull("Invalid resource returned non-null stream", is);
|
||||||
|
|
||||||
|
// getResourceAsStream where resource does exist
|
||||||
|
is = childLoader.getResourceAsStream("org/apache/commons/logging/Log.class");
|
||||||
|
assertNotNull("Null returned for valid resource", is);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
// It would be nice to test parent-first ordering here, but that would require
|
||||||
|
// having a resource with the same name in both the parent and child loaders,
|
||||||
|
// but with different contents. That's a little tricky to set up so we'll
|
||||||
|
// skip that for now.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the various flavours of ClassLoader.getResources work as expected.
|
* Test that the various flavours of ClassLoader.getResources work as expected.
|
||||||
*/
|
*/
|
||||||
@@ -265,45 +306,4 @@ public class ParentFirstTestCase extends TestCase {
|
|||||||
urlsToStrings[1].indexOf("/commons-logging-adapters-1.") > 0);
|
urlsToStrings[1].indexOf("/commons-logging-adapters-1.") > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility method to convert an enumeration-of-URLs into an array of URLs.
|
|
||||||
*/
|
|
||||||
private static URL[] toURLArray(final Enumeration e) {
|
|
||||||
final ArrayList l = new ArrayList();
|
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
final URL u = (URL) e.nextElement();
|
|
||||||
l.add(u);
|
|
||||||
}
|
|
||||||
final URL[] tmp = new URL[l.size()];
|
|
||||||
return (URL[]) l.toArray(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that getResourceAsStream works.
|
|
||||||
*/
|
|
||||||
public void testResourceAsStream() throws Exception {
|
|
||||||
java.io.InputStream is;
|
|
||||||
|
|
||||||
// verify the classloader hierarchy
|
|
||||||
final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
|
||||||
final ClassLoader childLoader = contextLoader.getParent();
|
|
||||||
final ClassLoader parentLoader = childLoader.getParent();
|
|
||||||
final ClassLoader bootLoader = parentLoader.getParent();
|
|
||||||
assertNull("Unexpected classloader hierarchy", bootLoader);
|
|
||||||
|
|
||||||
// getResourceAsStream where no instances exist
|
|
||||||
is = childLoader.getResourceAsStream("nosuchfile");
|
|
||||||
assertNull("Invalid resource returned non-null stream", is);
|
|
||||||
|
|
||||||
// getResourceAsStream where resource does exist
|
|
||||||
is = childLoader.getResourceAsStream("org/apache/commons/logging/Log.class");
|
|
||||||
assertNotNull("Null returned for valid resource", is);
|
|
||||||
is.close();
|
|
||||||
|
|
||||||
// It would be nice to test parent-first ordering here, but that would require
|
|
||||||
// having a resource with the same name in both the parent and child loaders,
|
|
||||||
// but with different contents. That's a little tricky to set up so we'll
|
|
||||||
// skip that for now.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ import java.security.Permissions;
|
|||||||
*/
|
*/
|
||||||
public class MockSecurityManager extends SecurityManager {
|
public class MockSecurityManager extends SecurityManager {
|
||||||
|
|
||||||
private final Permissions permissions = new Permissions();
|
|
||||||
private static final Permission setSecurityManagerPerm =
|
private static final Permission setSecurityManagerPerm =
|
||||||
new RuntimePermission("setSecurityManager");
|
new RuntimePermission("setSecurityManager");
|
||||||
|
private final Permissions permissions = new Permissions();
|
||||||
|
|
||||||
private int untrustedCodeCount;
|
private int untrustedCodeCount;
|
||||||
|
|
||||||
@@ -46,18 +46,6 @@ public class MockSecurityManager extends SecurityManager {
|
|||||||
permissions.add(p);
|
permissions.add(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This returns the number of times that a check of a permission failed
|
|
||||||
* due to stack-walking tracing up into untrusted code. Any non-zero
|
|
||||||
* value indicates a bug in JCL, ie a situation where code was not
|
|
||||||
* correctly wrapped in an AccessController block. The result of such a
|
|
||||||
* bug is that signing JCL is not sufficient to allow JCL to perform
|
|
||||||
* the operation; the caller would need to be signed too.
|
|
||||||
*/
|
|
||||||
public int getUntrustedCodeCount() {
|
|
||||||
return untrustedCodeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkPermission(final Permission p) throws SecurityException {
|
public void checkPermission(final Permission p) throws SecurityException {
|
||||||
if (setSecurityManagerPerm.implies(p)) {
|
if (setSecurityManagerPerm.implies(p)) {
|
||||||
@@ -147,4 +135,16 @@ public class MockSecurityManager extends SecurityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the number of times that a check of a permission failed
|
||||||
|
* due to stack-walking tracing up into untrusted code. Any non-zero
|
||||||
|
* value indicates a bug in JCL, ie a situation where code was not
|
||||||
|
* correctly wrapped in an AccessController block. The result of such a
|
||||||
|
* bug is that signing JCL is not sufficient to allow JCL to perform
|
||||||
|
* the operation; the caller would need to be signed too.
|
||||||
|
*/
|
||||||
|
public int getUntrustedCodeCount() {
|
||||||
|
return untrustedCodeCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ import org.apache.commons.logging.PathableTestSuite;
|
|||||||
*/
|
*/
|
||||||
public class SecurityAllowedTestCase extends TestCase
|
public class SecurityAllowedTestCase extends TestCase
|
||||||
{
|
{
|
||||||
private SecurityManager oldSecMgr;
|
|
||||||
|
|
||||||
// Dummy special hashtable, so we can tell JCL to use this instead of
|
// Dummy special hashtable, so we can tell JCL to use this instead of
|
||||||
// the standard one.
|
// the standard one.
|
||||||
public static class CustomHashtable extends Hashtable {
|
public static class CustomHashtable extends Hashtable {
|
||||||
@@ -69,6 +67,8 @@ public class SecurityAllowedTestCase extends TestCase
|
|||||||
return new PathableTestSuite(testClass, parent);
|
return new PathableTestSuite(testClass, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SecurityManager oldSecMgr;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
// save security manager so it can be restored in tearDown
|
// save security manager so it can be restored in tearDown
|
||||||
|
|||||||
@@ -48,9 +48,6 @@ import org.apache.commons.logging.PathableTestSuite;
|
|||||||
*/
|
*/
|
||||||
public class SecurityForbiddenTestCase extends TestCase
|
public class SecurityForbiddenTestCase extends TestCase
|
||||||
{
|
{
|
||||||
private SecurityManager oldSecMgr;
|
|
||||||
private ClassLoader otherClassLoader;
|
|
||||||
|
|
||||||
// Dummy special hashtable, so we can tell JCL to use this instead of
|
// Dummy special hashtable, so we can tell JCL to use this instead of
|
||||||
// the standard one.
|
// the standard one.
|
||||||
public static class CustomHashtable extends Hashtable {
|
public static class CustomHashtable extends Hashtable {
|
||||||
@@ -60,7 +57,6 @@ public class SecurityForbiddenTestCase extends TestCase
|
|||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 7224652794746236024L;
|
private static final long serialVersionUID = 7224652794746236024L;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
*/
|
*/
|
||||||
@@ -75,6 +71,27 @@ public class SecurityForbiddenTestCase extends TestCase
|
|||||||
return new PathableTestSuite(testClass, parent);
|
return new PathableTestSuite(testClass, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SecurityManager oldSecMgr;
|
||||||
|
|
||||||
|
private ClassLoader otherClassLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a class with the given classloader.
|
||||||
|
*/
|
||||||
|
private Object loadClass(final String name, final ClassLoader classLoader) {
|
||||||
|
try {
|
||||||
|
final Class clazz = classLoader.loadClass(name);
|
||||||
|
final Object obj = clazz.getConstructor().newInstance();
|
||||||
|
return obj;
|
||||||
|
} catch ( final Exception e ) {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final PrintWriter pw = new PrintWriter(sw);
|
||||||
|
e.printStackTrace(pw);
|
||||||
|
fail("Unexpected exception:" + e.getMessage() + ":" + sw.toString());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
// save security manager so it can be restored in tearDown
|
// save security manager so it can be restored in tearDown
|
||||||
@@ -175,21 +192,4 @@ public class SecurityForbiddenTestCase extends TestCase
|
|||||||
fail("Unexpected exception:" + t.getMessage() + ":" + sw.toString());
|
fail("Unexpected exception:" + t.getMessage() + ":" + sw.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a class with the given classloader.
|
|
||||||
*/
|
|
||||||
private Object loadClass(final String name, final ClassLoader classLoader) {
|
|
||||||
try {
|
|
||||||
final Class clazz = classLoader.loadClass(name);
|
|
||||||
final Object obj = clazz.getConstructor().newInstance();
|
|
||||||
return obj;
|
|
||||||
} catch ( final Exception e ) {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final PrintWriter pw = new PrintWriter(sw);
|
|
||||||
e.printStackTrace(pw);
|
|
||||||
fail("Unexpected exception:" + e.getMessage() + ":" + sw.toString());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,52 +37,6 @@ import org.apache.commons.logging.impl.SimpleLog;
|
|||||||
*/
|
*/
|
||||||
public class CustomConfigTestCase extends DefaultConfigTestCase {
|
public class CustomConfigTestCase extends DefaultConfigTestCase {
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The expected log records.</p>
|
|
||||||
*/
|
|
||||||
protected List expected;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The message levels that should have been logged.</p>
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
protected Level[] testLevels =
|
|
||||||
{ Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The message strings that should have been logged.</p>
|
|
||||||
*/
|
|
||||||
protected String[] testMessages =
|
|
||||||
{ "debug", "info", "warn", "error", "fatal" };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set system properties that will control the LogFactory/Log objects
|
|
||||||
* when they are created. Subclasses can override this method to
|
|
||||||
* define properties that suit them.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setProperties() {
|
|
||||||
System.setProperty(
|
|
||||||
"org.apache.commons.logging.Log",
|
|
||||||
"org.apache.commons.logging.simple.DecoratedSimpleLog");
|
|
||||||
System.setProperty(
|
|
||||||
"org.apache.commons.logging.simplelog.defaultlog",
|
|
||||||
"debug");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up instance variables required by this test case.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
LogFactory.releaseAll();
|
|
||||||
setProperties();
|
|
||||||
expected = new ArrayList();
|
|
||||||
setUpFactory();
|
|
||||||
setUpLog("DecoratedLogger");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -108,37 +62,23 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tear down instance variables required by this test case.
|
* <p>The message levels that should have been logged.</p>
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
protected Level[] testLevels =
|
||||||
|
{ Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE, Level.SEVERE };
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public void tearDown() {
|
|
||||||
super.tearDown();
|
|
||||||
expected = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test logging message strings with exceptions
|
/**
|
||||||
public void testExceptionMessages() throws Exception {
|
* <p>The expected log records.</p>
|
||||||
((DecoratedSimpleLog) log).clearCache();
|
*/
|
||||||
logExceptionMessages();
|
protected List expected;
|
||||||
checkExpected();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test logging plain message strings
|
/**
|
||||||
public void testPlainMessages() throws Exception {
|
* <p>The message strings that should have been logged.</p>
|
||||||
((DecoratedSimpleLog) log).clearCache();
|
*/
|
||||||
logPlainMessages();
|
protected String[] testMessages =
|
||||||
checkExpected();
|
{ "debug", "info", "warn", "error", "fatal" };
|
||||||
}
|
|
||||||
|
|
||||||
// Test Serializability of standard instance
|
|
||||||
@Override
|
|
||||||
public void testSerializable() throws Exception {
|
|
||||||
((DecoratedSimpleLog) log).clearCache();
|
|
||||||
logPlainMessages();
|
|
||||||
super.testSerializable();
|
|
||||||
logExceptionMessages();
|
|
||||||
checkExpected();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the decorated log instance
|
// Check the decorated log instance
|
||||||
@Override
|
@Override
|
||||||
@@ -169,19 +109,12 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Hook for subclassses */
|
|
||||||
protected void checkShowDateTime() {
|
|
||||||
assertFalse(((DecoratedSimpleLog) log).getShowDateTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Hook for subclasses */
|
/** Hook for subclasses */
|
||||||
protected void checkDecoratedDateTime() {
|
protected void checkDecoratedDateTime() {
|
||||||
assertEquals("yyyy/MM/dd HH:mm:ss:SSS zzz",
|
assertEquals("yyyy/MM/dd HH:mm:ss:SSS zzz",
|
||||||
((DecoratedSimpleLog) log).getDateTimeFormat());
|
((DecoratedSimpleLog) log).getDateTimeFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Check the actual log records against the expected ones
|
// Check the actual log records against the expected ones
|
||||||
protected void checkExpected() {
|
protected void checkExpected() {
|
||||||
final List acts = ((DecoratedSimpleLog) log).getCache();
|
final List acts = ((DecoratedSimpleLog) log).getCache();
|
||||||
@@ -196,6 +129,10 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Hook for subclassses */
|
||||||
|
protected void checkShowDateTime() {
|
||||||
|
assertFalse(((DecoratedSimpleLog) log).getShowDateTime());
|
||||||
|
}
|
||||||
|
|
||||||
// Check the standard log instance
|
// Check the standard log instance
|
||||||
@Override
|
@Override
|
||||||
@@ -203,7 +140,6 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
checkDecorated();
|
checkDecorated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Log the messages with exceptions
|
// Log the messages with exceptions
|
||||||
protected void logExceptionMessages() {
|
protected void logExceptionMessages() {
|
||||||
// Generate log records
|
// Generate log records
|
||||||
@@ -223,7 +159,6 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", t));
|
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Log the plain messages
|
// Log the plain messages
|
||||||
protected void logPlainMessages() {
|
protected void logPlainMessages() {
|
||||||
// Generate log records
|
// Generate log records
|
||||||
@@ -241,4 +176,69 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_ERROR, "error", null));
|
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_ERROR, "error", null));
|
||||||
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", null));
|
expected.add(new LogRecord(SimpleLog.LOG_LEVEL_FATAL, "fatal", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set system properties that will control the LogFactory/Log objects
|
||||||
|
* when they are created. Subclasses can override this method to
|
||||||
|
* define properties that suit them.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setProperties() {
|
||||||
|
System.setProperty(
|
||||||
|
"org.apache.commons.logging.Log",
|
||||||
|
"org.apache.commons.logging.simple.DecoratedSimpleLog");
|
||||||
|
System.setProperty(
|
||||||
|
"org.apache.commons.logging.simplelog.defaultlog",
|
||||||
|
"debug");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up instance variables required by this test case.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
LogFactory.releaseAll();
|
||||||
|
setProperties();
|
||||||
|
expected = new ArrayList();
|
||||||
|
setUpFactory();
|
||||||
|
setUpLog("DecoratedLogger");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tear down instance variables required by this test case.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void tearDown() {
|
||||||
|
super.tearDown();
|
||||||
|
expected = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test logging message strings with exceptions
|
||||||
|
public void testExceptionMessages() throws Exception {
|
||||||
|
((DecoratedSimpleLog) log).clearCache();
|
||||||
|
logExceptionMessages();
|
||||||
|
checkExpected();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test logging plain message strings
|
||||||
|
public void testPlainMessages() throws Exception {
|
||||||
|
((DecoratedSimpleLog) log).clearCache();
|
||||||
|
logPlainMessages();
|
||||||
|
checkExpected();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test Serializability of standard instance
|
||||||
|
@Override
|
||||||
|
public void testSerializable() throws Exception {
|
||||||
|
((DecoratedSimpleLog) log).clearCache();
|
||||||
|
logPlainMessages();
|
||||||
|
super.testSerializable();
|
||||||
|
logExceptionMessages();
|
||||||
|
checkExpected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,28 @@ public class DateTimeCustomConfigTestCase extends CustomConfigTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Checks that the date time format has been successfully set */
|
||||||
|
@Override
|
||||||
|
protected void checkDecoratedDateTime() {
|
||||||
|
assertEquals("Expected date format to be set", "dd.mm.yyyy",
|
||||||
|
((DecoratedSimpleLog) log).getDateTimeFormat());
|
||||||
|
// try the formatter
|
||||||
|
final Date now = new Date();
|
||||||
|
final DateFormat formatter = ((DecoratedSimpleLog) log).getDateTimeFormatter();
|
||||||
|
final SimpleDateFormat sampleFormatter = new SimpleDateFormat("dd.mm.yyyy");
|
||||||
|
assertEquals("Date should be formatters to pattern dd.mm.yyyy",
|
||||||
|
sampleFormatter.format(now), formatter.format(now));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Hook for subclassses */
|
||||||
|
@Override
|
||||||
|
protected void checkShowDateTime() {
|
||||||
|
assertTrue(((DecoratedSimpleLog) log).getShowDateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------- Methods
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up system properties required by this unit test. Here, we
|
* Set up system properties required by this unit test. Here, we
|
||||||
* set up the props defined in the parent class setProperties method,
|
* set up the props defined in the parent class setProperties method,
|
||||||
@@ -84,26 +106,4 @@ public class DateTimeCustomConfigTestCase extends CustomConfigTestCase {
|
|||||||
super.setUp();
|
super.setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------- Methods
|
|
||||||
|
|
||||||
/** Checks that the date time format has been successfully set */
|
|
||||||
@Override
|
|
||||||
protected void checkDecoratedDateTime() {
|
|
||||||
assertEquals("Expected date format to be set", "dd.mm.yyyy",
|
|
||||||
((DecoratedSimpleLog) log).getDateTimeFormat());
|
|
||||||
// try the formatter
|
|
||||||
final Date now = new Date();
|
|
||||||
final DateFormat formatter = ((DecoratedSimpleLog) log).getDateTimeFormatter();
|
|
||||||
final SimpleDateFormat sampleFormatter = new SimpleDateFormat("dd.mm.yyyy");
|
|
||||||
assertEquals("Date should be formatters to pattern dd.mm.yyyy",
|
|
||||||
sampleFormatter.format(now), formatter.format(now));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Hook for subclassses */
|
|
||||||
@Override
|
|
||||||
protected void checkShowDateTime() {
|
|
||||||
assertTrue(((DecoratedSimpleLog) log).getShowDateTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,58 +40,17 @@ public class DecoratedSimpleLog extends SimpleLog {
|
|||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 196544280770017153L;
|
private static final long serialVersionUID = 196544280770017153L;
|
||||||
|
|
||||||
public DecoratedSimpleLog(final String name) {
|
// Cache of logged records
|
||||||
super(name);
|
protected ArrayList cache = new ArrayList();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------- Properties
|
// ------------------------------------------------------------- Properties
|
||||||
|
|
||||||
public DateFormat getDateTimeFormatter() {
|
public DecoratedSimpleLog(final String name) {
|
||||||
return dateFormatter;
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getDateTimeFormat() {
|
|
||||||
return dateTimeFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getLogName() {
|
|
||||||
return logName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean getShowDateTime() {
|
|
||||||
return showDateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean getShowShortName() {
|
|
||||||
return showShortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------- Protected Methods
|
|
||||||
|
|
||||||
|
|
||||||
// Cache logged messages
|
|
||||||
@Override
|
|
||||||
protected void log(final int type, final Object message, final Throwable t) {
|
|
||||||
|
|
||||||
super.log(type, message, t);
|
|
||||||
cache.add(new LogRecord(type, message, t));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------- Public Methods
|
|
||||||
|
|
||||||
|
|
||||||
// Cache of logged records
|
|
||||||
protected ArrayList cache = new ArrayList();
|
|
||||||
|
|
||||||
|
|
||||||
// Clear cache
|
// Clear cache
|
||||||
public void clearCache() {
|
public void clearCache() {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
@@ -104,4 +63,45 @@ public class DecoratedSimpleLog extends SimpleLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getDateTimeFormat() {
|
||||||
|
return dateTimeFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DateFormat getDateTimeFormatter() {
|
||||||
|
return dateFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------- Protected Methods
|
||||||
|
|
||||||
|
|
||||||
|
public String getLogName() {
|
||||||
|
return logName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------- Public Methods
|
||||||
|
|
||||||
|
|
||||||
|
public boolean getShowDateTime() {
|
||||||
|
return showDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean getShowShortName() {
|
||||||
|
return showShortName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Cache logged messages
|
||||||
|
@Override
|
||||||
|
protected void log(final int type, final Object message, final Throwable t) {
|
||||||
|
|
||||||
|
super.log(type, message, t);
|
||||||
|
cache.add(new LogRecord(type, message, t));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,16 +40,6 @@ import org.apache.commons.logging.impl.SimpleLog;
|
|||||||
|
|
||||||
public class DefaultConfigTestCase extends TestCase {
|
public class DefaultConfigTestCase extends TestCase {
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The {@link LogFactory} implementation we have selected.</p>
|
|
||||||
*/
|
|
||||||
protected LogFactory factory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>The {@link Log} implementation we have selected.</p>
|
|
||||||
*/
|
|
||||||
protected Log log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -75,78 +65,14 @@ public class DefaultConfigTestCase extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set system properties that will control the LogFactory/Log objects
|
* <p>The {@link LogFactory} implementation we have selected.</p>
|
||||||
* when they are created. Subclasses can override this method to
|
|
||||||
* define properties that suit them.
|
|
||||||
*/
|
*/
|
||||||
public void setProperties() {
|
protected LogFactory factory;
|
||||||
System.setProperty(
|
|
||||||
"org.apache.commons.logging.Log",
|
|
||||||
"org.apache.commons.logging.impl.SimpleLog");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up instance variables required by this test case.
|
* <p>The {@link Log} implementation we have selected.</p>
|
||||||
*/
|
*/
|
||||||
@Override
|
protected Log log;
|
||||||
public void setUp() throws Exception {
|
|
||||||
LogFactory.releaseAll();
|
|
||||||
setProperties();
|
|
||||||
setUpFactory();
|
|
||||||
setUpLog("TestLogger");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tear down instance variables required by this test case.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void tearDown() {
|
|
||||||
log = null;
|
|
||||||
factory = null;
|
|
||||||
LogFactory.releaseAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test pristine DecoratedSimpleLog instance
|
|
||||||
public void testPristineDecorated() {
|
|
||||||
setUpDecorated("DecoratedLogger");
|
|
||||||
checkDecorated();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test pristine Log instance
|
|
||||||
public void testPristineLog() {
|
|
||||||
checkStandard();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test pristine LogFactory instance
|
|
||||||
public void testPristineFactory() {
|
|
||||||
assertNotNull("LogFactory exists", factory);
|
|
||||||
assertEquals("LogFactory class",
|
|
||||||
"org.apache.commons.logging.impl.LogFactoryImpl",
|
|
||||||
factory.getClass().getName());
|
|
||||||
|
|
||||||
final String[] names = factory.getAttributeNames();
|
|
||||||
assertNotNull("Names exists", names);
|
|
||||||
assertEquals("Names empty", 0, names.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test Serializability of standard instance
|
|
||||||
public void testSerializable() throws Exception {
|
|
||||||
|
|
||||||
// Serialize and deserialize the instance
|
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
final ObjectOutputStream oos = new ObjectOutputStream(baos);
|
|
||||||
oos.writeObject(log);
|
|
||||||
oos.close();
|
|
||||||
final ByteArrayInputStream bais =
|
|
||||||
new ByteArrayInputStream(baos.toByteArray());
|
|
||||||
final ObjectInputStream ois = new ObjectInputStream(bais);
|
|
||||||
log = (Log) ois.readObject();
|
|
||||||
ois.close();
|
|
||||||
|
|
||||||
// Check the characteristics of the resulting object
|
|
||||||
checkStandard();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the decorated log instance
|
// Check the decorated log instance
|
||||||
protected void checkDecorated() {
|
protected void checkDecorated() {
|
||||||
@@ -175,7 +101,6 @@ public class DefaultConfigTestCase extends TestCase {
|
|||||||
assertTrue(((DecoratedSimpleLog) log).getShowShortName());
|
assertTrue(((DecoratedSimpleLog) log).getShowShortName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check the standard log instance
|
// Check the standard log instance
|
||||||
protected void checkStandard() {
|
protected void checkStandard() {
|
||||||
assertNotNull("Log exists", log);
|
assertNotNull("Log exists", log);
|
||||||
@@ -195,22 +120,97 @@ public class DefaultConfigTestCase extends TestCase {
|
|||||||
assertEquals(SimpleLog.LOG_LEVEL_INFO, ((SimpleLog) log).getLevel());
|
assertEquals(SimpleLog.LOG_LEVEL_INFO, ((SimpleLog) log).getLevel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set system properties that will control the LogFactory/Log objects
|
||||||
|
* when they are created. Subclasses can override this method to
|
||||||
|
* define properties that suit them.
|
||||||
|
*/
|
||||||
|
public void setProperties() {
|
||||||
|
System.setProperty(
|
||||||
|
"org.apache.commons.logging.Log",
|
||||||
|
"org.apache.commons.logging.impl.SimpleLog");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up instance variables required by this test case.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
LogFactory.releaseAll();
|
||||||
|
setProperties();
|
||||||
|
setUpFactory();
|
||||||
|
setUpLog("TestLogger");
|
||||||
|
}
|
||||||
|
|
||||||
// Set up decorated log instance
|
// Set up decorated log instance
|
||||||
protected void setUpDecorated(final String name) {
|
protected void setUpDecorated(final String name) {
|
||||||
log = new DecoratedSimpleLog(name);
|
log = new DecoratedSimpleLog(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set up factory instance
|
// Set up factory instance
|
||||||
protected void setUpFactory() throws Exception {
|
protected void setUpFactory() throws Exception {
|
||||||
factory = LogFactory.getFactory();
|
factory = LogFactory.getFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set up log instance
|
// Set up log instance
|
||||||
protected void setUpLog(final String name) throws Exception {
|
protected void setUpLog(final String name) throws Exception {
|
||||||
log = LogFactory.getLog(name);
|
log = LogFactory.getLog(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tear down instance variables required by this test case.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void tearDown() {
|
||||||
|
log = null;
|
||||||
|
factory = null;
|
||||||
|
LogFactory.releaseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test pristine DecoratedSimpleLog instance
|
||||||
|
public void testPristineDecorated() {
|
||||||
|
setUpDecorated("DecoratedLogger");
|
||||||
|
checkDecorated();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test pristine LogFactory instance
|
||||||
|
public void testPristineFactory() {
|
||||||
|
assertNotNull("LogFactory exists", factory);
|
||||||
|
assertEquals("LogFactory class",
|
||||||
|
"org.apache.commons.logging.impl.LogFactoryImpl",
|
||||||
|
factory.getClass().getName());
|
||||||
|
|
||||||
|
final String[] names = factory.getAttributeNames();
|
||||||
|
assertNotNull("Names exists", names);
|
||||||
|
assertEquals("Names empty", 0, names.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test pristine Log instance
|
||||||
|
public void testPristineLog() {
|
||||||
|
checkStandard();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test Serializability of standard instance
|
||||||
|
public void testSerializable() throws Exception {
|
||||||
|
|
||||||
|
// Serialize and deserialize the instance
|
||||||
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
final ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
|
oos.writeObject(log);
|
||||||
|
oos.close();
|
||||||
|
final ByteArrayInputStream bais =
|
||||||
|
new ByteArrayInputStream(baos.toByteArray());
|
||||||
|
final ObjectInputStream ois = new ObjectInputStream(bais);
|
||||||
|
log = (Log) ois.readObject();
|
||||||
|
ois.close();
|
||||||
|
|
||||||
|
// Check the characteristics of the resulting object
|
||||||
|
checkStandard();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ public class LogRecord implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -5254831759209770665L;
|
private static final long serialVersionUID = -5254831759209770665L;
|
||||||
|
|
||||||
|
public int type;
|
||||||
|
|
||||||
|
public Object message;
|
||||||
|
public Throwable t;
|
||||||
public LogRecord(final int type, final Object message, final Throwable t) {
|
public LogRecord(final int type, final Object message, final Throwable t) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.t = t;
|
this.t = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int type;
|
|
||||||
public Object message;
|
|
||||||
public Throwable t;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,23 @@ public class MyLog implements Log {
|
|||||||
|
|
||||||
public MyLog(final String category) {}
|
public MyLog(final String category) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(final Object message) {}
|
||||||
|
@Override
|
||||||
|
public void debug(final Object message, final Throwable t) {}
|
||||||
|
@Override
|
||||||
|
public void error(final Object message) {}
|
||||||
|
@Override
|
||||||
|
public void error(final Object message, final Throwable t) {}
|
||||||
|
@Override
|
||||||
|
public void fatal(final Object message) {}
|
||||||
|
@Override
|
||||||
|
public void fatal(final Object message, final Throwable t) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(final Object message) {}
|
||||||
|
@Override
|
||||||
|
public void info(final Object message, final Throwable t) {}
|
||||||
@Override
|
@Override
|
||||||
public boolean isDebugEnabled() { return false; }
|
public boolean isDebugEnabled() { return false; }
|
||||||
@Override
|
@Override
|
||||||
@@ -34,29 +51,12 @@ public class MyLog implements Log {
|
|||||||
public boolean isTraceEnabled() { return false; }
|
public boolean isTraceEnabled() { return false; }
|
||||||
@Override
|
@Override
|
||||||
public boolean isWarnEnabled() { return false; }
|
public boolean isWarnEnabled() { return false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void trace(final Object message) {}
|
public void trace(final Object message) {}
|
||||||
@Override
|
@Override
|
||||||
public void trace(final Object message, final Throwable t) {}
|
public void trace(final Object message, final Throwable t) {}
|
||||||
@Override
|
@Override
|
||||||
public void debug(final Object message) {}
|
|
||||||
@Override
|
|
||||||
public void debug(final Object message, final Throwable t) {}
|
|
||||||
@Override
|
|
||||||
public void info(final Object message) {}
|
|
||||||
@Override
|
|
||||||
public void info(final Object message, final Throwable t) {}
|
|
||||||
@Override
|
|
||||||
public void warn(final Object message) {}
|
public void warn(final Object message) {}
|
||||||
@Override
|
@Override
|
||||||
public void warn(final Object message, final Throwable t) {}
|
public void warn(final Object message, final Throwable t) {}
|
||||||
@Override
|
|
||||||
public void error(final Object message) {}
|
|
||||||
@Override
|
|
||||||
public void error(final Object message, final Throwable t) {}
|
|
||||||
@Override
|
|
||||||
public void fatal(final Object message) {}
|
|
||||||
@Override
|
|
||||||
public void fatal(final Object message, final Throwable t) {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user