Hi,

Robert: thanks for committing the plugins Exception patch.

Here is a patch to convert the Plugins module logging to always use the
Log object returned by digester.getLogger().

I still think that the way Digester centralizes logging is flawed.
However I have more interest in getting plugins finished than debating
logging, so this patch should resolve any arguments for the moment.

Maybe sometime later I will think about the logging issue and put
forward a more concrete proposal. At least now I think I understand the
requirements that led to the current implementation.

As the governor of California would say, "I'll be back".. :-)

Regards,

Simon

PS: I hope I've got the right licence header on new file LogUtils.java
this time!
/*
 * $Header: $
 * $Revision: $
 * $Date: $
 *
 * ====================================================================
 * 
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgement may appear in the software itself,
 *    if and wherever such third-party acknowledgements normally appear.
 *
 * 4. The names "Apache", "The Jakarta Project", "Commons", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache" nor may "Apache" appear in their names without prior 
 *    written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 
package org.apache.commons.digester.plugins;

import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;

/**
 * Simple utility class to assist in logging.
 * <p>
 * The Digester module has an interesting approach to logging:
 * all logging should be done via the Log object stored on the
 * digester instance that the object *doing* the logging is associated
 * with.
 * <p>
 * This is done because apparently some "container"-type applications
 * such as Avalon and Tomcat need to be able to configure different logging
 * for different <i>instances</i> of the Digester class which have been
 * loaded from the same ClassLoader [info from Craig McClanahan]. 
 * Not only the logging of the Digester instance should be affected; all 
 * objects associated with that Digester instance should obey the 
 * reconfiguration of their owning Digester instance's logging. The current 
 * solution is to force all objects to output logging info via a single 
 * Log object stored on the Digester instance they are associated with.
 * <p>
 * Of course this causes problems if logging is attempted before an
 * object <i>has</i> a valid reference to its owning Digester. The 
 * getLogging method provided here resolves this issue by returning a
 * Log object which silently discards all logging output in this
 * situation.
 * <p>
 * And it also implies that logging filtering can no longer be applied
 * to subcomponents of the Digester, because all logging is done via
 * a single Log object (a single Category). C'est la vie...
 * 
 * @author Simon Kitching
 */

public class LogUtils {
    
  /**
   * Get the Log object associated with the specified Digester instance,
   * or a "no-op" logging object if the digester reference is null.
   * <p>
   * You should use this method instead of digester.getLogger() in
   * any situation where the digester might be null.
   */
  public static Log getLogger(Digester digester) {
    if (digester == null) {
        return new org.apache.commons.logging.impl.NoOpLog();
    }
    
    return digester.getLogger();
  }
}
? LogUtils.java
Index: Declaration.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/digester/src/java/org/apache/commons/digester/plugins/Declaration.java,v
retrieving revision 1.4
diff -u -r1.4 Declaration.java
--- Declaration.java	27 Oct 2003 13:37:35 -0000	1.4
+++ Declaration.java	27 Oct 2003 22:14:01 -0000
@@ -69,7 +69,6 @@
 import org.apache.commons.beanutils.MethodUtils;
 import org.apache.commons.digester.Digester;
 import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Simple structure to store the set of attributes that can be present on 
@@ -78,7 +77,6 @@
  * @author Simon Kitching
  */
 public class Declaration {
-    private static Log log = LogFactory.getLog(Declaration.class);
 
     /** 
      * The name of the method looked for on the plugin class and any
@@ -225,7 +223,11 @@
      */
     public void init(Digester digester)
     throws PluginWrappedException {
-        log.debug("init being called!");
+        Log log = digester.getLogger();
+        boolean debug = log.isDebugEnabled();
+        if (debug) {
+            log.debug("init being called!");
+        }
         
         if (initialised_) {
             throw new PluginAssertionError("Init called multiple times.");
@@ -292,7 +294,11 @@
      
     public void configure(Digester digester, String pattern)
     throws PluginWrappedException {
-        log.debug("configure being called!");
+        Log log = digester.getLogger();
+        boolean debug = log.isDebugEnabled();
+        if (debug) {
+            log.debug("configure being called!");
+        }
         
         if (!initialised_) {
             throw new PluginAssertionError("Not initialised.");
@@ -350,7 +356,7 @@
 
         // look for rule class
         {
-            if (log.isDebugEnabled()) {
+            if (debug) {
                 log.debug("plugin class type:" + pluginClass_.getName());
             }
             String ruleClassName = pluginClass_.getName() + "RuleInfo";
@@ -385,7 +391,7 @@
         
         // try autoSetProperties
         if (autoSetProperties_) {
-            if (log.isDebugEnabled()) {
+            if (debug) {
                 log.debug("adding autoset for pattern [" + pattern + "]");
             }
             digester.addSetProperties(pattern);
@@ -410,6 +416,7 @@
                 is.close();
             }
             catch(IOException ioe) {
+                Log log = digester.getLogger();
                 log.warn("Unable to close stream after reading rules", ioe);
             }
         }
Index: PluginCreateRule.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/digester/src/java/org/apache/commons/digester/plugins/PluginCreateRule.java,v
retrieving revision 1.4
diff -u -r1.4 PluginCreateRule.java
--- PluginCreateRule.java	27 Oct 2003 13:37:35 -0000	1.4
+++ PluginCreateRule.java	27 Oct 2003 22:14:02 -0000
@@ -70,7 +70,6 @@
 import org.apache.commons.digester.Rule;
 import org.apache.commons.digester.Rules;
 import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Allows the original rules for parsing the configuration file to define
@@ -81,8 +80,6 @@
  */
 public class PluginCreateRule extends Rule implements InitializableRule {
 
-    private static Log log = LogFactory.getLog(PluginCreateRule.class);
-
     private static final String PLUGIN_CLASS_ATTR = "plugin-class";
     private static final String PLUGIN_ID_ATTR = "plugin-id";
     
@@ -195,8 +192,12 @@
      */
     public void postRegisterInit(String pattern)
     throws PluginConfigurationException {
-        log.debug("PluginCreateRule.postRegisterInit" + 
-                  ": rule registered for pattern [" + pattern + "]");
+        Log log = LogUtils.getLogger(digester);
+        boolean debug = log.isDebugEnabled();
+        if (debug) {
+            log.debug("PluginCreateRule.postRegisterInit" + 
+                      ": rule registered for pattern [" + pattern + "]");
+        }
 
         if (digester == null) {
             // We require setDigester to be called before this method.
@@ -300,7 +301,9 @@
     String namespace, String name, 
     org.xml.sax.Attributes attributes)
     throws java.lang.Exception {
-        if (log.isDebugEnabled()) {
+        Log log = digester.getLogger();
+        boolean debug = log.isDebugEnabled();
+        if (debug) {
             log.debug("PluginCreateRule.begin" + ": pattern=[" + pattern_ + "]" + 
                   " match=[" + digester.getMatch() + "]");
         }
@@ -325,7 +328,7 @@
             PluginManager pluginManager = localRules_.getPluginManager();
             Declaration currDeclaration = null;
             
-            if (log.isDebugEnabled()) {
+            if (debug) {
                 log.debug("PluginCreateRule.begin: installing new plugin: " 
                     + "oldrules=" + oldRules.toString()
                     + ", localrules=" + localRules_.toString());
@@ -376,7 +379,7 @@
                 
                 Object instance = pluginClass.newInstance();
                 getDigester().push(instance);
-                if (log.isDebugEnabled()) {
+                if (debug) {
                     log.debug(
                         "PluginCreateRule.begin" + ": pattern=[" + pattern_ + "]" + 
                         " match=[" + digester.getMatch() + "]" + 
@@ -391,7 +394,7 @@
         // fire the begin method of all custom rules
         Rules oldRules = digester.getRules();
         
-        if (log.isDebugEnabled()) {
+        if (debug) {
             log.debug("PluginCreateRule.begin: firing nested rules: " 
                 + "oldrules=" + oldRules.toString()
                 + ", localrules=" + localRules_.toString());
@@ -402,7 +405,7 @@
         delegateBegin(namespace, name, attributes);
         digester.setRules(oldRules);
 
-        if (log.isDebugEnabled()) {
+        if (debug) {
             log.debug("PluginCreateRule.begin: restored old rules to " 
                 + "oldrules=" + oldRules.toString());
         }
@@ -491,6 +494,7 @@
     throws java.lang.Exception {
         
         // Fire "begin" events for all relevant rules
+        Log log = digester.getLogger();
         boolean debug = log.isDebugEnabled();
         String match = digester.getMatch();
         List rules = digester.getRules().match(namespace, match);
@@ -510,6 +514,7 @@
     public void delegateBody(String namespace, String name, String text)
     throws Exception {
         // Fire "body" events for all relevant rules
+        Log log = digester.getLogger();
         boolean debug = log.isDebugEnabled();
         String match = digester.getMatch();
         List rules = digester.getRules().match(namespace, match);
@@ -529,6 +534,7 @@
     public void delegateEnd(String namespace, String name)
     throws Exception {
         // Fire "end" events for all relevant rules in reverse order
+        Log log = digester.getLogger();
         boolean debug = log.isDebugEnabled();
         String match = digester.getMatch();
         List rules = digester.getRules().match(namespace, match);
Index: PluginDeclarationRule.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/digester/src/java/org/apache/commons/digester/plugins/PluginDeclarationRule.java,v
retrieving revision 1.4
diff -u -r1.4 PluginDeclarationRule.java
--- PluginDeclarationRule.java	27 Oct 2003 13:37:35 -0000	1.4
+++ PluginDeclarationRule.java	27 Oct 2003 22:14:02 -0000
@@ -68,7 +68,6 @@
 import org.apache.commons.beanutils.MethodUtils;
 
 import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * A Digester rule which allows the user to pre-declare a class which is to
@@ -82,7 +81,6 @@
  */
 
 public class PluginDeclarationRule extends Rule {
-    private static Log log = LogFactory.getLog(PluginDeclarationRule.class);
 
     //------------------- constructors ---------------------------------------
 
@@ -114,6 +112,10 @@
             String name,
             org.xml.sax.Attributes attributes)
              throws java.lang.Exception {
+                 
+        Log log = digester.getLogger();
+        boolean debug = log.isDebugEnabled();
+        
         String id = attributes.getValue("id");
         String pluginClassName = attributes.getValue("class");
         String ruleMethodName = attributes.getValue("method");
@@ -122,7 +124,7 @@
         String ruleFile = attributes.getValue("file");
         String autoSetPropertiesStr = attributes.getValue("setprops");
 
-        if (log.isDebugEnabled()) {
+        if (debug) {
             log.debug(
                 "mapping id [" + id + "] -> [" + pluginClassName + "]");
         }
@@ -184,7 +186,9 @@
                 // the same external file at multiple locations within a
                 // parent document. if the declaration is identical,
                 // then we just ignore it.
-                log.debug("plugin redeclaration is identical: ignoring");
+                if (debug) {
+                    log.debug("plugin redeclaration is identical: ignoring");
+                }
                 return;
             } else {
                 throw new PluginInvalidInputException(
Index: PluginManager.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/digester/src/java/org/apache/commons/digester/plugins/PluginManager.java,v
retrieving revision 1.3
diff -u -r1.3 PluginManager.java
--- PluginManager.java	9 Oct 2003 21:09:48 -0000	1.3
+++ PluginManager.java	27 Oct 2003 22:14:02 -0000
@@ -66,7 +66,6 @@
 import org.apache.commons.digester.Digester;
 
 import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Coordinates between PluginDeclarationRule and PluginCreateRule objects,
@@ -79,7 +78,6 @@
  */
 
 public class PluginManager {
-    private static Log log = LogFactory.getLog(PluginManager.class);
 
     /** Map of classname->Declaration */
     private HashMap declarationsByClass_ = new HashMap();
@@ -89,7 +87,7 @@
 
     /** the parent manager to which this one may delegate lookups. */
     private PluginManager parent_;
-    
+
     //------------------- constructors ---------------------------------------
     
     /** Constructor. */
@@ -105,10 +103,17 @@
 
     /**
      * Add the declaration to the set of known declarations.
+     * <p>
+     * TODO: somehow get a reference to a Digester object
+     * so that we can really log here. Currently, all
+     * logging is disabled from this method.
      *
      [EMAIL PROTECTED] decl an object representing a plugin class.
      */
     public void addDeclaration(Declaration decl) {
+        Log log = LogUtils.getLogger(null);
+        boolean debug = log.isDebugEnabled();
+        
         Class pluginClass = decl.getPluginClass();
         String id = decl.getId();
         
@@ -116,7 +121,7 @@
             
         if (id != null) {
             declarationsById_.put(id, decl);
-            if (log.isDebugEnabled()) {
+            if (debug) {
                 log.debug(
                     "Indexing plugin-id [" + id + "]"
                     + " -> class [" + pluginClass.getName() + "]");
Index: PluginRules.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/digester/src/java/org/apache/commons/digester/plugins/PluginRules.java,v
retrieving revision 1.3
diff -u -r1.3 PluginRules.java
--- PluginRules.java	9 Oct 2003 21:09:48 -0000	1.3
+++ PluginRules.java	27 Oct 2003 22:14:02 -0000
@@ -75,7 +75,6 @@
 import org.apache.commons.digester.Rules;
 import org.apache.commons.digester.RulesBase;
 import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * A custom digester Rules manager which must be used as the Rules object
@@ -85,7 +84,6 @@
  */
 
 public class PluginRules implements Rules {
-    private static Log log = LogFactory.getLog(PluginRules.class);
                                                
     /** 
      * The rules implementation that we are "enhancing" with plugins
@@ -230,10 +228,14 @@
      * @param rule Rule instance to be registered
      */
     public void add(String pattern, Rule rule) {
-        if (log.isDebugEnabled()) {
+        Log log = LogUtils.getLogger(digester_);
+        boolean debug = log.isDebugEnabled();
+        
+        if (debug) {
             log.debug("add entry" + ": mapping pattern [" + pattern + "]" + 
                   " to rule of type [" + rule.getClass().getName() + "]");
         }
+        
         decoratedRules_.add(pattern, rule);
 
         if (rule instanceof InitializableRule) {
@@ -245,13 +247,15 @@
                 // initialisable rule to remember that its initialisation
                 // failed, and to throw the exception when begin is
                 // called for the first time.
-                log.debug("Rule initialisation failed", e);
+                if (debug) {
+                    log.debug("Rule initialisation failed", e);
+                }
                 // throw e; -- alas, can't do this
                 return;
             }
         }
         
-        if (log.isDebugEnabled()) {
+        if (debug) {
             log.debug("add exit" + ": mapped pattern [" + pattern + "]" + 
                   " to rule of type [" + rule.getClass().getName() + "]");
         }
@@ -298,16 +302,20 @@
      * @param pattern Nesting pattern to be matched
      */
     public List match(String namespaceURI, String pattern) {
-        if (log.isDebugEnabled()) {
+        Log log = LogUtils.getLogger(digester_);
+        boolean debug = log.isDebugEnabled();
+        
+        if (debug) {
             log.debug(
                 "Matching pattern [" + pattern 
                 + "] on rules object " + this.toString());
         }
+
         List matches;
         if ((currPluginCreateRule_ != null) && 
             (pattern.length() > currPluginCreateRule_.getPattern().length())) {
             // assert pattern.startsWith(currPluginCreateRule.getPattern())
-            if (log.isDebugEnabled()) {
+            if (debug) {
                 log.debug(
                     "Pattern [" + pattern + "] matching PluginCreateRule " 
                     + currPluginCreateRule_.toString());
@@ -332,15 +340,20 @@
      * endPlugin method is called.
      */
     public void beginPlugin(PluginCreateRule pcr) {
+        Log log = LogUtils.getLogger(digester_);
+        boolean debug = log.isDebugEnabled();
+
         if (currPluginCreateRule_ != null) {
             throw new PluginAssertionError(
                 "endPlugin called when currPluginCreateRule_ is not null.");
         }
-        if (log.isDebugEnabled()) {
+
+        if (debug) {
             log.debug(
                 "Entering PluginCreateRule " + pcr.toString() 
                 + " on rules object " + this.toString());
         }
+
         currPluginCreateRule_ = pcr;
     }
     
@@ -349,6 +362,9 @@
      * See [EMAIL PROTECTED] #beginPlugin}.
      */
     public void endPlugin(PluginCreateRule pcr) {
+        Log log = LogUtils.getLogger(digester_);
+        boolean debug = log.isDebugEnabled();
+
         if (currPluginCreateRule_ == null) {
             throw new PluginAssertionError(
                 "endPlugin called when currPluginCreateRule_ is null.");
@@ -360,7 +376,7 @@
         }
         
         currPluginCreateRule_ = null;
-        if (log.isDebugEnabled()) {
+        if (debug) {
             log.debug(
                 "Leaving PluginCreateRule " + pcr.toString()
                 + " on rules object " + this.toString());

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to