ceki 2003/09/23 11:52:51 Modified: src/java/org/apache/joran/action ActionConst.java src/java/org/apache/joran JoranParser.java RuleStore.java SimpleRuleStore.java tests build.xml src/java/org/apache/log4j/pattern PatternParser.java . build.xml tests/src/java/org/apache/joran JoranParserTest.java src/java/org/apache/log4j PatternLayout.java Added: src/java/org/apache/joran/action ConversionRuleAction.java NewRuleAction.java tests/input/joran conversionRule.xml Log: - Joran, through its ConversionRuleAction, can now deal with new conversion words for a PatternLayout. - Joran can learn new rules on the fiy. (Not yet tested) Revision Changes Path 1.3 +3 -1 jakarta-log4j/src/java/org/apache/joran/action/ActionConst.java Index: ActionConst.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/joran/action/ActionConst.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ActionConst.java 11 Sep 2003 17:25:24 -0000 1.2 +++ ActionConst.java 23 Sep 2003 18:52:50 -0000 1.3 @@ -16,7 +16,9 @@ public static final String VALUE_ATTRIBUTE = "value"; public static final String CLASS_ATTRIBUTE = "class"; public static final String ADDITIVITY_ATTRIBUTE = "additivity"; - + public static final String CONVERTER_CLASS_ATTRIBUTE = "converterClass"; + public static final String CONVERSION_WORD_ATTRIBUTE = "conversionWord"; + public static final String PATTERN_ATTRIBUTE = "pattern"; public static final String ACTION_CLASS_ATTRIBUTE = "actionClass"; static final String INHERITED = "INHERITED"; static final String NULL = "NULL"; 1.1 jakarta-log4j/src/java/org/apache/joran/action/ConversionRuleAction.java Index: ConversionRuleAction.java =================================================================== /* * ============================================================================ * The Apache Software License, Version 1.1 * ============================================================================ * * Copyright (C) 1999 The Apache Software Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, must * include the following acknowledgment: "This product includes software * developed by the Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, if * and wherever such third-party acknowledgments normally appear. * * 4. The names "log4j" and "Apache Software Foundation" must not be used to * endorse or promote products derived from this software without prior * written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", nor may * "Apache" appear in their name, without prior written permission of the * Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This software consists of voluntary contributions made by many individuals * on behalf of the Apache Software Foundation. For more information on the * Apache Software Foundation, please see <http://www.apache.org/>. * */ package org.apache.joran.action; import org.apache.joran.ExecutionContext; import org.apache.joran.helper.Option; import org.apache.log4j.Layout; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.w3c.dom.Element; public class ConversionRuleAction extends Action { static final Logger logger = Logger.getLogger(ConversionRuleAction.class); Layout layout; /** * Instantiates an layout of the given class and sets its name. * */ public void begin(ExecutionContext ec, Element element) { // Let us forget about previous errors (in this object) inError = false; String errorMsg; String conversionWord = element.getAttribute(ActionConst.CONVERSION_WORD_ATTRIBUTE); String converterClass = element.getAttribute(ActionConst.CONVERTER_CLASS_ATTRIBUTE); if (Option.isEmpty(conversionWord)) { inError = true; errorMsg = "No 'conversionWord' attribute in <conversionRule>"; logger.warn(errorMsg); ec.addError(errorMsg); return; } if (Option.isEmpty(converterClass)) { inError = true; errorMsg = "No 'converterClass' attribute in <conversionRule>"; logger.warn(errorMsg); ec.addError(errorMsg); return; } try { logger.debug( "About to add conversion rule [" + conversionWord + ", " + converterClass + "] to layout"); Object o = ec.peekObject(); if (o instanceof PatternLayout) { PatternLayout patternLayout = (PatternLayout) o; patternLayout.addConversionRule(conversionWord, converterClass); } } catch (Exception oops) { inError = true; errorMsg = "Could not add conversion rule to PatternLayout."; logger.error(errorMsg, oops); ec.addError(errorMsg); } } /** * Once the children elements are also parsed, now is the time to activate * the appender options. */ public void end(ExecutionContext ec, Element e) { } public void finish(ExecutionContext ec) { } } 1.1 jakarta-log4j/src/java/org/apache/joran/action/NewRuleAction.java Index: NewRuleAction.java =================================================================== /* * ============================================================================ * The Apache Software License, Version 1.1 * ============================================================================ * * Copyright (C) 1999 The Apache Software Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, must * include the following acknowledgment: "This product includes software * developed by the Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, if * and wherever such third-party acknowledgments normally appear. * * 4. The names "log4j" and "Apache Software Foundation" must not be used to * endorse or promote products derived from this software without prior * written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", nor may * "Apache" appear in their name, without prior written permission of the * Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This software consists of voluntary contributions made by many individuals * on behalf of the Apache Software Foundation. For more information on the * Apache Software Foundation, please see <http://www.apache.org/>. * */ package org.apache.joran.action; import org.apache.joran.ExecutionContext; import org.apache.joran.Pattern; import org.apache.joran.helper.Option; import org.apache.log4j.Layout; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.w3c.dom.Element; public class NewRuleAction extends Action { static final Logger logger = Logger.getLogger(NewRuleAction.class); Layout layout; /** * Instantiates an layout of the given class and sets its name. * */ public void begin(ExecutionContext ec, Element element) { // Let us forget about previous errors (in this object) inError = false; String errorMsg; String pattern = element.getAttribute(ActionConst.PATTERN_ATTRIBUTE); String actionClass = element.getAttribute(ActionConst.ACTION_CLASS_ATTRIBUTE); if(Option.isEmpty(pattern)) { inError = true; errorMsg = "No 'patern' attribute in <newRule>"; logger.warn(errorMsg); ec.addError(errorMsg); return; } if(Option.isEmpty(actionClass)) { inError = true; errorMsg = "No 'actionClass' attribute in <newRule>"; logger.warn(errorMsg); ec.addError(errorMsg); return; } try { logger.debug("About to add new Joran parsing rule ["+pattern+","+actionClass+"]."); ec.getJoranParser().getRuleStore().addRule(new Pattern(pattern), actionClass); } catch (Exception oops) { inError = true; errorMsg = "Could not add new Joran parsing rule ["+pattern+","+actionClass+"]"; logger.error(errorMsg, oops); ec.addError(errorMsg); } } /** * Once the children elements are also parsed, now is the time to activate * the appender options. */ public void end(ExecutionContext ec, Element e) { } public void finish(ExecutionContext ec) { } } 1.6 +9 -0 jakarta-log4j/src/java/org/apache/joran/JoranParser.java Index: JoranParser.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/joran/JoranParser.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- JoranParser.java 12 Sep 2003 18:24:26 -0000 1.5 +++ JoranParser.java 23 Sep 2003 18:52:51 -0000 1.6 @@ -195,4 +195,13 @@ action.end(ec, e); } } + + public RuleStore getRuleStore() { + return ruleStore; + } + + public void setRuleStore(RuleStore ruleStore) { + this.ruleStore = ruleStore; + } + } 1.5 +2 -2 jakarta-log4j/src/java/org/apache/joran/RuleStore.java Index: RuleStore.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/joran/RuleStore.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- RuleStore.java 12 Sep 2003 18:24:26 -0000 1.4 +++ RuleStore.java 23 Sep 2003 18:52:51 -0000 1.5 @@ -51,10 +51,10 @@ import java.util.List; -import org.apache.joran.action.*; - +import org.apache.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.4 +19 -2 jakarta-log4j/src/java/org/apache/joran/SimpleRuleStore.java Index: SimpleRuleStore.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/joran/SimpleRuleStore.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- SimpleRuleStore.java 2 Sep 2003 18:36:29 -0000 1.3 +++ SimpleRuleStore.java 23 Sep 2003 18:52:51 -0000 1.4 @@ -49,15 +49,20 @@ package org.apache.joran; +import org.apache.joran.action.*; + +import org.apache.log4j.Logger; +import org.apache.log4j.helpers.OptionConverter; + import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; -import org.apache.joran.action.*; - public class SimpleRuleStore implements RuleStore { + final static Logger logger = Logger.getLogger(SimpleRuleStore.class); + HashMap rules = new HashMap(); public void addRule(Pattern pattern, Action action) { @@ -70,6 +75,18 @@ } 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); + } else { + logger.warn("Could not intantiate Action of class ["+actionClassName+"]."); + } } public List matchActions(Pattern pattern) { 1.1 jakarta-log4j/tests/input/joran/conversionRule.xml Index: conversionRule.xml =================================================================== <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="A1" class="org.apache.log4j.rolling.RollingFileAppender"> <param name="File" value="output/temp.A1" /> <param name="Append" value="false" /> <rollingPolicy class="org.apache.log4j.rolling.SlidingWindowRollingPolicy"> <param name="activeFileName" value="output/parser3"/> <param name="fileNamePattern" value="output/parser3.%i"/> </rollingPolicy> <triggeringPolicy class="org.apache.log4j.rolling.SizeBasedTriggeringPolicy"> <param name="maxFileSize" value="100"/> </triggeringPolicy> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p %c{2} - %m%n"/> <conversionRule conversionWord="toto" converterClass="org.apache.log4j.toto"/> </layout> </appender> </log4j:configuration> 1.43 +35 -0 jakarta-log4j/tests/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/jakarta-log4j/tests/build.xml,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- build.xml 18 Sep 2003 21:26:55 -0000 1.42 +++ build.xml 23 Sep 2003 18:52:51 -0000 1.43 @@ -110,6 +110,7 @@ HierarchyThreshold, DefaultInit, SocketServer, XMLLayout, AsyncAppender, ErrorHandler, OptionConverter, BoundedFIFO, + Joran, CyclicBuffer, OR, VariaLevelMatchFilter, VariaLevelRangeFilter, PatternParser, LevelMatchFilter, DRFA, Plugins, @@ -122,6 +123,12 @@ <target name="longUnit" depends=""/> <!-- ================================================================= --> + <!-- Joran unit tests --> + <!-- ================================================================= --> + <target name="Joran" depends="Pattern, SimpleStore, JoranParser"/> + + + <!-- ================================================================= --> <!-- ============== Regression and Unit Tests follow ================= --> <!-- ================================================================= --> <target name="Minimum" depends="build, cleanOutputDir"> @@ -408,6 +415,34 @@ <test name="org.apache.log4j.rolling.helpers.CompressTestCase" /> </junit> </target> + + <target name="Pattern" depends="build, cleanOutputDir"> + <junit printsummary="yes" fork="yes" haltonfailure="yes"> + <classpath refid="tests.classpath"/> + <formatter type="plain" usefile="false" /> + <test name="org.apache.joran.PatternTest" /> + </junit> + </target> + + <target name="SimpleStore" depends="build, cleanOutputDir"> + <junit printsummary="yes" fork="yes" haltonfailure="yes"> + <classpath refid="tests.classpath"/> + <formatter type="plain" usefile="false" /> + <test name="org.apache.joran.SimpleStoreTest" /> + </junit> + </target> + + + <target name="JoranParser" depends="build, cleanOutputDir"> + <junit printsummary="yes" fork="yes" haltonfailure="yes"> + <classpath refid="tests.classpath"/> + <formatter type="plain" usefile="false" /> + <test name="org.apache.joran.JoranParserTest" /> + </junit> + </target> + + + <!-- ================================================================= --> <!-- ========================= Very long Tests ======================= --> 1.7 +4 -4 jakarta-log4j/src/java/org/apache/log4j/pattern/PatternParser.java Index: PatternParser.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/pattern/PatternParser.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- PatternParser.java 19 Sep 2003 19:54:12 -0000 1.6 +++ PatternParser.java 23 Sep 2003 18:52:51 -0000 1.7 @@ -369,15 +369,15 @@ String converterId = extractConverter(c); - System.out.println("converter ID[" + converterId + "]"); - System.out.println("c is [" + c + "]"); + //System.out.println("converter ID[" + converterId + "]"); + //System.out.println("c is [" + c + "]"); String className = (String) findConverterClass(converterId); - System.out.println("converter class [" + className + "]"); + //System.out.println("converter class [" + className + "]"); String option = extractOption(); - System.out.println("Option is [" + option + "]"); + //System.out.println("Option is [" + option + "]"); if (className != null) { pc = (PatternConverter) OptionConverter.instantiateByClassName( 1.77 +3 -1 jakarta-log4j/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/jakarta-log4j/build.xml,v retrieving revision 1.76 retrieving revision 1.77 diff -u -r1.76 -r1.77 --- build.xml 23 Sep 2003 13:17:03 -0000 1.76 +++ build.xml 23 Sep 2003 18:52:51 -0000 1.77 @@ -582,7 +582,9 @@ org.apache.log4j.varia, org.apache.log4j.chainsaw, org.apache.log4j.xml, - org.apache.log4j.xml.examples" + org.apache.log4j.xml.examples, + org.apache.joran, + org.apache.joran.action" additionalparam="-breakiterator" version="true" protected="true" 1.5 +43 -2 jakarta-log4j/tests/src/java/org/apache/joran/JoranParserTest.java Index: JoranParserTest.java =================================================================== RCS file: /home/cvs/jakarta-log4j/tests/src/java/org/apache/joran/JoranParserTest.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- JoranParserTest.java 12 Sep 2003 18:24:26 -0000 1.4 +++ JoranParserTest.java 23 Sep 2003 18:52:51 -0000 1.5 @@ -60,6 +60,7 @@ import org.apache.joran.action.ActionConst; import org.apache.joran.action.AppenderAction; import org.apache.joran.action.AppenderRefAction; +import org.apache.joran.action.ConversionRuleAction; import org.apache.joran.action.LayoutAction; import org.apache.joran.action.LevelAction; import org.apache.joran.action.LoggerAction; @@ -67,6 +68,7 @@ import org.apache.joran.action.ParamAction; import org.apache.joran.action.RootLoggerAction; +import org.apache.log4j.Appender; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; @@ -184,7 +186,7 @@ jp.parse(doc); } - public void testLoop3() throws Exception { + public void xtestLoop3() throws Exception { logger.debug("Starting testLoop3"); DocumentBuilderFactory dbf = null; @@ -201,8 +203,9 @@ new Pattern("log4j:configuration/logger/level"), new LevelAction()); rs.addRule( new Pattern("log4j:configuration/root"), new RootLoggerAction()); + //rs.addRule( - //new Pattern("log4j:configuration/root/level"), new LevelAction()); + //new Pattern("log4j:configuration/root/level"), new LevelAction()); rs.addRule( new Pattern("log4j:configuration/logger/appender-ref"), new AppenderRefAction()); @@ -224,5 +227,43 @@ ec.pushObject(LogManager.getLoggerRepository()); logger.debug("About to parse doc"); jp.parse(doc); + } + + public void testNewConversionWord() throws Exception { + logger.debug("Starting testNewConversionWord"); + + DocumentBuilderFactory dbf = null; + + dbf = DocumentBuilderFactory.newInstance(); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + + //inputSource.setSystemId("dummy://log4j.dtd"); + Document doc = docBuilder.parse("file:input/joran/conversionRule.xml"); + RuleStore rs = new SimpleRuleStore(); + rs.addRule( + new Pattern("log4j:configuration/appender"), new AppenderAction()); + rs.addRule( + new Pattern("log4j:configuration/appender/layout"), new LayoutAction()); + rs.addRule( + new Pattern("log4j:configuration/appender/layout/conversionRule"), + new ConversionRuleAction()); + + rs.addRule(new Pattern("*/param"), new ParamAction()); + + JoranParser jp = new JoranParser(rs); + jp.addImplcitAction(new NestComponentIA()); + + ExecutionContext ec = jp.getExecutionContext(); + HashMap omap = ec.getObjectMap(); + omap.put(ActionConst.APPENDER_BAG, new HashMap()); + ec.pushObject(LogManager.getLoggerRepository()); + jp.parse(doc); + + HashMap appenderBag = + (HashMap) ec.getObjectMap().get(ActionConst.APPENDER_BAG); + Appender appender = (Appender) appenderBag.get("A1"); + PatternLayout pl = (PatternLayout) appender.getLayout(); + assertEquals("org.apache.log4j.toto", pl.getRuleRegistry().get("toto")); } } 1.24 +15 -15 jakarta-log4j/src/java/org/apache/log4j/PatternLayout.java Index: PatternLayout.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/PatternLayout.java,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- PatternLayout.java 18 Sep 2003 21:26:55 -0000 1.23 +++ PatternLayout.java 23 Sep 2003 18:52:51 -0000 1.24 @@ -62,21 +62,21 @@ // Anders Kristensen <[EMAIL PROTECTED]> /** - - A flexible layout configurable with pattern string. - - <p>The goal of this class is to [EMAIL PROTECTED] #format format} a [EMAIL PROTECTED] - LoggingEvent} and return the results as a String. The results - depend on the <em>conversion pattern</em>. - - <p>The conversion pattern is closely related to the conversion - pattern of the printf function in C. A conversion pattern is - composed of literal text and format control expressions called - <em>conversion specifiers</em>. - - <p><i>You are free to insert any literal text within the conversion - pattern.</i> - + * <p>A flexible layout configurable with pattern string. The goal of this class + * is to [EMAIL PROTECTED] #format format} a [EMAIL PROTECTED] LoggingEvent} and return the results + * in a {#link StringBuffer}. The format of the result depensd on the + * <em>conversion pattern</em>. + * <p> + * + * <p>The conversion pattern is closely related to the conversion + * pattern of the printf function in C. A conversion pattern is + * composed of literal text and format control expressions called + * <em>conversion specifiers</em>. + * + * <p><i>Note that you are free to insert any literal text within the + * conversion pattern.</i> + * </p> + <p>Each conversion specifier starts with a percent sign (%) and is followed by optional <em>format modifiers</em> and a <em>conversion character</em>. The conversion character specifies the type of
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]