Bug 58040 - Log Forging

and marked POILogger/POILogFactory internal

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1686748 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2015-06-21 19:06:32 +00:00
parent f58646196d
commit 48208023fb
6 changed files with 211 additions and 1070 deletions

View File

@ -27,12 +27,10 @@ package org.apache.poi.util;
* @author Glen Stampoultzis (glens at apache.org) * @author Glen Stampoultzis (glens at apache.org)
* @author Nicola Ken Barozzi (nicolaken at apache.org) * @author Nicola Ken Barozzi (nicolaken at apache.org)
*/ */
public class NullLogger extends POILogger public class NullLogger extends POILogger {
{
@Override @Override
public void initialize(final String cat) public void initialize(final String cat){
{ // do nothing
//do nothing
} }
/** /**
@ -45,147 +43,7 @@ public class NullLogger extends POILogger
@Override @Override
public void log(final int level, final Object obj1) public void log(final int level, final Object obj1)
{ {
//do nothing // do nothing
}
/**
* Check if a logger is enabled to log at the specified level
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
*/
@Override
public boolean check(final int level)
{
return false;
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first object to place in the message
* @param obj2 second object to place in the message
*/
@Override
public void log(final int level, final Object obj1, final Object obj2)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
* @param obj5 fifth Object to place in the message
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4, final Object obj5)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
* @param obj5 fifth Object to place in the message
* @param obj6 sixth Object to place in the message
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4, final Object obj5,
final Object obj6)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
* @param obj5 fifth Object to place in the message
* @param obj6 sixth Object to place in the message
* @param obj7 seventh Object to place in the message
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4, final Object obj5,
final Object obj6, final Object obj7)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
* @param obj5 fifth Object to place in the message
* @param obj6 sixth Object to place in the message
* @param obj7 seventh Object to place in the message
* @param obj8 eighth Object to place in the message
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4, final Object obj5,
final Object obj6, final Object obj7, final Object obj8)
{
//do nothing
} }
/** /**
@ -195,289 +53,19 @@ public class NullLogger extends POILogger
* @param obj1 The object to log. This is converted to a string. * @param obj1 The object to log. This is converted to a string.
* @param exception An exception to be logged * @param exception An exception to be logged
*/ */
public void log(int level, Object obj1, final Throwable exception) {
@Override // do nothing
public void log(final int level, final Object obj1,
final Throwable exception)
{
//do nothing
} }
/** /**
* Log a message. Lazily appends Object parameters together. * Check if a logger is enabled to log at the specified level
* *
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param exception An exception to be logged
*/ */
@Override @Override
public void log(final int level, final Object obj1, final Object obj2, public boolean check(final int level) {
final Throwable exception) return false;
{
//do nothing
} }
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param exception An error message to be logged
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Throwable exception)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param exception An exception to be logged
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4,
final Throwable exception)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param obj5 fifth object to place in the message
* @param exception An exception to be logged
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4, final Object obj5,
final Throwable exception)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param obj5 fifth object to place in the message
* @param obj6 sixth object to place in the message
* @param exception An exception to be logged
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4, final Object obj5,
final Object obj6, final Throwable exception)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param obj5 fifth object to place in the message
* @param obj6 sixth object to place in the message
* @param obj7 seventh object to place in the message
* @param exception An exception to be logged
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4, final Object obj5,
final Object obj6, final Object obj7,
final Throwable exception)
{
//do nothing
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param obj5 fifth object to place in the message
* @param obj6 sixth object to place in the message
* @param obj7 seventh object to place in the message
* @param obj8 eighth object to place in the message
* @param exception An exception to be logged
*/
@Override
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3, final Object obj4, final Object obj5,
final Object obj6, final Object obj7, final Object obj8,
final Throwable exception)
{
//do nothing
}
/**
* Logs a formated message. The message itself may contain %
* characters as place holders. This routine will attempt to match
* the placeholder by looking at the type of parameter passed to
* obj1.<p>
*
* If the parameter is an array, it traverses the array first and
* matches parameters sequentially against the array items.
* Otherwise the parameters after <code>message</code> are matched
* in order.<p>
*
* If the place holder matches against a number it is printed as a
* whole number. This can be overridden by specifying a precision
* in the form %n.m where n is the padding for the whole part and
* m is the number of decimal places to display. n can be excluded
* if desired. n and m may not be more than 9.<p>
*
* If the last parameter (after flattening) is a Throwable it is
* logged specially.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param message The message to log.
* @param obj1 The first object to match against.
*/
@Override
public void logFormatted(final int level, final String message,
final Object obj1)
{
//do nothing
}
/**
* Logs a formated message. The message itself may contain %
* characters as place holders. This routine will attempt to match
* the placeholder by looking at the type of parameter passed to
* obj1.<p>
*
* If the parameter is an array, it traverses the array first and
* matches parameters sequentially against the array items.
* Otherwise the parameters after <code>message</code> are matched
* in order.<p>
*
* If the place holder matches against a number it is printed as a
* whole number. This can be overridden by specifying a precision
* in the form %n.m where n is the padding for the whole part and
* m is the number of decimal places to display. n can be excluded
* if desired. n and m may not be more than 9.<p>
*
* If the last parameter (after flattening) is a Throwable it is
* logged specially.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param message The message to log.
* @param obj1 The first object to match against.
* @param obj2 The second object to match against.
*/
@Override
public void logFormatted(final int level, final String message,
final Object obj1, final Object obj2)
{
//do nothing
}
/**
* Logs a formated message. The message itself may contain %
* characters as place holders. This routine will attempt to match
* the placeholder by looking at the type of parameter passed to
* obj1.<p>
*
* If the parameter is an array, it traverses the array first and
* matches parameters sequentially against the array items.
* Otherwise the parameters after <code>message</code> are matched
* in order.<p>
*
* If the place holder matches against a number it is printed as a
* whole number. This can be overridden by specifying a precision
* in the form %n.m where n is the padding for the whole part and
* m is the number of decimal places to display. n can be excluded
* if desired. n and m may not be more than 9.<p>
*
* If the last parameter (after flattening) is a Throwable it is
* logged specially.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param message The message to log.
* @param obj1 The first object to match against.
* @param obj2 The second object to match against.
* @param obj3 The third object to match against.
*/
@Override
public void logFormatted(final int level, final String message,
final Object obj1, final Object obj2,
final Object obj3)
{
//do nothing
}
/**
* Logs a formated message. The message itself may contain %
* characters as place holders. This routine will attempt to match
* the placeholder by looking at the type of parameter passed to
* obj1.<p>
*
* If the parameter is an array, it traverses the array first and
* matches parameters sequentially against the array items.
* Otherwise the parameters after <code>message</code> are matched
* in order.<p>
*
* If the place holder matches against a number it is printed as a
* whole number. This can be overridden by specifying a precision
* in the form %n.m where n is the padding for the whole part and
* m is the number of decimal places to display. n can be excluded
* if desired. n and m may not be more than 9.<p>
*
* If the last parameter (after flattening) is a Throwable it is
* logged specially.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param message The message to log.
* @param obj1 The first object to match against.
* @param obj2 The second object to match against.
* @param obj3 The third object to match against.
* @param obj4 The forth object to match against.
*/
@Override
public void logFormatted(final int level, final String message,
final Object obj1, final Object obj2,
final Object obj3, final Object obj4)
{
//do nothing
}
} }

View File

@ -30,20 +30,18 @@ import java.util.Map;
* @author Marc Johnson (mjohnson at apache dot org) * @author Marc Johnson (mjohnson at apache dot org)
* @author Nicola Ken Barozzi (nicolaken at apache.org) * @author Nicola Ken Barozzi (nicolaken at apache.org)
*/ */
@Internal
public class POILogFactory public final class POILogFactory {
{
/** /**
* Map of POILogger instances, with classes as keys * Map of POILogger instances, with classes as keys
*/ */
private static Map<String,POILogger> _loggers = new HashMap<String,POILogger>();; private static Map<String,POILogger> _loggers = new HashMap<String,POILogger>();
/** /**
* A common instance of NullLogger, as it does nothing * A common instance of NullLogger, as it does nothing
* we only need the one * we only need the one
*/ */
private static POILogger _nullLogger = new NullLogger(); private static final POILogger _nullLogger = new NullLogger();
/** /**
* The name of the class to use. Initialised the * The name of the class to use. Initialised the
* first time we need it * first time we need it
@ -53,9 +51,7 @@ public class POILogFactory
/** /**
* Construct a POILogFactory. * Construct a POILogFactory.
*/ */
private POILogFactory() private POILogFactory() {}
{
}
/** /**
* Get a logger, based on a class name * Get a logger, based on a class name
@ -64,9 +60,7 @@ public class POILogFactory
* *
* @return a POILogger for the specified class * @return a POILogger for the specified class
*/ */
public static POILogger getLogger(final Class<?> theclass) {
public static POILogger getLogger(final Class<?> theclass)
{
return getLogger(theclass.getName()); return getLogger(theclass.getName());
} }
@ -77,9 +71,7 @@ public class POILogFactory
* *
* @return a POILogger for the specified class * @return a POILogger for the specified class
*/ */
public static POILogger getLogger(final String cat) {
public static POILogger getLogger(final String cat)
{
POILogger logger = null; POILogger logger = null;
// If we haven't found out what logger to use yet, // If we haven't found out what logger to use yet,
@ -108,18 +100,18 @@ public class POILogFactory
// Fetch the right logger for them, creating // Fetch the right logger for them, creating
// it if that's required // it if that's required
if (_loggers.containsKey(cat)) {
logger = _loggers.get(cat); logger = _loggers.get(cat);
} else { if (logger == null) {
try { try {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Class<? extends POILogger> loggerClass = Class<? extends POILogger> loggerClass =
(Class<? extends POILogger>)Class.forName(_loggerClassName); (Class<? extends POILogger>) Class.forName(_loggerClassName);
logger = loggerClass.newInstance(); logger = loggerClass.newInstance();
logger.initialize(cat); logger.initialize(cat);
} catch(Exception e) { } catch(Exception e) {
// Give up and use the null logger // Give up and use the null logger
logger = _nullLogger; logger = _nullLogger;
_loggerClassName = _nullLogger.getClass().getName();
} }
// Save for next time // Save for next time
@ -127,4 +119,4 @@ public class POILogFactory
} }
return logger; return logger;
} }
} // end public class POILogFactory }

View File

@ -30,6 +30,7 @@ import java.util.List;
* @author Glen Stampoultzis (glens at apache.org) * @author Glen Stampoultzis (glens at apache.org)
* @author Nicola Ken Barozzi (nicolaken at apache.org) * @author Nicola Ken Barozzi (nicolaken at apache.org)
*/ */
@Internal
public abstract class POILogger { public abstract class POILogger {
public static final int DEBUG = 1; public static final int DEBUG = 1;
@ -49,7 +50,7 @@ public abstract class POILogger {
* package. You need a POILogger? Go to the POILogFactory for one * package. You need a POILogger? Go to the POILogFactory for one
*/ */
POILogger() { POILogger() {
// no fields to initialise // no fields to initialize
} }
abstract public void initialize(String cat); abstract public void initialize(String cat);
@ -60,7 +61,7 @@ public abstract class POILogger {
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 The object to log. This is converted to a string. * @param obj1 The object to log. This is converted to a string.
*/ */
abstract public void log(int level, Object obj1); abstract protected void log(int level, Object obj1);
/** /**
* Log a message * Log a message
@ -69,8 +70,7 @@ public abstract class POILogger {
* @param obj1 The object to log. This is converted to a string. * @param obj1 The object to log. This is converted to a string.
* @param exception An exception to be logged * @param exception An exception to be logged
*/ */
abstract public void log(int level, Object obj1, abstract protected void log(int level, Object obj1, final Throwable exception);
final Throwable exception);
/** /**
@ -82,344 +82,32 @@ public abstract class POILogger {
/** /**
* Log a message. Lazily appends Object parameters together. * Log a message. Lazily appends Object parameters together.
* If the last parameter is a {@link Throwable} it is logged specially.
* *
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first object to place in the message * @param objs the objects to place in the message
* @param obj2 second object to place in the message
*/ */
public void log(int level, Object obj1, Object obj2) public void log(int level, Object... objs) {
{ if (!check(level)) return;
if (check(level)) StringBuilder sb = new StringBuilder(32);
{ Throwable lastEx = null;
log(level, new StringBuffer(32).append(obj1).append(obj2)); for (int i=0; i<objs.length; i++) {
if (i == objs.length-1 && objs[i] instanceof Throwable) {
lastEx = (Throwable)objs[i];
} else {
sb.append(objs[i]);
} }
} }
/** String msg = sb.toString();
* Log a message. Lazily appends Object parameters together. msg = msg.replaceAll("[\r\n]+", " "); // log forging escape
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
*/
public void log(int level, Object obj1, Object obj2,
Object obj3)
{
// somehow this ambiguity works and doesn't lead to a loop,
if (check(level)) // but it's confusing ...
{ if (lastEx == null) {
log(level, log(level, msg);
new StringBuffer(48).append(obj1).append(obj2) } else {
.append(obj3)); log(level, msg, lastEx);
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4)
{
if (check(level))
{
log(level,
new StringBuffer(64).append(obj1).append(obj2)
.append(obj3).append(obj4));
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
* @param obj5 fifth Object to place in the message
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4, Object obj5)
{
if (check(level))
{
log(level,
new StringBuffer(80).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5));
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
* @param obj5 fifth Object to place in the message
* @param obj6 sixth Object to place in the message
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4, Object obj5,
Object obj6)
{
if (check(level))
{
log(level ,
new StringBuffer(96).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5).append(obj6));
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
* @param obj5 fifth Object to place in the message
* @param obj6 sixth Object to place in the message
* @param obj7 seventh Object to place in the message
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4, Object obj5,
Object obj6, Object obj7)
{
if (check(level))
{
log(level,
new StringBuffer(112).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5).append(obj6)
.append(obj7));
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third Object to place in the message
* @param obj4 fourth Object to place in the message
* @param obj5 fifth Object to place in the message
* @param obj6 sixth Object to place in the message
* @param obj7 seventh Object to place in the message
* @param obj8 eighth Object to place in the message
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4, Object obj5,
Object obj6, Object obj7, Object obj8)
{
if (check(level))
{
log(level,
new StringBuffer(128).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5).append(obj6)
.append(obj7).append(obj8));
}
}
/**
* Log an exception, without a message
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param exception An exception to be logged
*/
public void log(int level, final Throwable exception)
{
log(level, null, exception);
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param exception An exception to be logged
*/
public void log(int level, Object obj1, Object obj2,
final Throwable exception)
{
if (check(level))
{
log(level, new StringBuffer(32).append(obj1).append(obj2),
exception);
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param exception An error message to be logged
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, final Throwable exception)
{
if (check(level))
{
log(level, new StringBuffer(48).append(obj1).append(obj2)
.append(obj3), exception);
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param exception An exception to be logged
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4,
final Throwable exception)
{
if (check(level))
{
log(level, new StringBuffer(64).append(obj1).append(obj2)
.append(obj3).append(obj4), exception);
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param obj5 fifth object to place in the message
* @param exception An exception to be logged
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4, Object obj5,
final Throwable exception)
{
if (check(level))
{
log(level, new StringBuffer(80).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5), exception);
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param obj5 fifth object to place in the message
* @param obj6 sixth object to place in the message
* @param exception An exception to be logged
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4, Object obj5,
Object obj6, final Throwable exception)
{
if (check(level))
{
log(level , new StringBuffer(96).append(obj1)
.append(obj2).append(obj3).append(obj4).append(obj5)
.append(obj6), exception);
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param obj5 fifth object to place in the message
* @param obj6 sixth object to place in the message
* @param obj7 seventh object to place in the message
* @param exception An exception to be logged
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4, Object obj5,
Object obj6, Object obj7,
final Throwable exception)
{
if (check(level))
{
log(level, new StringBuffer(112).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5).append(obj6)
.append(obj7), exception);
}
}
/**
* Log a message. Lazily appends Object parameters together.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param obj1 first Object to place in the message
* @param obj2 second Object to place in the message
* @param obj3 third object to place in the message
* @param obj4 fourth object to place in the message
* @param obj5 fifth object to place in the message
* @param obj6 sixth object to place in the message
* @param obj7 seventh object to place in the message
* @param obj8 eighth object to place in the message
* @param exception An exception to be logged
*/
public void log(int level, Object obj1, Object obj2,
Object obj3, Object obj4, Object obj5,
Object obj6, Object obj7, Object obj8,
final Throwable exception)
{
if (check(level))
{
log(level, new StringBuffer(128).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5).append(obj6)
.append(obj7).append(obj8), exception);
} }
} }
@ -445,239 +133,67 @@ public abstract class POILogger {
* *
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param message The message to log. * @param message The message to log.
* @param obj1 The first object to match against. * @param unflatParams... The objects to match against.
*/ */
public void logFormatted(int level, String message, public void logFormatted(int level, String message, Object... unflatParams) {
Object obj1) if (!check(level)) return;
{
commonLogFormatted(level, message, new Object[]
{
obj1
});
}
/**
* Logs a formated message. The message itself may contain %
* characters as place holders. This routine will attempt to match
* the placeholder by looking at the type of parameter passed to
* obj1.<p>
*
* If the parameter is an array, it traverses the array first and
* matches parameters sequentially against the array items.
* Otherwise the parameters after <code>message</code> are matched
* in order.<p>
*
* If the place holder matches against a number it is printed as a
* whole number. This can be overridden by specifying a precision
* in the form %n.m where n is the padding for the whole part and
* m is the number of decimal places to display. n can be excluded
* if desired. n and m may not be more than 9.<p>
*
* If the last parameter (after flattening) is a Throwable it is
* logged specially.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param message The message to log.
* @param obj1 The first object to match against.
* @param obj2 The second object to match against.
*/
public void logFormatted(int level, String message,
Object obj1, Object obj2)
{
commonLogFormatted(level, message, new Object[]
{
obj1, obj2
});
}
/**
* Logs a formated message. The message itself may contain %
* characters as place holders. This routine will attempt to match
* the placeholder by looking at the type of parameter passed to
* obj1.<p>
*
* If the parameter is an array, it traverses the array first and
* matches parameters sequentially against the array items.
* Otherwise the parameters after <code>message</code> are matched
* in order.<p>
*
* If the place holder matches against a number it is printed as a
* whole number. This can be overridden by specifying a precision
* in the form %n.m where n is the padding for the whole part and
* m is the number of decimal places to display. n can be excluded
* if desired. n and m may not be more than 9.<p>
*
* If the last parameter (after flattening) is a Throwable it is
* logged specially.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param message The message to log.
* @param obj1 The first object to match against.
* @param obj2 The second object to match against.
* @param obj3 The third object to match against.
*/
public void logFormatted(int level, String message,
Object obj1, Object obj2,
Object obj3)
{
commonLogFormatted(level, message, new Object[]
{
obj1, obj2, obj3
});
}
/**
* Logs a formated message. The message itself may contain %
* characters as place holders. This routine will attempt to match
* the placeholder by looking at the type of parameter passed to
* obj1.<p>
*
* If the parameter is an array, it traverses the array first and
* matches parameters sequentially against the array items.
* Otherwise the parameters after <code>message</code> are matched
* in order.<p>
*
* If the place holder matches against a number it is printed as a
* whole number. This can be overridden by specifying a precision
* in the form %n.m where n is the padding for the whole part and
* m is the number of decimal places to display. n can be excluded
* if desired. n and m may not be more than 9.<p>
*
* If the last parameter (after flattening) is a Throwable it is
* logged specially.
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
* @param message The message to log.
* @param obj1 The first object to match against.
* @param obj2 The second object to match against.
* @param obj3 The third object to match against.
* @param obj4 The forth object to match against.
*/
public void logFormatted(int level, String message,
Object obj1, Object obj2,
Object obj3, Object obj4)
{
commonLogFormatted(level, message, new Object[]
{
obj1, obj2, obj3, obj4
});
}
private void commonLogFormatted(int level, String message,
Object [] unflatParams)
{
if (check(level))
{
Object[] params = flattenArrays(unflatParams); Object[] params = flattenArrays(unflatParams);
String msg = StringUtil.format(message, params);
msg = msg.replaceAll("[\r\n]+", " "); // log forging escape
if (params[ params.length - 1 ] instanceof Throwable) if (params.length > 0 && params[params.length-1] instanceof Throwable) {
{ log(level, msg, (Throwable)params[params.length-1]);
log(level, StringUtil.format(message, params), } else {
( Throwable ) params[ params.length - 1 ]); log(level, msg);
}
else
{
log(level, StringUtil.format(message, params));
}
} }
} }
/** /**
* Flattens any contained objects. Only tranverses one level deep. * Flattens any contained objects. Only traverses one level deep.
*/ */
private Object [] flattenArrays(Object [] objects) private Object[] flattenArrays(Object... unflatParams) {
{
List<Object> results = new ArrayList<Object>(); List<Object> results = new ArrayList<Object>();
for (Object obj : unflatParams) {
for (int i = 0; i < objects.length; i++) flattenObject(results, obj);
{
results.addAll(objectToObjectArray(objects[ i ]));
} }
return results.toArray(new Object[ results.size() ]); return results.toArray(new Object[results.size()]);
} }
private List<Object> objectToObjectArray(Object object) private void flattenObject(List<Object> results, Object object) {
{ if (object instanceof byte[]) {
List<Object> results = new ArrayList<Object>(); for (byte b : (byte[])object) {
results.add(Byte.valueOf(b));
if (object instanceof byte [])
{
byte[] array = ( byte [] ) object;
for (int j = 0; j < array.length; j++)
{
results.add(Byte.valueOf(array[ j ]));
} }
} else if (object instanceof char[]) {
for (char c : (char[])object) {
results.add(Character.valueOf(c));
} }
if (object instanceof char []) } else if (object instanceof short[]) {
{ for (short s : (short[])object) {
char[] array = ( char [] ) object; results.add(Short.valueOf(s));
for (int j = 0; j < array.length; j++)
{
results.add(Character.valueOf(array[ j ]));
} }
} else if (object instanceof int[]) {
for (int i : (int[])object) {
results.add(Integer.valueOf(i));
} }
else if (object instanceof short []) } else if (object instanceof long[]) {
{ for (long l : (long[])object) {
short[] array = ( short [] ) object; results.add(Long.valueOf(l));
for (int j = 0; j < array.length; j++)
{
results.add(Short.valueOf(array[ j ]));
} }
} else if (object instanceof float[]) {
for (float f : (float[])object) {
results.add(Float.valueOf(f));
} }
else if (object instanceof int []) } else if (object instanceof double[]) {
{ for (double d : (double[])object) {
int[] array = ( int [] ) object; results.add(Double.valueOf(d));
for (int j = 0; j < array.length; j++)
{
results.add(Integer.valueOf(array[ j ]));
} }
} else if (object instanceof Object[]) {
for (Object o : (Object[])object) {
results.add(o);
} }
else if (object instanceof long []) } else {
{
long[] array = ( long [] ) object;
for (int j = 0; j < array.length; j++)
{
results.add(Long.valueOf(array[ j ]));
}
}
else if (object instanceof float [])
{
float[] array = ( float [] ) object;
for (int j = 0; j < array.length; j++)
{
results.add(new Float(array[ j ]));
}
}
else if (object instanceof double [])
{
double[] array = ( double [] ) object;
for (int j = 0; j < array.length; j++)
{
results.add(new Double(array[ j ]));
}
}
else if (object instanceof Object [])
{
Object[] array = ( Object [] ) object;
for (int j = 0; j < array.length; j++)
{
results.add(array[ j ]);
}
}
else
{
results.add(object); results.add(object);
} }
return results;
} }
} }

View File

@ -22,6 +22,7 @@ import java.text.FieldPosition;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.hssf.record.RecordInputStream;
@ -310,7 +311,7 @@ public class StringUtil {
Number number, Number number,
String formatting, String formatting,
StringBuffer outputTo) { StringBuffer outputTo) {
NumberFormat numberFormat = NumberFormat.getInstance(); NumberFormat numberFormat = NumberFormat.getInstance(Locale.US);
if ((0 < formatting.length()) if ((0 < formatting.length())
&& Character.isDigit(formatting.charAt(0))) { && Character.isDigit(formatting.charAt(0))) {
numberFormat.setMinimumIntegerDigits( numberFormat.setMinimumIntegerDigits(

View File

@ -17,30 +17,29 @@
package org.apache.poi.util; package org.apache.poi.util;
import junit.framework.Test; import org.junit.runner.RunWith;
import junit.framework.TestSuite; import org.junit.runners.Suite;
/** /**
* Test suite for all sub-packages of org.apache.poi.util<br/> * Test suite for all sub-packages of org.apache.poi.util<br/>
*/ */
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestArrayUtil.class
, TestBinaryTree.class
, TestBitField.class
, TestByteField.class
, TestHexDump.class
, TestIntegerField.class
, TestIntList.class
, TestLittleEndian.class
, TestLongField.class
, TestPOILogFactory.class
, TestPOILogger.class
, TestShortField.class
, TestShortList.class
, TestStringUtil.class
, TestTempFile.class
})
public final class AllPOIUtilTests { public final class AllPOIUtilTests {
public static Test suite() {
TestSuite result = new TestSuite(AllPOIUtilTests.class.getName());
result.addTestSuite(TestArrayUtil.class);
result.addTestSuite(TestBinaryTree.class);
result.addTestSuite(TestBitField.class);
result.addTestSuite(TestByteField.class);
result.addTestSuite(TestHexDump.class);
result.addTestSuite(TestIntegerField.class);
result.addTestSuite(TestIntList.class);
result.addTestSuite(TestLittleEndian.class);
result.addTestSuite(TestLongField.class);
result.addTestSuite(TestPOILogFactory.class);
result.addTestSuite(TestPOILogger.class);
result.addTestSuite(TestShortField.class);
result.addTestSuite(TestShortList.class);
result.addTestSuite(TestStringUtil.class);
result.addTestSuite(TestTempFile.class);
return result;
}
} }

View File

@ -18,7 +18,13 @@
package org.apache.poi.util; package org.apache.poi.util;
import junit.framework.TestCase; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
import org.junit.Test;
/** /**
* Tests the log class. * Tests the log class.
@ -27,23 +33,62 @@ import junit.framework.TestCase;
* @author Marc Johnson (mjohnson at apache dot org) * @author Marc Johnson (mjohnson at apache dot org)
* @author Nicola Ken Barozzi (nicolaken at apache.org) * @author Nicola Ken Barozzi (nicolaken at apache.org)
*/ */
public final class TestPOILogger extends TestCase { public final class TestPOILogger extends POILogger {
private String lastLog = "";
private Throwable lastEx = null;
/** /**
* Test different types of log output. * Test different types of log output.
*/ */
public void testVariousLogTypes() { @Test
//NKB Testing only that logging classes use gives no exception public void testVariousLogTypes() throws Exception {
// Since logging can be disabled, no checking of logging Field f = POILogFactory.class.getDeclaredField("_loggerClassName");
// output is done. f.setAccessible(true);
String oldLCN = (String)f.get(null);
try {
f.set(null, TestPOILogger.class.getName());
POILogger log = POILogFactory.getLogger( "foo" ); POILogger log = POILogFactory.getLogger( "foo" );
assertTrue(log instanceof TestPOILogger);
log.log( POILogger.WARN, "Test = ", Integer.valueOf( 1 ) ); TestPOILogger tlog = (TestPOILogger)log;
log.logFormatted( POILogger.ERROR, "Test param 1 = %, param 2 = %", "2", Integer.valueOf( 3 ) );
log.logFormatted( POILogger.ERROR, "Test param 1 = %, param 2 = %", new int[]{4, 5} );
log.logFormatted( POILogger.ERROR,
"Test param 1 = %1.1, param 2 = %0.1", new double[]{4, 5.23} );
log.log(POILogger.WARN, "Test = ", 1);
assertEquals("Test = 1", tlog.lastLog);
log.logFormatted(POILogger.ERROR, "Test param 1 = %, param 2 = %d", "2", 3 );
assertEquals("Test param 1 = 2, param 2 = 3", tlog.lastLog);
log.logFormatted(POILogger.ERROR, "Test param 1 = %d, param 2 = %", new int[]{4, 5} );
assertEquals("Test param 1 = 4, param 2 = 5", tlog.lastLog);
log.logFormatted(POILogger.ERROR, "Test param 1 = %1.1, param 2 = %0.1", new double[]{4, 5.23} );
assertEquals("Test param 1 = 4, param 2 = 5.2", tlog.lastLog);
log.log(POILogger.ERROR, "Test ", 1,2,new Exception("bla"));
assertEquals("Test 12", tlog.lastLog);
assertNotNull(tlog.lastEx);
log.log(POILogger.ERROR, "log\nforging", "\nevil","\nlog");
assertEquals("log forging evil log", tlog.lastLog);
} finally {
f.set(null, oldLCN);
}
}
public void initialize(String cat) {
}
public void log(int level, Object obj1) {
lastLog = (obj1 == null) ? "" : obj1.toString();
lastEx = null;
}
public void log(int level, Object obj1, Throwable exception) {
lastLog = (obj1 == null) ? "" : obj1.toString();
lastEx = exception;
}
public boolean check(int level) {
return true;
} }
} }