
Author: ceki Date: Wed Jan 28 22:06:55 2009 New Revision: 2136 Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/AddAction.java logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator1.java logback/trunk/logback-examples/src/main/java/chapter10/calculator/LiteralAction.java logback/trunk/logback-examples/src/main/java/chapter10/calculator/MultiplyAction.java logback/trunk/logback-examples/src/main/java/chapter10/calculator/calculator1.xml logback/trunk/logback-site/src/site/pages/css/common.css logback/trunk/logback-site/src/site/pages/manual/onJoran.html Log: Continuing improving Joran documentation as mandated by LBSITE-25 Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/AddAction.java ============================================================================== --- logback/trunk/logback-examples/src/main/java/chapter10/calculator/AddAction.java (original) +++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/AddAction.java Wed Jan 28 22:06:55 2009 @@ -1,7 +1,7 @@ /** - * Logback: the reliable, fast and flexible logging library for Java. + * Logback: the generic, reliable, fast and flexible logging framework. * - * Copyright (C) 1999-2006, QOS.ch + * Copyright (C) 2000-2009, QOS.ch * * This library is free software, you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -10,8 +10,6 @@ package chapter10.calculator; - - import java.util.EmptyStackException; import org.xml.sax.Attributes; @@ -28,23 +26,23 @@ */ public class AddAction extends Action { - public void begin(InterpretationContext ec, String name, Attributes attributes) { - int first = fetchInteger(ec); - int second = fetchInteger(ec); + public void begin(InterpretationContext ic, String name, Attributes attributes) { + int first = fetchInteger(ic); + int second = fetchInteger(ic); // Push the result of the addition for the following actions. - ec.pushObject(new Integer(first + second)); + ic.pushObject(new Integer(first + second)); } /** * Pop the Integer object at the top of the stack. - * This code illustrates usage of Joran's error handling paradigm. + * This code also illustrates usage of Joran's error handling paradigm. */ - int fetchInteger(InterpretationContext ec) { + int fetchInteger(InterpretationContext ic) { int result = 0; try { - // Pop the object at the top of the exection context stack. - Object o1 = ec.popObject(); + // Pop the object at the top of the interpretation context's stack. + Object o1 = ic.popObject(); if (o1 instanceof Integer) { result = ((Integer) o1).intValue(); @@ -52,20 +50,17 @@ String errMsg = "Object [" + o1 + "] currently at the top of the stack is not an integer."; - ec.addError(errMsg); + ic.addError(errMsg); throw new IllegalArgumentException(errMsg); } } catch (EmptyStackException ese) { - ec.addError(("Expecting an integer on the execution stack.")); + ic.addError(("Expecting an integer on the execution stack.")); throw ese; } return result; } - public void end(InterpretationContext ec, String name) { + public void end(InterpretationContext ic, String name) { // Nothing to do here. - // In general, the end() method of actions associated with elements - // having no children do not need to perform any processing in their - // end() method. } } Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator1.java ============================================================================== --- logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator1.java (original) +++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator1.java Wed Jan 28 22:06:55 2009 @@ -1,7 +1,7 @@ /** - * Logback: the reliable, fast and flexible logging library for Java. + * Logback: the generic, reliable, fast and flexible logging framework. * - * Copyright (C) 1999-2006, QOS.ch + * Copyright (C) 2000-2009, QOS.ch * * This library is free software, you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -16,7 +16,6 @@ import ch.qos.logback.core.Context; import ch.qos.logback.core.ContextBase; import ch.qos.logback.core.joran.action.Action; -import ch.qos.logback.core.joran.spi.JoranException; import ch.qos.logback.core.joran.spi.Pattern; import ch.qos.logback.core.util.StatusPrinter; import chapter10.SimpleConfigurator; @@ -25,18 +24,6 @@ * This examples illustrates collaboration between multiple actions through the * common execution context stack. * - * The first and only argument of this application must be the path to the XML - * file to interpret. There are sample XML files in the - * <em>examples/src/joran/calculator/</em> directory. - * - * For example, - * - * <pre> - * java joran.calculator.Calculator1 examples/src/joran/calculator/calculator1.xml - * </pre> - * - * Please refer to the comments in the source code for more information. - * * @author Ceki Güulcü */ public class Calculator1 { @@ -58,11 +45,8 @@ // link the configurator with its context simpleConfigurator.setContext(context); - try { - simpleConfigurator.doConfigure(args[0]); - } catch (JoranException e) { - // Print any errors that might have occured. - StatusPrinter.print(context); - } + simpleConfigurator.doConfigure(args[0]); + // Print any errors that might have occured. + StatusPrinter.print(context); } } Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/LiteralAction.java ============================================================================== --- logback/trunk/logback-examples/src/main/java/chapter10/calculator/LiteralAction.java (original) +++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/LiteralAction.java Wed Jan 28 22:06:55 2009 @@ -1,7 +1,7 @@ /** - * Logback: the reliable, fast and flexible logging library for Java. + * Logback: the generic, reliable, fast and flexible logging framework. * - * Copyright (C) 1999-2006, QOS.ch + * Copyright (C) 2000-2009, QOS.ch * * This library is free software, you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -17,37 +17,36 @@ import ch.qos.logback.core.util.OptionHelper; /** - * - * This action converts the value attribute of the associated element to - * an integer and pushes the resulting Integer object on top of the execution + * This action converts the value attribute of the associated element to an + * integer and pushes the resulting Integer object on top of the execution * context stack. - * - * It also illustrates usage of Joran's error handling paradigm. - * + * + * <p>It also illustrates usage of Joran's error reporting/handling paradigm. + * * @author Ceki Gülcü */ public class LiteralAction extends Action { public static String VALUE_ATR = "value"; - public void begin(InterpretationContext ec, String name, Attributes attributes) { + public void begin(InterpretationContext ic, String name, Attributes attributes) { String valueStr = attributes.getValue(VALUE_ATR); if (OptionHelper.isEmpty(valueStr)) { - ec.addError("The literal action requires a value attribute"); + ic.addError("The literal action requires a value attribute"); return; } try { Integer i = Integer.valueOf(valueStr); - ec.pushObject(i); + ic.pushObject(i); } catch (NumberFormatException nfe) { - ec.addError("The value [" + valueStr + "] could not be converted to an Integer", - nfe); + ic.addError("The value [" + valueStr + + "] could not be converted to an Integer", nfe); throw nfe; } } - public void end(InterpretationContext ec, String name) { + public void end(InterpretationContext ic, String name) { // Nothing to do here. // In general, the end() method of actions associated with elements // having no children do not need to perform any processing in their Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/MultiplyAction.java ============================================================================== --- logback/trunk/logback-examples/src/main/java/chapter10/calculator/MultiplyAction.java (original) +++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/MultiplyAction.java Wed Jan 28 22:06:55 2009 @@ -1,7 +1,7 @@ /** * Logback: the generic, reliable, fast and flexible logging framework. * - * Copyright (C) 1999-2006, QOS.ch + * Copyright (C) 2000-2009, QOS.ch * * This library is free software, you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -10,7 +10,6 @@ package chapter10.calculator; - import org.xml.sax.Attributes; import ch.qos.logback.core.joran.action.Action; @@ -18,53 +17,47 @@ import java.util.EmptyStackException; - /** - * - * This action multiplies the two integers at the top of the stack (they are removed) - * and pushes the result on top the stack. - * + * + * This action multiplies the two integers at the top of the stack (they are + * removed) and pushes the result on top the stack. + * * @author Ceki Gülcü */ public class MultiplyAction extends Action { - - - public void begin(InterpretationContext ec, String name, Attributes attributes) { - int first = fetchInteger(ec); - int second = fetchInteger(ec); - ec.pushObject(new Integer(first * second)); + + public void begin(InterpretationContext ic, String name, Attributes attributes) { + int first = fetchInteger(ic); + int second = fetchInteger(ic); + ic.pushObject(new Integer(first * second)); } /** - * Pop the Integer object at the top of the stack. - * This code illustrates usage of Joran's error handling paradigm. + * Pop the Integer object at the top of the stack. This code illustrates usage + * of Joran's error handling paradigm. */ - int fetchInteger(InterpretationContext ec) { + int fetchInteger(InterpretationContext ic) { int result = 0; try { - Object o1 = ec.popObject(); + Object o1 = ic.popObject(); if (o1 instanceof Integer) { result = ((Integer) o1).intValue(); } else { - String errMsg = - "Object [" + o1 - + "] currently at the top of the stack is not an integer."; - ec.addError(errMsg); + String errMsg = "Object [" + o1 + + "] currently at the top of the stack is not an integer."; + ic.addError(errMsg); throw new IllegalArgumentException(errMsg); } } catch (EmptyStackException ese) { - ec.addError("Expecting an integer on the execution stack."); + ic.addError("Expecting an integer on the execution stack."); throw ese; } return result; } - public void end(InterpretationContext ec, String name) { + public void end(InterpretationContext ic, String name) { // Nothing to do here. - // In general, the end() method of actions associated with elements - // having no children do not need to perform any processing in their - // end() method. } } Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/calculator1.xml ============================================================================== --- logback/trunk/logback-examples/src/main/java/chapter10/calculator/calculator1.xml (original) +++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/calculator1.xml Wed Jan 28 22:06:55 2009 @@ -1,6 +1,3 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE computation> - <computation name="total"> <literal value="3"/> </computation> Modified: logback/trunk/logback-site/src/site/pages/css/common.css ============================================================================== --- logback/trunk/logback-site/src/site/pages/css/common.css (original) +++ logback/trunk/logback-site/src/site/pages/css/common.css Wed Jan 28 22:06:55 2009 @@ -18,26 +18,26 @@ margin-top: 1em; } -.source { +.source, .command, .console { border-top: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD; background:#eee; font-family: Courier, "MS Courier New", Prestige, monospace; - padding-bottom: 0.5ex; - padding-top: 0.5ex; padding-left: 1ex; white-space: pre; } -.command { - border-top: 1px solid #DDDDDD; - border-bottom: 1px solid #DDDDDD; - background:#eee; - font-family: Courier, "MS Courier New", Prestige, monospace; +.source { + padding-bottom: 0.5ex; + padding-top: 0.5ex; +} + +.command { padding-bottom: 0ex; padding-top: 0ex; - padding-left: 1ex; - white-space: pre; +} + +.console { } pre { Modified: logback/trunk/logback-site/src/site/pages/manual/onJoran.html ============================================================================== --- logback/trunk/logback-site/src/site/pages/manual/onJoran.html (original) +++ logback/trunk/logback-site/src/site/pages/manual/onJoran.html Wed Jan 28 22:06:55 2009 @@ -126,15 +126,21 @@ problems. </p> - + <h3>Non goals</h3> + + <p>Given its highly dynamic nature, the Joran API is not intended + to be used to parse very large XML documents with many thousands + of elements. + </p> + + <h3><a name="pattern" href="#pattern">Pattern</a></h3> <p>A Joran pattern is essentially a string. There are two kind of - patterns, <em>exact</em> and <em>wildcard</em>. The pattern - "a/b" can be used to match <code><b></code> element nested - within a top-level <code><a></code> element but not a - <code><c></code> element, even if nested within a - <code><b></code> element.</p> + patterns, <em>exact</em> and <em>wildcard</em>. The pattern "a/b" + can be used to match <code><b></code> element nested within a + top-level <code><a></code> element. The "a/b" will not match + any other element, hence the <em>exact</em> match designation.</p> <p>Wildcards can be used to match suffixes or prefixes. For example, the "*/a" pattern can be used to match any suffix ending @@ -145,13 +151,6 @@ <code><a></code> element. </p> - <p>When several rules match the current pattern, then exact - matches override suffix matches, and suffix matches overide prefix - matches. For exact details of implementation, please see the <a - href="../xref/ch/qos/logback/core/joran/spi/SimpleRuleStore.java">SimpleRuleStore</a> - class. - </p> - <h3><a name="action" href="#action">Actions</a></h3> <p>As mentioned above, Joran parsing rules consists of the @@ -190,9 +189,33 @@ <h3><a name="ruleStore" href="#ruleStore">RuleStore</a> </h3> + <p>As mentioned previously, the invocation of actions according to + matching patterns is a central concept in Joran. A rule is an + association of a pattern and an action. Rules are stored in a <a + href="../xref/ch/qos/logback/core/joran/spi/RuleStore.java">RuleStore</a>. + </p> + + <p>As mentioned above, Joran is built on top of the SAX API. As an + XML document is parsed, each element generates events corresponding + to the start, body and end of each element. When a joran + configurator receives these events, it will attempt to find in its + rule store an action corresponding to the <em>current + pattern</em>.. For example, the current pattern for the start, body + or end event of element <em>B</em> nested within a top-level + <em>A</em> element is "A/B". The current pattern is a data + structure maintained automatically by Joran as it receives and + processes SAX events. </p> + + <p>When several rules match the current pattern, then exact + matches override suffix matches, and suffix matches overide prefix + matches. For exact details of implementation, please see the <a + href="../xref/ch/qos/logback/core/joran/spi/SimpleRuleStore.java">SimpleRuleStore</a> + class. + </p> - <h2>Interpretation context</h2> + <h3><a name="interpretationContext" + href="#interpretationContext">Interpretation context</a></h3> <p>To allow various actions to collaborate, the invocation of begin and end methods include an interpretation context as the first @@ -242,8 +265,6 @@ if any, are printed</li> </ul> - - <p>The <em>hello.xml</em> file contains one <hello-world> element, without any other nested elements. See the <em>logback-examples/src/main/java/chapter10/helloWorld/</em> @@ -253,7 +274,14 @@ <p>Running the HelloWorld application with <em>hello.xml</em> file will print "Hello World" on the console.</p> - <p class="source">java chapter10.helloWorld.HelloWorld src/main/java/chapter10/helloWorld/hello.xml</p> + <p class="command">java chapter10.helloWorld.HelloWorld src/main/java/chapter10/helloWorld/hello.xml</p> + + <p>You are highly encourared to poke about this example, by adding + new rules on the rule store, modifying the XML document + (hello.xml) and adding new actions. + </p> + + <!-- ====================================================== --> <h3><a name="calculator" href="#calculator">Collaborating actions</a></h3> @@ -266,15 +294,35 @@ <p>The <em>calculator1.xml</em> file contains a <code>computation</code> element, with a nested - <code>literal</code> element. + <code>literal</code> element. Here are its contents. </p> + <em>Example 10.<span class="autoEx"/>: First calculator example + (logback-examples/src/main/java/chapter10/calculator/calculator1.xml)</em> + + <em> </em> + <p class="source"><computation name="total"> + <literal value="3"/> +</computation></p> + <p>In the <a href="../xref/chapter3/calculator/Calculator1.html"> - <code>Calculator1</code></a> class, we declare various patterns - and actions, that will collaborate and calculate a result based on - the xml file. The simple <em>calculator1.xml</em> file only - creates a computation and declares a literal value. The resulting - parsing is pretty simple: + <code>Calculator1</code></a> application, we declare various + parsing rules (patterns and actions) collaborating together to + compute a result based on the contents of an XML document. + </p> + + <p> Running <code>Calculator1</code> application with + <em>calculator1.xml</em></p> + + <p class="command">java chapter10.calculator.Calculator1 src/main/java/chapter10/calculator/calculator1.xml</p> + + <p>will print:</p> + + <p class="console">The computation named [total] resulted in the value 3</p> + + + <p>Parsing the <em>calculator1.xml</em> document (listed above) + involves the following steps: </p> <ul> @@ -290,15 +338,17 @@ is called</li> </ul> - <p>What is interesting here is the way that the Actions - collaborate. The <code>LiteralAction</code> reads a literal value - and pushes it in the object stack maintained by the + <p>What is interesting here is the way actions collaborate. The + <code>LiteralAction</code> reads a literal value and pushes it in + the object stack maintained by the <code>InterpretationContext</code>. Once done, any other action can pop the value to read or modify it. Here, the <code>end()</code> method of the <code>ComputationAction1</code> class pops the value from the stack and prints it. </p> + <!-- TO BE CONTINUED --> + <p>The <em>calculator2.xml</em> file is a bit more complex, but much more interesting.</p> @@ -544,14 +594,6 @@ <multiply/> </computation></pre></div> - - <h3>Non goals</h3> - - <p>The Joran API is not intended to be used to parse documents with - thousands of elements. - </p> - - <script src="templates/footer.js" type="text/javascript"></script> </div> </body>