ceki        2005/01/12 07:04:21

  Modified:    src/java/org/apache/log4j/joran/action LevelAction.java
                        ConversionRuleAction.java LoggerAction.java
                        AppenderRefAction.java AppenderAction.java
                        PropertyAction.java RootLoggerAction.java
                        LayoutAction.java
                        JndiSubstitutionPropertyAction.java
                        PriorityAction.java PluginAction.java
                        SubstitutionPropertyAction.java
                        RepositoryPropertyAction.java
                        ConfigurationAction.java
               src/java/org/apache/log4j/joran JoranConfigurator.java
  Added:       src/java/org/apache/log4j/joran/action ImplicitAction.java
                        NewRuleAction.java Action.java NestComponentIA.java
                        ParamAction.java
               src/java/org/apache/log4j/joran/spi Pattern.java
                        RuleStore.java Interpreter.java
                        ExecutionContext.java SimpleRuleStore.java
  Removed:     src/java/org/apache/joran ExecutionContext.java
                        RuleStore.java Interpreter.java Pattern.java
               src/java/org/apache/joran/action NewRuleAction.java
                        Action.java ParamAction.java NestComponentIA.java
                        ImplicitAction.java
               src/java/org/apache/joran/helper SimpleRuleStore.java
  Log:
  Since Joran depends on log4j classes, no use pretending that it is an 
independedt package.
  
  Revision  Changes    Path
  1.14      +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/LevelAction.java
  
  Index: LevelAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/LevelAction.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- LevelAction.java  8 Jan 2005 14:05:28 -0000       1.13
  +++ LevelAction.java  12 Jan 2005 15:04:18 -0000      1.14
  @@ -1,12 +1,11 @@
   package org.apache.log4j.joran.action;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   
   import org.apache.log4j.Level;
   import org.apache.log4j.Logger;
   import org.apache.log4j.helpers.Loader;
   import org.apache.log4j.helpers.OptionConverter;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.ErrorItem;
   
   import org.xml.sax.Attributes;
  
  
  
  1.13      +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/ConversionRuleAction.java
  
  Index: ConversionRuleAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/ConversionRuleAction.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ConversionRuleAction.java 28 Dec 2004 23:08:12 -0000      1.12
  +++ ConversionRuleAction.java 12 Jan 2005 15:04:18 -0000      1.13
  @@ -19,12 +19,11 @@
   import java.util.HashMap;
   import java.util.Map;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   import org.apache.joran.helper.Option;
   
   import org.apache.log4j.Layout;
   import org.apache.log4j.PatternLayout;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.ErrorItem;
   import org.apache.log4j.spi.LoggerRepository;
   
  
  
  
  1.11      +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/LoggerAction.java
  
  Index: LoggerAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/LoggerAction.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- LoggerAction.java 28 Dec 2004 16:33:57 -0000      1.10
  +++ LoggerAction.java 12 Jan 2005 15:04:18 -0000      1.11
  @@ -16,13 +16,12 @@
   
   package org.apache.log4j.joran.action;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   import org.apache.joran.helper.Option;
   
   import org.apache.log4j.Logger;
   import org.apache.log4j.helpers.Loader;
   import org.apache.log4j.helpers.OptionConverter;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.ErrorItem;
   import org.apache.log4j.spi.LoggerRepository;
   
  
  
  
  1.16      +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/AppenderRefAction.java
  
  Index: AppenderRefAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/AppenderRefAction.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- AppenderRefAction.java    28 Dec 2004 16:33:57 -0000      1.15
  +++ AppenderRefAction.java    12 Jan 2005 15:04:18 -0000      1.16
  @@ -16,13 +16,12 @@
   
   package org.apache.log4j.joran.action;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   import org.apache.joran.helper.Option;
   
   import org.apache.log4j.Appender;
   import org.apache.log4j.Logger;
   import org.apache.log4j.helpers.Constants;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.AppenderAttachable;
   import org.apache.log4j.spi.ErrorItem;
   
  
  
  
  1.17      +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/AppenderAction.java
  
  Index: AppenderAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/AppenderAction.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- AppenderAction.java       8 Jan 2005 14:05:28 -0000       1.16
  +++ AppenderAction.java       12 Jan 2005 15:04:18 -0000      1.17
  @@ -16,12 +16,11 @@
   
   package org.apache.log4j.joran.action;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   import org.apache.joran.helper.Option;
   
   import org.apache.log4j.Appender;
   import org.apache.log4j.helpers.OptionConverter;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.ErrorItem;
   import org.apache.log4j.spi.LoggerRepository;
   import org.apache.log4j.spi.OptionHandler;
  
  
  
  1.9       +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/PropertyAction.java
  
  Index: PropertyAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/PropertyAction.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- PropertyAction.java       28 Dec 2004 16:33:57 -0000      1.8
  +++ PropertyAction.java       12 Jan 2005 15:04:18 -0000      1.9
  @@ -16,11 +16,10 @@
   
   package org.apache.log4j.joran.action;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   import org.apache.joran.helper.Option;
   
   import org.apache.log4j.helpers.OptionConverter;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.ErrorItem;
   
   import org.xml.sax.Attributes;
  
  
  
  1.10      +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/RootLoggerAction.java
  
  Index: RootLoggerAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/RootLoggerAction.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- RootLoggerAction.java     28 Dec 2004 16:33:57 -0000      1.9
  +++ RootLoggerAction.java     12 Jan 2005 15:04:18 -0000      1.10
  @@ -16,10 +16,9 @@
   
   package org.apache.log4j.joran.action;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   
   import org.apache.log4j.Logger;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.LoggerRepository;
   
   import org.xml.sax.Attributes;
  
  
  
  1.16      +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/LayoutAction.java
  
  Index: LayoutAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/LayoutAction.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- LayoutAction.java 8 Jan 2005 14:05:28 -0000       1.15
  +++ LayoutAction.java 12 Jan 2005 15:04:18 -0000      1.16
  @@ -16,12 +16,11 @@
   
   package org.apache.log4j.joran.action;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   
   import org.apache.log4j.Appender;
   import org.apache.log4j.Layout;
   import org.apache.log4j.helpers.OptionConverter;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.ErrorItem;
   import org.apache.log4j.spi.LoggerRepository;
   import org.apache.log4j.spi.OptionHandler;
  
  
  
  1.3       +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/JndiSubstitutionPropertyAction.java
  
  Index: JndiSubstitutionPropertyAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/JndiSubstitutionPropertyAction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- JndiSubstitutionPropertyAction.java       7 Dec 2004 20:18:14 -0000       
1.2
  +++ JndiSubstitutionPropertyAction.java       12 Jan 2005 15:04:18 -0000      
1.3
  @@ -20,8 +20,7 @@
   import javax.naming.NamingException;
   import javax.naming.InitialContext;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.ErrorItem;
   
   import org.xml.sax.Attributes;
  
  
  
  1.3       +1 -1      
logging-log4j/src/java/org/apache/log4j/joran/action/PriorityAction.java
  
  Index: PriorityAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/PriorityAction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PriorityAction.java       20 Nov 2004 12:47:06 -0000      1.2
  +++ PriorityAction.java       12 Jan 2005 15:04:18 -0000      1.3
  @@ -2,7 +2,7 @@
   
   
   
  -import org.apache.joran.ExecutionContext;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.xml.sax.Attributes;
   
   /**
  
  
  
  1.9       +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/PluginAction.java
  
  Index: PluginAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/PluginAction.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- PluginAction.java 8 Jan 2005 14:05:28 -0000       1.8
  +++ PluginAction.java 12 Jan 2005 15:04:18 -0000      1.9
  @@ -15,11 +15,10 @@
    */
   package org.apache.log4j.joran.action;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   import org.apache.joran.helper.Option;
   
   import org.apache.log4j.helpers.OptionConverter;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.plugins.Plugin;
   import org.apache.log4j.spi.ErrorItem;
   import org.apache.log4j.spi.LoggerRepository;
  
  
  
  1.2       +1 -1      
logging-log4j/src/java/org/apache/log4j/joran/action/SubstitutionPropertyAction.java
  
  Index: SubstitutionPropertyAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/SubstitutionPropertyAction.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SubstitutionPropertyAction.java   17 May 2004 16:58:29 -0000      1.1
  +++ SubstitutionPropertyAction.java   12 Jan 2005 15:04:18 -0000      1.2
  @@ -18,7 +18,7 @@
   
   import java.util.Properties;
   
  -import org.apache.joran.ExecutionContext;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   
   
   /**
  
  
  
  1.4       +1 -1      
logging-log4j/src/java/org/apache/log4j/joran/action/RepositoryPropertyAction.java
  
  Index: RepositoryPropertyAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/RepositoryPropertyAction.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- RepositoryPropertyAction.java     19 Nov 2004 15:20:06 -0000      1.3
  +++ RepositoryPropertyAction.java     12 Jan 2005 15:04:18 -0000      1.4
  @@ -17,7 +17,7 @@
   
   import java.util.Properties;
   
  -import org.apache.joran.ExecutionContext;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.ErrorItem;
   import org.apache.log4j.spi.LoggerRepository;
   
  
  
  
  1.10      +1 -2      
logging-log4j/src/java/org/apache/log4j/joran/action/ConfigurationAction.java
  
  Index: ConfigurationAction.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/ConfigurationAction.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ConfigurationAction.java  28 Dec 2004 16:33:57 -0000      1.9
  +++ ConfigurationAction.java  12 Jan 2005 15:04:18 -0000      1.10
  @@ -18,10 +18,9 @@
   
   import java.util.List;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.action.Action;
   
   import org.apache.log4j.config.ConfiguratorBase;
  +import org.apache.log4j.joran.spi.ExecutionContext;
   import org.apache.log4j.spi.LoggerRepository;
   import org.xml.sax.Attributes;
   
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/action/ImplicitAction.java
  
  Index: ImplicitAction.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.action;
  
  import org.apache.log4j.joran.spi.ExecutionContext;
  import org.apache.log4j.joran.spi.Pattern;
  
  import org.xml.sax.Attributes;
  
  
  /**
   * ImplcitActions are like normal (explicit) actions except that are applied
   * by the parser when no other pattern applies. Since there can be many 
implcit
   * actions, each action is asked whether it applies in the given context. The
   * first impplcit action to respond postively will be applied. See also the
   * [EMAIL PROTECTED] #isApplicable} method.
   *
   * @author Ceki Gülcü
   */
  public abstract class ImplicitAction extends Action {
    
    /**
     * Check whether this implicit action is apprioriate in the current context.
     * 
     * 
     * @param currentPattern This pattern contains the tag name of the current 
     * element being parsed at the top of the stack.
     * @param attributes The attributes of the current element to process.
     * @param ec
     * @return Whether the implicit action is applicable in the current context
     */
    public abstract boolean isApplicable(
      Pattern currentPattern, Attributes attributes, ExecutionContext ec);
    
    
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/action/NewRuleAction.java
  
  Index: NewRuleAction.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.action;
  
  import org.apache.joran.helper.Option;
  
  import org.apache.log4j.joran.spi.ExecutionContext;
  import org.apache.log4j.joran.spi.Pattern;
  import org.apache.log4j.spi.ErrorItem;
  import org.xml.sax.Attributes;
  
  
  public class NewRuleAction extends Action {
    boolean inError = false;
    
    /**
     * Instantiates an layout of the given class and sets its name.
     *
     */
    public void begin(ExecutionContext ec, String localName, Attributes 
attributes) {
                // Let us forget about previous errors (in this object)
                inError = false; 
      String errorMsg;
      String pattern =  attributes.getValue(Action.PATTERN_ATTRIBUTE);
      String actionClass =  attributes.getValue(Action.ACTION_CLASS_ATTRIBUTE);
  
      if(Option.isEmpty(pattern)) {
         inError = true;
         errorMsg = "No 'pattern' attribute in <newRule>";
         getLogger().warn(errorMsg);
         ec.addError(new ErrorItem(errorMsg));
         return;
       }
      
       if(Option.isEmpty(actionClass)) {
           inError = true;
           errorMsg = "No 'actionClass' attribute in <newRule>";
           getLogger().warn(errorMsg);
           ec.addError(new ErrorItem(errorMsg));
           return;
       }
         
      try {
        getLogger().debug("About to add new Joran parsing rule 
["+pattern+","+actionClass+"].");
        ec.getJoranInterpreter().getRuleStore().addRule(new Pattern(pattern), 
actionClass);
      } catch (Exception oops) {
        inError = true;
        errorMsg =  "Could not add new Joran parsing rule 
["+pattern+","+actionClass+"]"; 
        getLogger().error(errorMsg, oops);
        ec.addError(new ErrorItem(errorMsg));
      }
    }
  
    /**
     * Once the children elements are also parsed, now is the time to activate
     * the appender options.
     */
    public void end(ExecutionContext ec, String n) {
    }
  
    public void finish(ExecutionContext ec) {
    }
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/action/Action.java
  
  Index: Action.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.action;
  
  import org.apache.log4j.joran.spi.ExecutionContext;
  import org.apache.log4j.joran.spi.Interpreter;
  import org.apache.log4j.spi.ComponentBase;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.Locator;
  
  
  /**
   *
   * Most of the work for configuring log4j is done by Actions.
   *
   * Methods of an Action are invoked while an XML file is parsed through.
   *
   * This class is largely copied from the relevant class in the 
commons-digester
   * project of the Apache Software Foundation.
   *
   * @author Craig McClanahan
   * @author Christopher Lenz
   * @author Ceki G&uuml;lc&uuml;
   *
   */
  public abstract class Action extends ComponentBase {
    public static final String NAME_ATTRIBUTE = "name";
    public static final String VALUE_ATTRIBUTE = "value";
    public static final String FILE_ATTRIBUTE = "file";
    public static final String CLASS_ATTRIBUTE = "class";
    public static final String PATTERN_ATTRIBUTE = "pattern";
    public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";
  
    /**
     * Called when the parser first encounters an element.
     *
     * The return value indicates whether child elements should be processed. If
     * the returned value is 'false', then child elements are ignored.
     */
    public abstract void begin(
      ExecutionContext ec, String name, Attributes attributes);
  
    public abstract void end(ExecutionContext ec, String name);
  
    public String toString() {
      return this.getClass().getName();
    }
  
    protected int getColumnNumber(ExecutionContext ec) {
      Interpreter jp = ec.getJoranInterpreter();
      Locator locator = jp.getLocator();
      if (locator != null) {
        return locator.getColumnNumber();
      }
      return -1;
    }
  
    protected int getLineNumber(ExecutionContext ec) {
      Interpreter jp = ec.getJoranInterpreter();
      Locator locator = jp.getLocator();
      if (locator != null) {
        return locator.getLineNumber();
      }
      return -1;
    }
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/action/NestComponentIA.java
  
  Index: NestComponentIA.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.action;
  
  import org.apache.joran.helper.Option;
  
  import org.apache.log4j.config.PropertySetter;
  import org.apache.log4j.helpers.Loader;
  import org.apache.log4j.joran.action.ImplicitAction;
  import org.apache.log4j.joran.spi.ExecutionContext;
  import org.apache.log4j.joran.spi.Pattern;
  import org.apache.log4j.spi.Component;
  import org.apache.log4j.spi.ErrorItem;
  import org.apache.log4j.spi.OptionHandler;
  
  import org.xml.sax.Attributes;
  
  import java.util.Stack;
  
  
  /**
   * @author Ceki G&uuml;lc&uuml;
   *
   */
  public class NestComponentIA extends ImplicitAction {
    
    // actionDataStack contains ActionData instances
    // We use a stack of ActionData objects in order to support nested
    // elements which are handled by the same NestComponentIA instance.
    // We push a ActionData instance in the isApplicable method (if the
    // action is applicable) and pop it in the end() method.
    // The XML well-formedness property will guarantee that a push will 
eventually
    // be followed by the corresponding pop.
    Stack actionDataStack = new Stack();
  
    public boolean isApplicable(
      Pattern pattern, Attributes attributes, ExecutionContext ec) {
      //LogLog.debug("in NestComponentIA.isApplicable <" + pattern + ">");
      String nestedElementTagName = pattern.peekLast();
  
      Object o = ec.peekObject();
      PropertySetter parentBean = new PropertySetter(o);
  
      int containmentType = 
parentBean.canContainComponent(nestedElementTagName);
  
      switch (containmentType) {
      case PropertySetter.NOT_FOUND:
        return false;
  
      // we only push action data if NestComponentIA is applicable
      case PropertySetter.AS_COLLECTION:
      case PropertySetter.AS_PROPERTY:
        ActionData ad = new ActionData(parentBean, containmentType);
        actionDataStack.push(ad);
  
        return true;
      default:
        ec.addError(
          new ErrorItem(
            "PropertySetter.canContainComponent returned " + containmentType));
        return false;
      }
    }
  
    public void begin(
      ExecutionContext ec, String localName, Attributes attributes) {
      //LogLog.debug("in NestComponentIA begin method");
      // get the action data object pushed in isApplicable() method call
      ActionData actionData = (ActionData) actionDataStack.peek();
  
      String className = attributes.getValue(CLASS_ATTRIBUTE);
  
      // perform variable name substitution
      className = ec.subst(className);
  
      if (Option.isEmpty(className)) {
        actionData.inError = true;
  
        String errMsg = "No class name attribute in <" + localName + ">";
        getLogger().error(errMsg);
        ec.addError(new ErrorItem(errMsg));
  
        return;
      }
  
      try {
        getLogger().debug(
          "About to instantiate component <{}> of type [{}]", localName,
          className);
  
        actionData.nestedComponent = Loader.loadClass(className).newInstance();
        
        // pass along the repository
        if(actionData.nestedComponent instanceof Component) {
          ((Component) 
actionData.nestedComponent).setLoggerRepository(this.repository);
        }
        getLogger().debug(
          "Pushing component <{}> on top of the object stack.", localName);
        ec.pushObject(actionData.nestedComponent);
      } catch (Exception oops) {
        actionData.inError = true;
  
        String msg = "Could not create component <" + localName + ">.";
        getLogger().error(msg, oops);
        ec.addError(new ErrorItem(msg));
      }
    }
  
    public void end(ExecutionContext ec, String tagName) {
      getLogger().debug("entering end method");
  
      // pop the action data object pushed in isApplicable() method call
      // we assume that each this begin
      ActionData actionData = (ActionData) actionDataStack.pop();
  
      if (actionData.inError) {
        return;
      }
  
      if (actionData.nestedComponent instanceof OptionHandler) {
        ((OptionHandler) actionData.nestedComponent).activateOptions();
      }
  
      Object o = ec.peekObject();
  
      if (o != actionData.nestedComponent) {
        getLogger().warn(
          "The object on the top the of the stack is not the component pushed 
earlier.");
      } else {
        getLogger().debug("Removing component from the object stack");
        ec.popObject();
  
        // Now let us attach the component
        switch (actionData.containmentType) {
        case PropertySetter.AS_PROPERTY:
          getLogger().debug(
            "Setting [{}] to parent of type [{}]", tagName,
            actionData.parentBean.getObjClass());
          actionData.parentBean.setComponent(
            tagName, actionData.nestedComponent);
  
          break;
        case PropertySetter.AS_COLLECTION:
          getLogger().debug(
            "Adding [{}] to parent of type [{}]", tagName,
            actionData.parentBean.getObjClass());
          actionData.parentBean.addComponent(
            tagName, actionData.nestedComponent);
  
          break;
        }
      }
    }
  
    public void finish(ExecutionContext ec) {
    }
  }
  
  
  class ActionData {
    PropertySetter parentBean;
    Object nestedComponent;
    int containmentType;
    boolean inError;
  
    ActionData(PropertySetter parentBean, int containmentType) {
      this.parentBean = parentBean;
      this.containmentType = containmentType;
    }
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/action/ParamAction.java
  
  Index: ParamAction.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.action;
  
  
  import org.apache.log4j.config.PropertySetter;
  import org.apache.log4j.helpers.OptionConverter;
  import org.apache.log4j.joran.spi.ExecutionContext;
  import org.apache.log4j.spi.ErrorItem;
  
  import org.xml.sax.Attributes;
  
  
  public class ParamAction extends Action {
    static String NO_NAME = "No name attribute in <param> element";
    static String NO_VALUE = "No name attribute in <param> element";
    boolean inError = false;
  
    public void begin(
      ExecutionContext ec, String localName, Attributes attributes) {
      String name = attributes.getValue(NAME_ATTRIBUTE);
      String value = attributes.getValue(VALUE_ATTRIBUTE);
  
      if (name == null) {
        inError = true;
        getLogger().error(NO_NAME);
        ec.addError(new ErrorItem(NO_NAME));
        return;
      }
  
      if (value == null) {
        inError = true;
        getLogger().error(NO_VALUE);
        ec.addError(new ErrorItem(NO_VALUE));
        return;
      }
  
      // remove both leading and trailing spaces
      value = value.trim();
  
      Object o = ec.peekObject();
      PropertySetter propSetter = new PropertySetter(o);
      value = ec.subst(OptionConverter.convertSpecialChars(value));
  
      // allow for variable substitution for name as well
      name = ec.subst(name);
  
      getLogger().debug(
        "In ParamAction setting parameter [{}] to value [{}].", name, value);
      propSetter.setProperty(name, value);
    }
  
    public void end(ExecutionContext ec, String localName) {
    }
  
    public void finish(ExecutionContext ec) {
    }
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/spi/Pattern.java
  
  Index: Pattern.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.spi;
  
  import java.util.ArrayList;
  
  
  public class Pattern {
    
    // contains String instances
    ArrayList components;
  
    public Pattern() {
      components = new ArrayList();
    }
  
    /**
     * Build a pattern from a string.
     * 
     * Note that "/x" is considered equivalent to "x" and to "x/"
     * 
     */
    public Pattern(String p) {
      this();
  
      if (p == null) {
        return;
      }
  
      int lastIndex = 0;
  
      //System.out.println("p is "+ p);
      while (true) {
        int k = p.indexOf('/', lastIndex);
  
        //System.out.println("k is "+ k);
        if (k == -1) {
          components.add(p.substring(lastIndex));
  
          break;
        } else {
          String c = p.substring(lastIndex, k);
  
          if (c.length() > 0) {
            components.add(c);
          }
  
          lastIndex = k + 1;
        }
      }
  
      //System.out.println(components);
    }
  
    public void push(String s) {
      components.add(s);
    }
  
    public int size() {
      return components.size();
    }
  
    public String get(int i) {
      return (String) components.get(i);
    }
  
    public void pop() {
      if (!components.isEmpty()) {
        components.remove(components.size() - 1);
      }
    }
    
    public String peekLast() {
      if (!components.isEmpty()) {
        int size = components.size();
        return (String) components.get(size - 1);
      } else {
       return null;
      }
    }
  
    /**
     * Returns the number of "tail" components that this pattern has in common
     * with the pattern p passed as parameter. By "tail" components we mean the
     * components at the end of the pattern.
     */
    public int tailMatch(Pattern p) {
      if (p == null) {
        return 0;
      }
  
      int lSize = this.components.size();
      int rSize = p.components.size();
  
      // no match possible for empty sets
      if ((lSize == 0) || (rSize == 0)) {
        return 0;
      }
  
      int minLen = (lSize <= rSize) ? lSize : rSize;
      int match = 0;
  
      // loop from the end to the front
      for (int i = 1; i <= minLen; i++) {
        String l = (String) this.components.get(lSize - i);
        String r = (String) p.components.get(rSize - i);
  
        if (l.equals(r)) {
          match++;
        } else {
          break;
        }
      }
  
      return match;
    }
  
    public boolean equals(Object o) {
      //System.out.println("in equals:" +this+ " vs. " + o);
      if ((o == null) || !(o instanceof Pattern)) {
        return false;
      }
  
      //System.out.println("both are Patterns");
      Pattern r = (Pattern) o;
  
      if (r.size() != size()) {
        return false;
      }
  
      //System.out.println("both are size compatible");
      int len = size();
  
      for (int i = 0; i < len; i++) {
        if (!(get(i).equals(r.get(i)))) {
          return false;
        }
      }
  
      // if everything matches, then the twp patterns are equal
      return true;
    }
  
    public int hashCode() {
      int hc = 0;
      int len = size();
  
      for (int i = 0; i < len; i++) {
        hc ^= get(i).hashCode();
  
        //System.out.println("i = "+i+", hc="+hc);
      }
  
      return hc;
    }
  
    public String toString() {
      int size = components.size();
      String result = "";
      for(int i = 0; i < size; i++) {
        result +=  "/" + components.get(i);
      }
      return result;
    }
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/spi/RuleStore.java
  
  Index: RuleStore.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.spi;
  
  import java.util.List;
  
  import org.apache.log4j.joran.action.Action;
  
  public interface RuleStore {
    public void addRule(Pattern pattern, String actionClassStr) throws 
ClassNotFoundException;
    public void addRule(Pattern pattern, Action action);
    
    public List matchActions(Pattern pattern);
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/spi/Interpreter.java
  
  Index: Interpreter.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.spi;
  
  import org.apache.log4j.LogManager;
  import org.apache.log4j.joran.action.Action;
  import org.apache.log4j.joran.action.ImplicitAction;
  import org.apache.log4j.spi.Component;
  import org.apache.log4j.spi.ErrorItem;
  import org.apache.log4j.spi.LoggerRepository;
  import org.apache.ugli.ULogger;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  import org.xml.sax.Locator;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.helpers.DefaultHandler;
  
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Stack;
  import java.util.Vector;
  
  
  /**
   * <id>Interpreter</id> is Joran's main driving class. It extends SAX
   * [EMAIL PROTECTED] org.xml.sax.helpers.DefaultHandler DefaultHandler} which 
invokes 
   * various [EMAIL PROTECTED] Action actions} according to predefined patterns.
   *
   * <p>Patterns are kept in a [EMAIL PROTECTED] RuleStore} which is programmed 
to store and
   * then later produce the applicable actions for a given pattern.
   *
   * <p>The pattern corresponding to a top level &lt;a&gt; element is the string
   * <id>"a"</id>.
   *
   * <p>The pattern corresponding to an element &lt;b&gt; embeded within a top 
level
   * &lt;a&gt; element is the string <id>"a/b"</id>.
   *
   * <p>The pattern corresponding to an &lt;b&gt; and any level of nesting is
   * "&#42;/b. Thus, the &#42; character placed at the beginning of a pattern
   * serves as a wildcard for the level of nesting.
   *
   * Conceptually, this is very similar to the API of commons-digester. Joran
   * offers several small advantages. First and foremost, it offers support for
   * implicit actions which result in a significant leap in flexibility. Second,
   * in our opinion better error reporting capability. Third, it is 
self-reliant.
   * It does not depend on other APIs, in particular commons-logging which is
   * a big no-no for log4j. Last but not least, joran is quite tiny and is
   * expected to remain so.
   *
   * @author Ceki G&uuml;lcu&uuml;
   *
   */
  public class Interpreter extends DefaultHandler implements Component  {
    private static List EMPTY_LIST = new Vector(0);
    private RuleStore ruleStore;
    private ExecutionContext ec;
    private ArrayList implicitActions;
    Pattern pattern;
    Locator locator;
  
    // The entity resolver is only needed in order to be compatible with
    // XML files written for DOMConfigurator containing the following DOCTYPE
    // <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    private EntityResolver entityResolver;
    
    private LoggerRepository repository;
    
    /**
     * The <id>actionListStack</id> contains a list of actions that are
     * executing for the given XML element.
     *
     * A list of actions is pushed by the {link #startElement} and popped by
     * [EMAIL PROTECTED] #endElement}.
     *
     */
    Stack actionListStack;
  
    public Interpreter(RuleStore rs) {
      ruleStore = rs;
      ec = new ExecutionContext(this);
      implicitActions = new ArrayList(3);
      pattern = new Pattern();
      actionListStack = new Stack();
    }
  
    public ExecutionContext getExecutionContext() {
      return ec;
    }
  
    public void startDocument() {
    }
  
    public void startElement(
      String namespaceURI, String localName, String qName, Attributes atts) {
  
      String tagName = getTagName(localName, qName);
  
      //LogLog.debug("in startElement <" + tagName + ">");
  
      pattern.push(tagName);
  
      List applicableActionList = getApplicableActionList(pattern, atts);
  
      if (applicableActionList != null) {
        actionListStack.add(applicableActionList);
        callBeginAction(applicableActionList, tagName, atts);
      } else {
        actionListStack.add(EMPTY_LIST);
  
        String errMsg =
          "no applicable action for <" + tagName + ">, current pattern is ["
          + pattern+"]";
        getLogger().warn(errMsg);
        ec.addError(new ErrorItem(errMsg));
      }
    }
  
    public void endElement(String namespaceURI, String localName, String qName) 
{
      List applicableActionList = (List) actionListStack.pop();
  
      if (applicableActionList != EMPTY_LIST) {
        callEndAction(applicableActionList, getTagName(localName, qName));
      }
  
      // given that we always push, we must also pop the pattern
      pattern.pop();
    }
  
    public Locator getLocator() {
      return locator;
    }
  
    public void setDocumentLocator(Locator l) {
      locator = l;
    }
  
    String getTagName(String localName, String qName) {
      String tagName = localName;
  
      if ((tagName == null) || (tagName.length() < 1)) {
        tagName = qName;
      }
  
      return tagName;
    }
  
    public void addImplicitAction(ImplicitAction ia) {
      implicitActions.add(ia);
    }
  
    /**
     * Check if any implicit actions are applicable. As soon as an applicable
     * action is found, it is returned. Thus, the returned list will have at 
most
     * one element.
     */
    List lookupImplicitAction(Pattern pattern, Attributes attributes, 
ExecutionContext ec) {
      int len = implicitActions.size();
  
      for (int i = 0; i < len; i++) {
        ImplicitAction ia = (ImplicitAction) implicitActions.get(i);
  
        if (ia.isApplicable(pattern, attributes, ec)) {
          List actionList = new ArrayList(1);
          actionList.add(ia);
  
          return actionList;
        }
      }
  
      return null;
    }
  
    /**
     * Return the list of applicable patterns for this
    */
    List getApplicableActionList(Pattern pattern, Attributes attributes) {
      List applicableActionList = ruleStore.matchActions(pattern);
  
      //logger.debug("set of applicable patterns: " + applicableActionList);
      if (applicableActionList == null) {
        applicableActionList = lookupImplicitAction(pattern, attributes, ec);
      }
  
      return applicableActionList;
    }
  
    void callBeginAction(
      List applicableActionList, String tagName, Attributes atts) {
      if (applicableActionList == null) {
        return;
      }
  
      Iterator i = applicableActionList.iterator();
  
      while (i.hasNext()) {
        Action action = (Action) i.next();
  
        // now let us invoke the action. We catch and report any eventual 
        // exceptions
        try {
          action.begin(ec, tagName, atts);
        } catch (Exception e) {
          ec.addError(new ErrorItem("Action threw an exception", e));
        }
      }
    }
  
    void callEndAction(List applicableActionList, String tagName) {
      if (applicableActionList == null) {
        return;
      }
  
      //logger.debug("About to call end actions on node: <" + localName + ">");
      Iterator i = applicableActionList.iterator();
  
      while (i.hasNext()) {
        Action action = (Action) i.next();
        action.end(ec, tagName);
      }
    }
  
    public RuleStore getRuleStore() {
      return ruleStore;
    }
  
    public void setRuleStore(RuleStore ruleStore) {
      this.ruleStore = ruleStore;
    }
  
  //  /**
  //   * Call the finish methods for all actions. Unfortunately, the endDocument
  //   * method is not called in case of errors in the XML document, which
  //   * makes endDocument() pretty damn useless.
  //   */
  //  public void endDocument() {
  //    Set arrayListSet = ruleStore.getActionSet();
  //    Iterator iterator = arrayListSet.iterator();
  //    while(iterator.hasNext()) {
  //      ArrayList al = (ArrayList) iterator.next();
  //      for(int i = 0; i < al.size(); i++) {
  //         Action a = (Action) al.get(i);
  //         a.endDocument(ec);
  //      }
  //    }
  //  }
  
    public void error(SAXParseException spe) throws SAXException {
      ec.addError(new ErrorItem("Parsing error", spe));
      getLogger().error(
        "Parsing problem on line " + spe.getLineNumber() + " and column "
        + spe.getColumnNumber(), spe);
    }
  
    public void fatalError(SAXParseException spe) throws SAXException {
      ec.addError(new ErrorItem("Parsing fatal error", spe));
      getLogger().error(
        "Parsing problem on line " + spe.getLineNumber() + " and column "
        + spe.getColumnNumber(), spe);
    }
  
    public void warning(SAXParseException spe) throws SAXException {
      ec.addError(new ErrorItem("Parsing warning", spe));
      getLogger().warn(
        "Parsing problem on line " + spe.getLineNumber() + " and column "
        + spe.getColumnNumber(), spe);
    }
  
    public void endPrefixMapping(java.lang.String prefix) {
    }
  
    public void ignorableWhitespace(char[] ch, int start, int length) {
    }
  
    public void processingInstruction(
      java.lang.String target, java.lang.String data) {
    }
  
    public void skippedEntity(java.lang.String name) {
    }
  
    public void startPrefixMapping(
      java.lang.String prefix, java.lang.String uri) {
    }
  
    public EntityResolver getEntityResolver() {
      return entityResolver;
    }
    
    public void setEntityResolver(EntityResolver entityResolver) {
      this.entityResolver = entityResolver;
    }
  
    
    /**
     * If a specific entityResolver is set for this Interpreter instance, then 
     * we use it to resolve entities. Otherwise, we use the default 
implementation
     * offered by the super class.
     * 
     * <p>Due to inexplicable voodoo, the original resolveEntity method in 
     * org.xml.sax.helpers.DefaultHandler declares throwing an IOException, 
     * whereas the org.xml.sax.helpers.DefaultHandler class included in
     * JDK 1.4 masks this exception.
     * 
     * <p>In order to compile under JDK 1.4, we are forced to mask the 
IOException
     * as well. Since its signatures varies, we cannot call our super class' 
     * resolveEntity method. We are forced to implement the default behavior 
     * ourselves, which in this case, is just returning null.
     * 
     */
    public InputSource resolveEntity(String publicId, String systemId) throws 
SAXException {
      if(entityResolver == null) {
        // the default implementation is to return null
        return null;
      } else {
        try {
          return entityResolver.resolveEntity(publicId, systemId);
        } catch(IOException ioe) {
          // fall back to the default "implementation"
          return null;
        }
      }
    }
  
    public void setLoggerRepository(LoggerRepository repository) {
      this.repository = repository;
    }
  
    protected ULogger getLogger() {
      if(repository != null) {
        return repository.getLogger(this.getClass().getName());
      } else {
        return LogManager.SIMPLE_LOGGER_FA.getLogger(this.getClass().getName());
      }
    } 
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/spi/ExecutionContext.java
  
  Index: ExecutionContext.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.spi;
  
  //import org.apache.log4j.helpers.OptionConverter;
  
  import org.apache.log4j.helpers.OptionConverter;
  import org.apache.log4j.spi.ErrorItem;
  import org.xml.sax.Locator;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Properties;
  import java.util.Stack;
  import java.util.Vector;
  
  
  /**
   *
   * The ExecutionContext contains the contextual state of a Joran parsing 
   * session. [EMAIL PROTECTED] org.apache.log4j.joran.action.Action Actions} 
depend on this 
   * context to exchange and store information.
   *  
   * @author Ceki G&uuml;lc&uuml;
   */
  public class ExecutionContext {
    Stack objectStack;
    Map objectMap;
    Vector errorList;
    Properties substitutionProperties;
    Interpreter joranInterpreter;
  
    public ExecutionContext(Interpreter joranInterpreter) {
      this.joranInterpreter = joranInterpreter;
      objectStack = new Stack();
      objectMap = new HashMap(5);
      errorList = new Vector();
      substitutionProperties = new Properties();
    }
  
  //  /**
  //   * Clear the internal structures for reuse of the execution context
  //   * 
  //   */
  //  public void clear() {
  //    objectStack.clear();
  //    objectMap.clear();
  //    errorList.clear();
  //    substitutionProperties.clear();
  //  }
    
    public void addError(ErrorItem errorItem) {
      Locator locator = joranInterpreter.getLocator();
  
      if (locator != null) {
        errorItem.setLineNumber(locator.getLineNumber());
        errorItem.setColNumber(locator.getColumnNumber());
      }
  
      errorList.add(errorItem);
    }
  
    public List getErrorList() {
      return errorList;
    }
  
    public Locator getLocator() {
      return joranInterpreter.getLocator();
    }
  
    public Interpreter getJoranInterpreter() {
      return joranInterpreter;
    }
  
    public Stack getObjectStack() {
      return objectStack;
    }
  
    public Object peekObject() {
      return objectStack.peek();
    }
  
    public void pushObject(Object o) {
      objectStack.push(o);
    }
  
    public Object popObject() {
      return objectStack.pop();
    }
  
    public Object getObject(int i) {
      return objectStack.get(i);
    }
  
    public Map getObjectMap() {
      return objectMap;
    }
  
    /**
     * Add a property to the properties of this execution context.
     * If the property exists already, it is overwritten.
     */
    public void addProperty(String key, String value) {
      if(key == null || value == null) {
        return;
      }
  //    if (substitutionProperties.contains(key)) {
  //      LogLog.warn(
  //        "key [" + key
  //        + "] already contained in the EC properties. Overwriting.");
  //    }
  
      // values with leading or trailing spaces are bad. We remove them now.
      value = value.trim();
      substitutionProperties.put(key, value);
    }
  
   public void addProperties(Properties props) {
      if(props == null) {
        return;
      }
      Iterator i = props.keySet().iterator();
      while(i.hasNext()) {
        String key = (String) i.next();
        addProperty(key, props.getProperty(key));
      }
    }
   
    public String getSubstitutionProperty(String key) {
      return substitutionProperties.getProperty(key);
    }
  
    public String subst(String value) {
      if(value == null) {
        return null;
      }
      return OptionConverter.substVars(value, substitutionProperties);
    }
  }
  
  
  
  1.1                  
logging-log4j/src/java/org/apache/log4j/joran/spi/SimpleRuleStore.java
  
  Index: SimpleRuleStore.java
  ===================================================================
  /*
   * Copyright 1999,2004 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.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.joran.spi;
  
  import org.apache.joran.*;
  import org.apache.joran.action.*;
  
  import org.apache.log4j.helpers.OptionConverter;
  import org.apache.log4j.joran.action.Action;
  import org.apache.log4j.spi.LoggerRepository;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  
  
  public class SimpleRuleStore implements RuleStore {
  
    // key: Pattern instance, value: ArrayList containing actions
    HashMap rules = new HashMap();
    LoggerRepository repository;
  
    public SimpleRuleStore() {
    }
  
    public SimpleRuleStore(LoggerRepository repository) {
      this.repository = repository;
    }
    
    public void addRule(Pattern pattern, Action action) {
      action.setLoggerRepository(repository);
      
      List a4p = (List) rules.get(pattern);
  
      if (a4p == null) {
        a4p = new ArrayList();
        rules.put(pattern, a4p);
      }
  
      a4p.add(action);
    }
  
    public void addRule(Pattern pattern, String actionClassName) {
      Action action =
        (Action) OptionConverter.instantiateByClassName(
          actionClassName, Action.class, null);
  
      if(action != null) {
          addRule(pattern, action);
        }
    }
  
    public List matchActions(Pattern pattern) {
      //System.out.println("pattern to search for:" + pattern + ", hashcode: " 
+ pattern.hashCode());
      //System.out.println("rules:" + rules);
      ArrayList a4p = (ArrayList) rules.get(pattern);
  
      if (a4p != null) {
        return a4p;
      } else {
        Iterator patternsIterator = rules.keySet().iterator();
        int max = 0;
        Pattern longestMatch = null;
  
        while (patternsIterator.hasNext()) {
          Pattern p = (Pattern) patternsIterator.next();
  
          if ((p.size() > 1) && p.get(0).equals("*")) {
            int r = pattern.tailMatch(p);
  
            //System.out.println("tailMatch " +r);
            if (r > max) {
              //System.out.println("New longest match "+p);
              max = r;
              longestMatch = p;
            }
          }
        }
  
        if (longestMatch != null) {
          return (ArrayList) rules.get(longestMatch);
        } else {
          return null;
        }
      }
    }
  }
  
  
  
  1.35      +8 -9      
logging-log4j/src/java/org/apache/log4j/joran/JoranConfigurator.java
  
  Index: JoranConfigurator.java
  ===================================================================
  RCS file: 
/home/cvs/logging-log4j/src/java/org/apache/log4j/joran/JoranConfigurator.java,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- JoranConfigurator.java    8 Jan 2005 14:05:28 -0000       1.34
  +++ JoranConfigurator.java    12 Jan 2005 15:04:21 -0000      1.35
  @@ -16,15 +16,7 @@
   
   package org.apache.log4j.joran;
   
  -import org.apache.joran.ExecutionContext;
  -import org.apache.joran.Interpreter;
  -import org.apache.joran.Pattern;
  -import org.apache.joran.RuleStore;
  -import org.apache.joran.action.NestComponentIA;
  -import org.apache.joran.action.NewRuleAction;
  -import org.apache.joran.action.ParamAction;
  -import org.apache.joran.helper.SimpleRuleStore;
  -
  +import org.apache.log4j.joran.action.NestComponentIA;
   import org.apache.log4j.config.ConfiguratorBase;
   import org.apache.log4j.joran.action.ActionConst;
   import org.apache.log4j.joran.action.AppenderAction;
  @@ -35,11 +27,18 @@
   import org.apache.log4j.joran.action.LayoutAction;
   import org.apache.log4j.joran.action.LevelAction;
   import org.apache.log4j.joran.action.LoggerAction;
  +import org.apache.log4j.joran.action.NewRuleAction;
  +import org.apache.log4j.joran.action.ParamAction;
   import org.apache.log4j.joran.action.PluginAction;
   import org.apache.log4j.joran.action.PriorityAction;
   import org.apache.log4j.joran.action.RepositoryPropertyAction;
   import org.apache.log4j.joran.action.RootLoggerAction;
   import org.apache.log4j.joran.action.SubstitutionPropertyAction;
  +import org.apache.log4j.joran.spi.ExecutionContext;
  +import org.apache.log4j.joran.spi.Interpreter;
  +import org.apache.log4j.joran.spi.Pattern;
  +import org.apache.log4j.joran.spi.RuleStore;
  +import org.apache.log4j.joran.spi.SimpleRuleStore;
   import org.apache.log4j.joran.util.JoranDocument;
   import org.apache.log4j.spi.ErrorItem;
   import org.apache.log4j.spi.LoggerRepository;
  
  
  

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

Reply via email to