You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ce...@apache.org on 2005/01/13 17:12:26 UTC
cvs commit: logging-log4j/tests/src/java/org/apache/log4j/joran/action TouchAction.java
ceki 2005/01/13 08:12:26
Modified: src/java/org/apache/log4j/joran/spi Interpreter.java
src/java/org/apache/log4j/joran/action AppenderAction.java
Action.java
tests/src/java/org/apache/log4j/joran InterpreterTest.java
tests build.xml
tests/src/java/org/apache/log4j/joran/action
TouchAction.java
Added: src/java/org/apache/log4j/joran/spi ActionException.java
tests/src/java/org/apache/log4j/joran
SkippingInInterpreterTest.java
tests/input/joran badEnd1.xml badEnd2.xml
Removed: tests/input/joran exception2.xml
Log:
- By thowing an ActionExcetion an Action can now signal the joran Interpreter to skip processing children or following siblings.
- Added corresponding test cases
Revision Changes Path
1.3 +41 -10 logging-log4j/src/java/org/apache/log4j/joran/spi/Interpreter.java
Index: Interpreter.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/spi/Interpreter.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Interpreter.java 12 Jan 2005 18:04:36 -0000 1.2
+++ Interpreter.java 13 Jan 2005 16:12:25 -0000 1.3
@@ -17,7 +17,6 @@
package org.apache.log4j.joran.spi;
import org.apache.log4j.LogManager;
-import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.joran.action.Action;
import org.apache.log4j.joran.action.ImplicitAction;
import org.apache.log4j.spi.Component;
@@ -124,11 +123,6 @@
//LogLog.debug("in startElement <" + tagName + ">");
pattern.push(tagName);
-
- if(skip != null) {
- System.out.println("Skipping nested <"+tagName+"> element.");
- }
-
List applicableActionList = getApplicableActionList(pattern, atts);
@@ -149,9 +143,14 @@
public void endElement(String namespaceURI, String localName, String qName) {
List applicableActionList = (List) actionListStack.pop();
- if(skip != null && skip.equals(pattern)) {
- System.out.println("Setting skipping to null");
- skip = null;
+ if(skip != null) {
+ //System.err.println("In End, pattern is "+pattern+", skip pattern "+skip);
+ if(skip.equals(pattern)) {
+ getLogger().info("Skipping discontinued. Normall processing will continue with the following element.");
+ skip = null;
+ } else {
+ getLogger().info("Skipping invoking end() method for <{}>.", localName);
+ }
} else if (applicableActionList != EMPTY_LIST) {
callEndAction(applicableActionList, getTagName(localName, qName));
}
@@ -224,6 +223,11 @@
return;
}
+ if(skip != null) {
+ getLogger().debug("Skipping invoking end() method for <{}>.", pattern);
+ return;
+ }
+
Iterator i = applicableActionList.iterator();
while (i.hasNext()) {
@@ -233,9 +237,22 @@
// exceptions
try {
action.begin(ec, tagName, atts);
+ } catch( ActionException ae) {
+ switch(ae.getSkipCode()) {
+ case ActionException.SKIP_CHILDREN:
+ skip = (Pattern) pattern.clone();
+ break;
+ case ActionException.SKIP_SIBLINGS:
+ skip = (Pattern) pattern.clone();
+ // pretend the exception came from one level up. This will cause
+ // all children and following siblings elements to be skipped
+ skip.pop();
+ break;
+ }
+ getLogger().info("Skip pattern set to: "+skip);
} catch (Exception e) {
skip = (Pattern) pattern.clone();
- System.out.println("Skip pattern set to "+skip);
+ getLogger().info("Skip pattern set to: "+skip);
ec.addError(new ErrorItem("Exception in Action for tag <"+tagName+">", e));
}
}
@@ -255,8 +272,22 @@
// any eventual exceptions
try {
action.end(ec, tagName);
+ } catch( ActionException ae) {
+ switch(ae.getSkipCode()) {
+ case ActionException.SKIP_CHILDREN:
+ // after end() is called there can't be any children
+ break;
+ case ActionException.SKIP_SIBLINGS:
+ skip = (Pattern) pattern.clone();
+ skip.pop();
+ break;
+ }
+ getLogger().info("Skip pattern set to: "+skip);
} catch(Exception e) {
ec.addError(new ErrorItem("Exception in Action for tag <"+tagName+">", e));
+ skip = (Pattern) pattern.clone();
+ skip.pop(); // induce the siblings to be skipped
+ getLogger().info("Skip pattern set to <{}>.", skip);
}
}
}
1.1 logging-log4j/src/java/org/apache/log4j/joran/spi/ActionException.java
Index: ActionException.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;
/**
* By throwing an exception an action can signal the Interpreter to skip
* processing, all the nested elements nested within the element throwing the
* exception or skip all following sibling elements in the document.
*
* @author <a href="http://www.qos.ch/log4j/">Ceki Gulcu</a>
*/
public class ActionException extends Exception {
/**
* SKIP_CHILDREN signals the {@link Interpreter} to skip processing all the
* nested elements contained within the element causing this ActionException.
*/
public static final int SKIP_CHILDREN = 1;
/**
* SKIP_SIBLINGS signals the {@link Interpreter} to skip processing all the
* children of this element as well as all the siblings of this elements,
* including any children they may have.
*/
public static final int SKIP_SIBLINGS = 2;
final Throwable rootCause;
final int skipCode;
public ActionException(final int skipCode) {
this(skipCode, null);
}
public ActionException(final int skipCode, final Throwable rootCause) {
this.skipCode = skipCode;
this.rootCause = rootCause;
}
public Throwable getCause() {
return rootCause;
}
public int getSkipCode() {
return skipCode;
}
}
1.20 +8 -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.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- AppenderAction.java 12 Jan 2005 18:04:37 -0000 1.19
+++ AppenderAction.java 13 Jan 2005 16:12:26 -0000 1.20
@@ -20,6 +20,7 @@
import org.apache.log4j.Appender;
import org.apache.log4j.helpers.Option;
import org.apache.log4j.helpers.OptionConverter;
+import org.apache.log4j.joran.spi.ActionException;
import org.apache.log4j.joran.spi.ExecutionContext;
import org.apache.log4j.spi.ErrorItem;
import org.apache.log4j.spi.LoggerRepository;
@@ -40,9 +41,13 @@
* The appender thus generated is placed in the ExecutionContext appender bag.
*/
public void begin(
- ExecutionContext ec, String localName, Attributes attributes) {
+ ExecutionContext ec, String localName, Attributes attributes) throws ActionException {
String className = attributes.getValue(CLASS_ATTRIBUTE);
+ // We are just beginning, reset variables
+ appender = null;
+ inError = false;
+
try {
getLogger().debug("About to instantiate appender of type [{}]", className);
@@ -72,12 +77,13 @@
getLogger().debug("Pushing appender on to the object stack.");
ec.pushObject(appender);
- } catch (Throwable oops) {
+ } catch (Exception oops) {
inError = true;
getLogger().error(
"Could not create an Appender. Reported error follows.", oops);
ec.addError(
new ErrorItem("Could not create appender of type " + className + "]."));
+ throw new ActionException(ActionException.SKIP_CHILDREN, oops);
}
}
1.2 +3 -2 logging-log4j/src/java/org/apache/log4j/joran/action/Action.java
Index: Action.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/Action.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Action.java 12 Jan 2005 15:04:18 -0000 1.1
+++ Action.java 13 Jan 2005 16:12:26 -0000 1.2
@@ -16,6 +16,7 @@
package org.apache.log4j.joran.action;
+import org.apache.log4j.joran.spi.ActionException;
import org.apache.log4j.joran.spi.ExecutionContext;
import org.apache.log4j.joran.spi.Interpreter;
import org.apache.log4j.spi.ComponentBase;
@@ -53,9 +54,9 @@
* the returned value is 'false', then child elements are ignored.
*/
public abstract void begin(
- ExecutionContext ec, String name, Attributes attributes);
+ ExecutionContext ec, String name, Attributes attributes) throws ActionException ;
- public abstract void end(ExecutionContext ec, String name);
+ public abstract void end(ExecutionContext ec, String name) throws ActionException;
public String toString() {
return this.getClass().getName();
1.2 +2 -52 logging-log4j/tests/src/java/org/apache/log4j/joran/InterpreterTest.java
Index: InterpreterTest.java
===================================================================
RCS file: /home/cvs/logging-log4j/tests/src/java/org/apache/log4j/joran/InterpreterTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InterpreterTest.java 12 Jan 2005 18:04:35 -0000 1.1
+++ InterpreterTest.java 13 Jan 2005 16:12:26 -0000 1.2
@@ -38,10 +38,7 @@
import org.apache.log4j.joran.action.ActionConst;
import org.apache.log4j.joran.action.AppenderAction;
import org.apache.log4j.joran.action.AppenderRefAction;
-import org.apache.log4j.joran.action.BadBeginAction;
-import org.apache.log4j.joran.action.BadEndAction;
import org.apache.log4j.joran.action.ConversionRuleAction;
-import org.apache.log4j.joran.action.HelloAction;
import org.apache.log4j.joran.action.LayoutAction;
import org.apache.log4j.joran.action.LevelAction;
import org.apache.log4j.joran.action.LoggerAction;
@@ -49,7 +46,6 @@
import org.apache.log4j.joran.action.ParamAction;
import org.apache.log4j.joran.action.RootLoggerAction;
import org.apache.log4j.joran.action.StackCounterAction;
-import org.apache.log4j.joran.action.TouchAction;
import org.apache.log4j.joran.spi.ExecutionContext;
import org.apache.log4j.joran.spi.Interpreter;
import org.apache.log4j.joran.spi.Pattern;
@@ -63,7 +59,6 @@
import org.xml.sax.SAXParseException;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Stack;
@@ -389,52 +384,7 @@
assertEquals("Hello John Doe.", str);
}
- public void testException1() throws Exception {
- logger.debug("Starting testException1");
-
- RuleStore rs = new SimpleRuleStore();
- rs.addRule(new Pattern("test"), new NOPAction());
- rs.addRule(new Pattern("test/badBegin"), new BadBeginAction());
- rs.addRule(new Pattern("test/badBegin/touch"), new TouchAction());
- rs.addRule(new Pattern("test/hello"), new HelloAction());
-
- Interpreter jp = new Interpreter(rs);
- ExecutionContext ec = jp.getExecutionContext();
- Map omap = ec.getObjectMap();
-
- SAXParser saxParser = createParser();
- saxParser.parse("file:input/joran/exception1.xml", jp);
- List el = jp.getExecutionContext().getErrorList();
- for(int i = 0; i < el.size(); i++) {
- ((ErrorItem) el.get(i)).dump();
- }
- String str = (String) ec.getObjectMap().get("hello");
- assertEquals("Hello John Doe.", str);
- }
-
- public void testException2() throws Exception {
- logger.debug("Starting testException2");
-
- RuleStore rs = new SimpleRuleStore();
- rs.addRule(new Pattern("test"), new NOPAction());
- rs.addRule(new Pattern("test/badEnd"), new BadEndAction());
- rs.addRule(new Pattern("test/hello"), new HelloAction());
-
- Interpreter jp = new Interpreter(rs);
- ExecutionContext ec = jp.getExecutionContext();
- Map omap = ec.getObjectMap();
-
- SAXParser saxParser = createParser();
- saxParser.parse("file:input/joran/exception2.xml", jp);
- List el = jp.getExecutionContext().getErrorList();
- for(int i = 0; i < el.size(); i++) {
- ((ErrorItem) el.get(i)).dump();
- }
- String str = (String) ec.getObjectMap().get("hello");
- assertEquals("Hello John Doe.", str);
- }
-
- public static Test suite() {
+ public static Test RUNALLsuite() {
TestSuite suite = new TestSuite();
//suite.addTest(new InterpreterTest("testIllFormedXML"));
//suite.addTest(new InterpreterTest("testBasicLoop"));
@@ -442,7 +392,7 @@
//suite.addTest(new InterpreterTest("testParsing2"));
//suite.addTest(new InterpreterTest("testParsing3"))
suite.addTest(new InterpreterTest("testException1"));
- //suite.addTest(new InterpreterTest("testException2"));
+ suite.addTest(new InterpreterTest("testException2"));
return suite;
}
1.1 logging-log4j/tests/src/java/org/apache/log4j/joran/SkippingInInterpreterTest.java
Index: SkippingInInterpreterTest.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;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.joran.action.BadBeginAction;
import org.apache.log4j.joran.action.BadEndAction;
import org.apache.log4j.joran.action.HelloAction;
import org.apache.log4j.joran.action.TouchAction;
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.spi.ErrorItem;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
/**
* Test the way Interpreter skips elements in case of exceptions thrown by
* Actions.
*
* @author Ceki Gulcu
*/
public class SkippingInInterpreterTest extends TestCase {
static final Logger logger = Logger.getLogger(SkippingInInterpreterTest.class);
public SkippingInInterpreterTest(String name) {
super(name);
}
/*
* @see TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
Logger root = Logger.getRootLogger();
root.addAppender(
new ConsoleAppender(new PatternLayout("%r %5p [%t] %c - %m%n")));
}
/*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
LogManager.shutdown();
}
SAXParser createParser() throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
return spf.newSAXParser();
}
public void testChildrenSkipping() throws Exception {
logger.debug("Starting testException1");
RuleStore rs = new SimpleRuleStore();
rs.addRule(new Pattern("test"), new NOPAction());
rs.addRule(new Pattern("test/badBegin"), new BadBeginAction());
rs.addRule(new Pattern("test/badBegin/touch"), new TouchAction());
rs.addRule(new Pattern("test/hello"), new HelloAction());
Interpreter jp = new Interpreter(rs);
ExecutionContext ec = jp.getExecutionContext();
Map omap = ec.getObjectMap();
SAXParser saxParser = createParser();
saxParser.parse("file:input/joran/exception1.xml", jp);
List el = jp.getExecutionContext().getErrorList();
for(int i = 0; i < el.size(); i++) {
((ErrorItem) el.get(i)).dump();
}
String str = (String) ec.getObjectMap().get("hello");
assertEquals("Hello John Doe.", str);
Integer i = (Integer) ec.getObjectMap().get(TouchAction.KEY);
assertNull(i);
}
public void testSkipSiblings() throws Exception {
logger.debug("Starting testException2");
RuleStore rs = new SimpleRuleStore();
rs.addRule(new Pattern("test"), new NOPAction());
rs.addRule(new Pattern("test/badEnd"), new BadEndAction());
rs.addRule(new Pattern("test/badEnd/touch"), new TouchAction());
rs.addRule(new Pattern("test/hello"), new HelloAction());
Interpreter jp = new Interpreter(rs);
ExecutionContext ec = jp.getExecutionContext();
Map omap = ec.getObjectMap();
SAXParser saxParser = createParser();
saxParser.parse("file:input/joran/badEnd1.xml", jp);
String str = (String) ec.getObjectMap().get("hello");
assertNull(str);
Integer i = (Integer) ec.getObjectMap().get(TouchAction.KEY);
assertEquals(2, i.intValue());
}
public void testSkipSiblings2() throws Exception {
logger.debug("Starting testException2");
RuleStore rs = new SimpleRuleStore();
rs.addRule(new Pattern("test"), new NOPAction());
rs.addRule(new Pattern("test/badEnd"), new BadEndAction());
rs.addRule(new Pattern("test/badEnd/touch"), new TouchAction());
rs.addRule(new Pattern("test/hello"), new HelloAction());
Interpreter jp = new Interpreter(rs);
ExecutionContext ec = jp.getExecutionContext();
Map omap = ec.getObjectMap();
SAXParser saxParser = createParser();
saxParser.parse("file:input/joran/badEnd2.xml", jp);
String str = (String) ec.getObjectMap().get("hello");
assertEquals("Hello John Doe.", str);
Integer i = (Integer) ec.getObjectMap().get(TouchAction.KEY);
assertNull(i);
}
public static Test RUNALLsuite() {
TestSuite suite = new TestSuite();
suite.addTest(new SkippingInInterpreterTest("testChildrenSkipping"));
suite.addTest(new SkippingInInterpreterTest("testNoSkipping"));
return suite;
}
}
1.1 logging-log4j/tests/input/joran/badEnd1.xml
Index: badEnd1.xml
===================================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE test>
<test>
<!-- this action throws an exception in the Action.end method -->
<badEnd>
<touch/>
<touch/>
</badEnd>
<hello name="John Doe"></hello>
</test>
1.1 logging-log4j/tests/input/joran/badEnd2.xml
Index: badEnd2.xml
===================================================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE test>
<test>
<isolate>
<!-- badEnd throws an exception in the Action.end method -->
<badEnd>
<touch/>
<touch/>
</badEnd>
</isolate>
<hello name="John Doe"></hello>
</test>
1.93 +13 -2 logging-log4j/tests/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/logging-log4j/tests/build.xml,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -r1.92 -r1.93
--- build.xml 12 Jan 2005 18:04:41 -0000 1.92
+++ build.xml 13 Jan 2005 16:12:26 -0000 1.93
@@ -215,7 +215,10 @@
<!-- ================================================================= -->
<!-- Joran unit tests -->
<!-- ================================================================= -->
- <target name="Joran" depends="Pattern, SimpleStore, Interpreter,
+ <target name="Joran" depends="Pattern,
+ SimpleStore,
+ Interpreter,
+ SkipInInterpreter,
JoranConfigurator"/>
@@ -580,7 +583,15 @@
<test name="org.apache.log4j.joran.InterpreterTest" />
</junit>
</target>
-
+
+ <target name="SkipInInterpreter" depends="check, build, cleanOutputDir">
+ <junit printsummary="yes" fork="yes" haltonfailure="yes">
+ <classpath refid="tests.classpath"/>
+ <formatter type="plain" usefile="false" />
+ <test name="org.apache.log4j.joran.SkippingInInterpreterTest" />
+ </junit>
+ </target>
+
<target name="JoranConfigurator" depends="check, build, cleanOutputDir">
<junit printsummary="yes" fork="yes" haltonfailure="yes">
<classpath refid="tests.classpath"/>
1.2 +9 -2 logging-log4j/tests/src/java/org/apache/log4j/joran/action/TouchAction.java
Index: TouchAction.java
===================================================================
RCS file: /home/cvs/logging-log4j/tests/src/java/org/apache/log4j/joran/action/TouchAction.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TouchAction.java 12 Jan 2005 18:04:36 -0000 1.1
+++ TouchAction.java 13 Jan 2005 16:12:26 -0000 1.2
@@ -24,7 +24,8 @@
public class TouchAction extends Action {
-
+ public static String KEY = "touched";
+
public TouchAction() {
}
/**
@@ -32,7 +33,13 @@
*
*/
public void begin(ExecutionContext ec, String name, Attributes attributes) {
- ec.getObjectMap().put("touch", "x");
+
+ Integer i = (Integer) ec.getObjectMap().get(KEY);
+ if(i == null) {
+ ec.getObjectMap().put(KEY, new Integer(1));
+ } else {
+ ec.getObjectMap().put(KEY, new Integer(i.intValue()+1));
+ }
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org