Author: vgritsenko Date: Thu Mar 24 14:36:31 2005 New Revision: 158963 URL: http://svn.apache.org/viewcvs?view=rev&rev=158963 Log: Bug# 5978: Don't fail under SecurityManager
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java?view=diff&r1=158962&r2=158963 ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java (original) +++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java Thu Mar 24 14:36:31 2005 @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,20 +29,22 @@ import org.apache.log.Logger; /** - * An extended pattern formatter. New patterns are defined by this class are : + * An extended pattern formatter. New patterns defined by this class are: * <ul> - * <li><code>class</code> : outputs the name of the class that has logged the + * <li><code>class</code>: Outputs the name of the class that has logged the * message. The optional <code>short</code> subformat removes the - * package name. Warning : this pattern works only if formatting occurs in + * package name. Warning: This pattern works only if formatting occurs in * the same thread as the call to Logger, i.e. it won't work with * <code>AsyncLogTarget</code>.</li> - * <li><code>thread</code> : outputs the name of the current thread (first element + * <li><code>uri</code>: Outputs the request URI.<li> + * <li><code>thread</code>: Outputs the name of the current thread (first element * on the context stack).</li> - * <li><code>uri</code> : outputs the request URI.<li> + * <li><code>host</code>: Outputs the request host header.<li> * </ul> * * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a> - * @version CVS $Id$ + * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a> + * @version $Id$ */ public class CocoonLogFormatter extends ExtensiblePatternFormatter { @@ -64,14 +66,14 @@ protected final static String TYPE_THREAD_STR = "thread"; protected final static String TYPE_HOST_STR = "host"; - protected final SimpleDateFormat dateFormatter = new SimpleDateFormat("(yyyy-MM-dd) HH:mm.ss:SSS"); + protected final static SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("(yyyy-MM-dd) HH:mm.ss:SSS"); /** * Hack to get the call stack as an array of classes. The * SecurityManager class provides it as a protected method, so * change it to public through a new method ! */ - static public class CallStack extends SecurityManager { + static class CallStack extends SecurityManager { /** * Returns the current execution stack as an array of classes. * The length of the array is the number of methods on the execution @@ -90,31 +92,40 @@ * The class that we will search for in the call stack * (Avalon logging abstraction) */ - private Class logkitClass = LogKitLogger.class; + private final Class logkitClass = LogKitLogger.class; /** * The class that we will search for in the call stack * (LogKit logger) */ - private Class loggerClass = Logger.class; + private final Class loggerClass = Logger.class; - private CallStack callStack = new CallStack(); + /** + * The SecurityManager implementation which gives us access to + * the stack frame + */ + private CallStack callStack; - //The depth to which stacktraces are printed out + /** + * The depth to which stacktraces are printed out + */ private final int m_stackDepth; - public CocoonLogFormatter() - { - this( DEFAULT_STACK_DEPTH ); + + public CocoonLogFormatter() { + this(DEFAULT_STACK_DEPTH); } - public CocoonLogFormatter( int stackDepth ) - { - m_stackDepth = stackDepth; + public CocoonLogFormatter(int stackDepth) { + try { + this.callStack = new CallStack(); + } catch (SecurityException e) { + // Ignore security exception + } + this.m_stackDepth = stackDepth; } protected int getTypeIdFor(String type) { - // Search for new patterns defined here, or else delegate // to the parent class if (type.equalsIgnoreCase(TYPE_CLASS_STR)) { @@ -134,13 +145,13 @@ // Format new patterns defined here, or else delegate to // the parent class switch (run.m_type) { - case TYPE_CLASS : + case TYPE_CLASS: return getClass(run.m_format); - case TYPE_URI : + case TYPE_URI: return getURI(event.getContextMap()); - case TYPE_THREAD : + case TYPE_THREAD: return getThread(event.getContextMap()); - case TYPE_HOST : + case TYPE_HOST: return getHost(event.getContextMap()); } return super.formatPatternRun(event, run); @@ -150,84 +161,89 @@ * Finds the class that has called Logger. */ private String getClass(String format) { - Class[] stack = this.callStack.get(); + if (this.callStack != null) { + Class[] stack = this.callStack.get(); - // Traverse the call stack in reverse order until we find a Logger - for (int i = stack.length - 1; i >= 0; i--) { - if (this.logkitClass.isAssignableFrom(stack[i]) || - this.loggerClass.isAssignableFrom(stack[i])) { - // Found : the caller is the previous stack element - String className = stack[i+1].getName(); - // Handle optional format - if (TYPE_CLASS_SHORT_STR.equalsIgnoreCase(format)) { - className = ClassUtils.getShortClassName(className); + // Traverse the call stack in reverse order until we find a Logger + for (int i = stack.length - 1; i >= 0; i--) { + if (this.logkitClass.isAssignableFrom(stack[i]) || + this.loggerClass.isAssignableFrom(stack[i])) { + // Found: the caller is the previous stack element + String className = stack[i + 1].getName(); + // Handle optional format + if (TYPE_CLASS_SHORT_STR.equalsIgnoreCase(format)) { + className = ClassUtils.getShortClassName(className); + } + return className; } - return className; } } - // No Logger found in call stack : can occur with AsyncLogTarget + + // No callStack: can occur when running under SecurityManager, or + // no logger found in call stack: can occur with AsyncLogTarget // where formatting takes place in a different thread. - return "Unknown-class"; + return "Unknown-Class"; } /** * Find the URI that is being processed. */ private String getURI(ContextMap ctxMap) { - String result = "Unknown-URI"; - // Get URI from the the object model. if (ctxMap != null) { - Object context = ctxMap.get("objectModel"); + final Object context = ctxMap.get("objectModel"); if (context != null && context instanceof Map) { // Get the request - Request request = ObjectModelHelper.getRequest((Map)context); + final Request request = ObjectModelHelper.getRequest((Map) context); if (request != null) { - result = request.getRequestURI(); + return request.getRequestURI(); } } } - return result; + + return "Unknown-URI"; } /** * Find the host header of the request that is being processed. */ private String getHost(ContextMap ctxMap) { - String result = "Unknown-host"; - // Get URI from the the object model. if (ctxMap != null) { - Object context = ctxMap.get("objectModel"); + final Object context = ctxMap.get("objectModel"); if (context != null && context instanceof Map) { // Get the request - Request request = ObjectModelHelper.getRequest((Map)context); + final Request request = ObjectModelHelper.getRequest((Map) context); if (request != null) { - result = request.getHeader("host"); + return request.getHeader("host"); } } } - return result; - } + return "Unknown-Host"; + } /** * Find the thread that is logged this event. */ private String getThread(ContextMap ctxMap) { - if (ctxMap != null && ctxMap.get("threadName") != null) { - return (String)ctxMap.get("threadName"); - } else { - return "Unknown-thread"; + // Get thread name from the context. + if (ctxMap != null) { + final String threadName = (String) ctxMap.get("threadName"); + if (threadName != null) { + return threadName; + } } + + return "Unknown-Thread"; } /** * Utility method to format stack trace so that CascadingExceptions are * formatted with all nested exceptions. * - * FIXME : copied from AvalonFormatter, to be removed if ExtensiblePatternFormatter - * replaces PatternFormatter. + * <p>FIXME: copied from AvalonFormatter, to be removed if ExtensiblePatternFormatter + * replaces PatternFormatter.</p> * * @param throwable the throwable instance * @param format ancilliary format parameter - allowed to be null @@ -236,9 +252,9 @@ protected String getStackTrace(final Throwable throwable, final String format) { if (throwable != null) { return ExceptionUtil.printStackTrace(throwable, m_stackDepth); - } else { - return null; } + + return null; } /** @@ -249,6 +265,6 @@ * @return the formatted string */ protected String getTime(final long time, final String format) { - return this.dateFormatter.format(new Date()); + return DATE_FORMATTER.format(new Date()); } }