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ülcü * */ 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ülcü * */ 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 <a> element is the string * <id>"a"</id>. * * <p>The pattern corresponding to an element <b> embeded within a top level * <a> element is the string <id>"a/b"</id>. * * <p>The pattern corresponding to an <b> and any level of nesting is * "*/b. Thus, the * 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ülcuü * */ 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ülcü */ 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]