logback-dev
Threads by month
- ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
January 2009
- 4 participants
- 46 discussions

[JIRA] Created: (LBCORE-68) Add a pattern resolver to <file> property of FileAppnder
by Nicolas Giraud (JIRA) 03 Feb '09
by Nicolas Giraud (JIRA) 03 Feb '09
03 Feb '09
Add a pattern resolver to <file> property of FileAppnder
--------------------------------------------------------
Key: LBCORE-68
URL: http://jira.qos.ch/browse/LBCORE-68
Project: logback-core
Issue Type: New Feature
Components: Appender, Joran
Affects Versions: 0.9.11
Environment: Ubuntu 8.04, J2SE 6
Reporter: Nicolas Giraud
Assignee: Logback dev list
Following discussion on the mailing list, it would be very convenient to be able to use patterns in the filename of a FileAppender. My initial expectation was to be able to do something like:
<appender name="myFileAppender" class="ch.qos.logback.core.FileAppender">
<file>${logFolder}/SomePrefix.%d.someExt</file>
[...]
</appender>
where %d would be substituted by the current date. However Ralph Goers, when replying to my question on the mailing list, suggested a more flexibl approach:
<appender name="myFileAppender" class="ch.qos.logback.core.FileAppender">
<File resolver="com.mycorp.logback.MyPatternResolver">someName.%{host}.%{datetime}.log</File>
[...]
</appender>
with MyPatternResolver implementing an interface like:
package ch.qos.logback.core.pattern;
public interface Resolver {
String resolve(String pattern);
}
Providing a default implementation allowing to generate timestamp, use system properties, would be nice too.
Currently this can be done programmatically, but it would be most convenient to have the possibility to do this using the Joran configurator.
Best regards,
Nicolas
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
2
1

svn commit: r2136 - in logback/trunk: logback-examples/src/main/java/chapter10/calculator logback-site/src/site/pages/css logback-site/src/site/pages/manual
by noreply.ceki@qos.ch 28 Jan '09
by noreply.ceki@qos.ch 28 Jan '09
28 Jan '09
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>
1
0
Author: ceki
Date: Tue Jan 27 21:10:55 2009
New Revision: 2135
Added:
logback/trunk/logback-examples/src/main/java/chapter10/SimpleConfigurator.java
- copied, changed from r2131, /logback/trunk/logback-examples/src/main/java/chapter3/SimpleConfigurator.java
Removed:
logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/readme.txt
logback/trunk/logback-examples/src/main/java/chapter3/SimpleConfigurator.java
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/RuleStore.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java
logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator1.java
logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator2.java
logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorld.java
logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorldAction.java
logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/hello.xml
logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMe.java
logback/trunk/logback-examples/src/main/java/chapter10/newRule/NewRuleCalculator.java
logback/trunk/logback-site/src/site/pages/manual/onJoran.html
Log:
ongoing work on the javadocs and on chapter 10 (onJoran)
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java Tue Jan 27 21:10:55 2009
@@ -43,10 +43,8 @@
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.
+ * Called when the parser encounters an element matching a
+ * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
*/
public abstract void begin(InterpretationContext ec, String name,
Attributes attributes) throws ActionException;
@@ -56,6 +54,10 @@
// NOP
}
+ /*
+ * Called when the parser encounters an endElement event matching a
+ * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
+ */
public abstract void end(InterpretationContext ec, String name)
throws ActionException;
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java Tue Jan 27 21:10:55 2009
@@ -1,7 +1,7 @@
/**
* Logback: the generic, reliable, fast and flexible logging framework.
*
- * Copyright (C) 2000-2008, 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
@@ -12,6 +12,14 @@
import java.util.ArrayList;
+/**
+ * A pattern is used to designate XML elements in a document.
+ *
+ * <p>For more information see
+ * http://logback.qos.ch/manual/onJoran.html#pattern
+ *
+ * @author Ceki Gülcü
+ */
public class Pattern {
// contains String instances
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/RuleStore.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/RuleStore.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/RuleStore.java Tue Jan 27 21:10:55 2009
@@ -1,24 +1,35 @@
/**
- * LOGBack: the generic, reliable, fast and flexible logging framework.
+ * 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
* Software Foundation.
*/
-
package ch.qos.logback.core.joran.spi;
import java.util.List;
import ch.qos.logback.core.joran.action.Action;
-
-
+/**
+ *
+ * As its name indicates, a RuleStore contains 2-tuples consists of a Pattern
+ * and an Action.
+ *
+ * <p>As a joran configurator goes through the elements in a document, it asks
+ * the rule store whether there are rules matching the current pattern by
+ * invoking the {@link #matchActions(Pattern)} method.
+ *
+ * @author Ceki Gülcü
+ *
+ */
public interface RuleStore {
- public void addRule(Pattern pattern, String actionClassStr) throws ClassNotFoundException;
+ public void addRule(Pattern pattern, String actionClassStr)
+ throws ClassNotFoundException;
+
public void addRule(Pattern pattern, Action action);
-
- public List matchActions(Pattern pattern);
+
+ public List matchActions(Pattern currentPatern);
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java Tue Jan 27 21:10:55 2009
@@ -1,13 +1,12 @@
/**
- * LOGBack: the generic, reliable, fast and flexible logging framework.
+ * 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
* Software Foundation.
*/
-
package ch.qos.logback.core.joran.spi;
import java.util.ArrayList;
@@ -19,29 +18,32 @@
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.util.OptionHelper;
-
-
+/**
+ * This class implements the {@link RuleStore} interface. It is the rule store
+ * implementation used by default in Joran.
+ *
+ * @author Ceki Gülcü
+ *
+ */
public class SimpleRuleStore extends ContextAwareBase implements RuleStore {
// key: Pattern instance, value: ArrayList containing actions
HashMap<Pattern, List<Action>> rules = new HashMap<Pattern, List<Action>>();
-
-// public SimpleRuleStore() {
-// }
+
+ // public SimpleRuleStore() {
+ // }
public SimpleRuleStore(Context context) {
setContext(context);
}
-
+
/**
- * Add a new rule, i.e. a pattern, action pair to the rule store.
- * <p>
- * Note that the added action's LoggerRepository will be set in the
- * process.
+ * Add a new rule, i.e. a pattern, action pair to the rule store. <p> Note
+ * that the added action's LoggerRepository will be set in the process.
*/
public void addRule(Pattern pattern, Action action) {
action.setContext(context);
-
+
List<Action> a4p = rules.get(pattern);
if (a4p == null) {
@@ -54,16 +56,16 @@
public void addRule(Pattern pattern, String actionClassName) {
Action action = null;
-
+
try {
- action = (Action) OptionHelper.instantiateByClassName(
- actionClassName, Action.class, context);
- } catch(Exception e) {
- addError("Could not instantiate class ["+actionClassName+"]", e);
+ action = (Action) OptionHelper.instantiateByClassName(actionClassName,
+ Action.class, context);
+ } catch (Exception e) {
+ addError("Could not instantiate class [" + actionClassName + "]", e);
+ }
+ if (action != null) {
+ addRule(pattern, action);
}
- if(action != null) {
- addRule(pattern, action);
- }
}
// exact match has highest priority
@@ -71,36 +73,34 @@
// tail match for */x/y has higher priority than match for */x
// if no tail match, check for prefix match, i.e. matches for x/*
// match for x/y/* has higher priority than matches for x/*
-
+
public List matchActions(Pattern currentPattern) {
- //System.out.println("pattern to search for:" + pattern + ", hashcode: " + pattern.hashCode());
- //System.out.println("rules:" + rules);
List actionList;
if ((actionList = rules.get(currentPattern)) != null) {
return actionList;
- } else if ( (actionList = tailMatch(currentPattern)) != null){
- return actionList;
+ } else if ((actionList = tailMatch(currentPattern)) != null) {
+ return actionList;
} else if ((actionList = prefixMatch(currentPattern)) != null) {
- //System.out.println(currentPattern + " prefixMatches "+actionList);
+ // System.out.println(currentPattern + " prefixMatches "+actionList);
return actionList;
} else {
return null;
}
}
-
+
List tailMatch(Pattern currentPattern) {
int max = 0;
Pattern longestMatchingPattern = null;
- for (Pattern p: rules.keySet()) {
+ for (Pattern p : rules.keySet()) {
if ((p.size() > 1) && p.get(0).equals("*")) {
int r = currentPattern.getTailMatchLength(p);
- //System.out.println("tailMatch " +r);
+ // System.out.println("tailMatch " +r);
if (r > max) {
- //System.out.println("New longest tailMatch "+p);
+ // System.out.println("New longest tailMatch "+p);
max = r;
longestMatchingPattern = p;
}
@@ -113,21 +113,21 @@
return null;
}
}
-
+
List prefixMatch(Pattern currentPattern) {
int max = 0;
Pattern longestMatchingPattern = null;
- for (Pattern p: rules.keySet()) {
+ for (Pattern p : rules.keySet()) {
String last = p.peekLast();
- if("*".equals(last)) {
+ if ("*".equals(last)) {
int r = currentPattern.getPrefixMatchLength(p);
-
- //System.out.println("r = "+ r + ", p= "+p);
-
+
+ // System.out.println("r = "+ r + ", p= "+p);
+
// to qualify the match length must equal p's size omitting the '*'
- if ((r == p.size()-1) && (r > max)) {
- //System.out.println("New longest prefixMatch "+p);
+ if ((r == p.size() - 1) && (r > max)) {
+ // System.out.println("New longest prefixMatch "+p);
max = r;
longestMatchingPattern = p;
}
@@ -135,23 +135,23 @@
}
if (longestMatchingPattern != null) {
- //System.out.println("prefixMatch will return" +rules.get(longestMatchingPattern));
+ // System.out.println("prefixMatch will return"
+ // +rules.get(longestMatchingPattern));
return rules.get(longestMatchingPattern);
} else {
return null;
}
}
- public String toString() {
- final String TAB = " ";
-
- StringBuilder retValue = new StringBuilder();
-
- retValue.append("SimpleRuleStore ( ")
- .append("rules = ").append(this.rules).append(TAB)
- .append(" )");
-
- return retValue.toString();
+ public String toString() {
+ final String TAB = " ";
+
+ StringBuilder retValue = new StringBuilder();
+
+ retValue.append("SimpleRuleStore ( ").append("rules = ").append(this.rules)
+ .append(TAB).append(" )");
+
+ return retValue.toString();
}
-
+
}
Copied: logback/trunk/logback-examples/src/main/java/chapter10/SimpleConfigurator.java (from r2131, /logback/trunk/logback-examples/src/main/java/chapter3/SimpleConfigurator.java)
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/SimpleConfigurator.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/SimpleConfigurator.java Tue Jan 27 21:10:55 2009
@@ -1,13 +1,13 @@
/**
* 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
* Software Foundation.
*/
-package chapter3;
+package chapter10;
import java.util.List;
import java.util.Map;
@@ -19,6 +19,12 @@
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.joran.spi.RuleStore;
+/**
+ * A minimal configurator extending GenericConfigurator.
+ *
+ * @author Ceki Gücü
+ *
+ */
public class SimpleConfigurator extends GenericConfigurator {
final Map<Pattern, Action> ruleMap;
@@ -35,7 +41,6 @@
@Override
protected void addInstanceRules(RuleStore rs) {
-
for (Pattern pattern : ruleMap.keySet()) {
Action action = ruleMap.get(pattern);
rs.addRule(pattern, action);
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 Tue Jan 27 21:10:55 2009
@@ -19,7 +19,7 @@
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.util.StatusPrinter;
-import chapter3.SimpleConfigurator;
+import chapter10.SimpleConfigurator;
/**
* This examples illustrates collaboration between multiple actions through the
Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator2.java
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator2.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator2.java Tue Jan 27 21:10:55 2009
@@ -18,7 +18,7 @@
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.util.StatusPrinter;
-import chapter3.SimpleConfigurator;
+import chapter10.SimpleConfigurator;
/**
Modified: logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorld.java
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorld.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorld.java Tue Jan 27 21:10:55 2009
@@ -13,35 +13,24 @@
import java.util.HashMap;
import java.util.Map;
-import chapter3.SimpleConfigurator;
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;
/**
- *
+ *
* A hello world example using Joran.
- *
- * The first and only argument of this application must be the path to
- * the XML file to interpret.
- *
- * For example,
- *
-<pre>
- java joran.helloWorld.HelloWorld examples/src/joran/helloWorld/hello.xml
-</pre>
- *
+ *
* @author Ceki Gulcu
*/
public class HelloWorld {
public static void main(String[] args) throws Exception {
Map<Pattern, Action> ruleMap = new HashMap<Pattern, Action>();
- // Associate "hello-world" pattern with HelloWorldAction
+ // Associate "hello-world" pattern with HelloWorldAction
ruleMap.put(new Pattern("hello-world"), new HelloWorldAction());
// Joran needs to work within a context.
@@ -50,11 +39,7 @@
// 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]);
+ StatusPrinter.print(context);
+ }
}
Modified: logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorldAction.java
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorldAction.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorldAction.java Tue Jan 27 21:10:55 2009
@@ -10,18 +10,15 @@
package chapter10.helloWorld;
-
-
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-
/**
* A trivial action that writes "Hello world" on the console.
*
- * See the HelloWorld class for integrating with Joran.
+ * See the {@link HelloWorld} class for integration with Joran.
*
* @author Ceki Gülcü
*/
Modified: logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/hello.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/hello.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/hello.xml Tue Jan 27 21:10:55 2009
@@ -1,5 +1,2 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE hello-world>
-
-<hello-world>
+<hello-world>
</hello-world>
Modified: logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMe.java
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMe.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMe.java Tue Jan 27 21:10:55 2009
@@ -14,7 +14,7 @@
import java.util.List;
import java.util.Map;
-import chapter3.SimpleConfigurator;
+import chapter10.SimpleConfigurator;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.joran.action.Action;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/newRule/NewRuleCalculator.java
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter10/newRule/NewRuleCalculator.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/newRule/NewRuleCalculator.java Tue Jan 27 21:10:55 2009
@@ -20,7 +20,7 @@
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.util.StatusPrinter;
-import chapter3.SimpleConfigurator;
+import chapter10.SimpleConfigurator;
import chapter10.calculator.ComputationAction2;
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 Tue Jan 27 21:10:55 2009
@@ -11,9 +11,7 @@
</head>
<body>
- <script type="text/javascript">
- prefix='../';
- </script>
+ <script type="text/javascript">prefix='../'</script>
<script src="../templates/header.js" type="text/javascript"></script>
<div id="left">
<script src="../templates/left.js" type="text/javascript"></script>
@@ -25,21 +23,23 @@
<h2>Joran in your own applications</h2>
- <p>As we've seen, logback relies on Joran, a mature, flexible and
- powerful configuration framework. Many of the capabilities offered
- by logback modules are only possible on account of Joran.
+ <p>As apparent in previous chapters, logback relies on Joran, a
+ mature, flexible and powerful configuration framework. Many of the
+ capabilities offered by logback modules are only possible on
+ account of Joran. This chapter focuses on Joran, its basic design
+ and its salient features.
</p>
<p>Joran is actually a generic configuration system which can be
used independently of logging. To emphaises this point, we should
mention that the logback-core module does not have a notion of
- loggers. In that spirit, many of the examples related to this
- tutorial, have nothing to do with loggers, appenders or layouts.
+ loggers. In that spirit, most of the examples in this chapter have
+ nothing to do with loggers, appenders or layouts.
</p>
- <p class="red" style="text-decoration: line-through;">The examples
- for this chapter can be found under
- <em>LOGBACK_HOME/logback-examples/src/main/java/chapter3</em>.
+ <p>The examples presented in this chapter can be found under
+ <em>LOGBACK_HOME/logback-examples/src/main/java/chapter10</em>
+ folder.
</p>
<p>To install joran, simply <a href="../download.html">download</a>
@@ -48,36 +48,45 @@
<h2>Historical perspective</h2>
- <p>One of the most powerful features of the Java language is
- reflection. Reflection makes it possible to configure software
- systems declaratively. For example, many important properties of an
- EJB are configured with the <em>ejb.xml</em> file. While EJBs are
- written in Java, many of their properties are specified within the
- <em>ejb.xml</em> file. Similarly, logback settings can be specified
- in a configuration file, expressed in XML format.
- </p>
-
- <p>In log4j, logback's predecessor, <code>DOMConfigurator</code>
- which shipped with log4j version 1.2.x could also parse
- configuration files written in XML. The
- <code>DOMConfigurator</code> was written in a way that forced to
- tweak it each time the structure of the configuration file
- changed. The modified code had to be recompiled and
- redeployed. Just as importantly, the code of the DOMConfigurator
- consists of loops dealing with children elements containing many
- interspersed if/else statements. One could not help but notice
- that that particular code reeked of redundancy. The <a
- href="http://jakarta.apache.org/commons/digester/">digester
- project</a> has shown that it is possible to parse XML files using
- pattern matching rules. At parse time, digester will apply the
- rules that match previously stated patterns. Rule classes are
- usually quite small and specialized. Consequently, they are
- relatively easy to understand and to maintain.
- </p>
-
- <p>Joran is heavily inspired by the commons-digester project but
- uses a slightly different terminology. In commons-digester, a rule
- can be seen as consisting of a pattern and a rule, as shown by the
+ <p>Reflection is a powerful feature of the Java language, making
+ it possible to configure software systems declaratively. For
+ example, many important properties of an EJB are configured with
+ the <em>ejb.xml</em> file. While EJBs are written in Java, many of
+ their properties are specified within the <em>ejb.xml</em>
+ file. Similarly, logback settings can be specified in a
+ configuration file, expressed in XML format. Annotations available
+ in JDK 1.5 and heavily used in EJB 3.0 replace many of directives
+ previously found in XML files. Joran also makes use of annonations
+ but at a much smaller extent. Due to the dynamic nature of logback
+ configuration data (compared to EJBs) Joran's use of annonations
+ is rather limited.
+ </p>
+
+ <p>In log4j, logback's predecessor, the
+ <code>DOMConfigurator</code> class, which is part of log4j version
+ 1.2.x and later, could also parse configuration files written in
+ XML. <code>DOMConfigurator</code> was written in a way that forced
+ us, the developers, to tweak the code each time the structure of
+ the configuration file changed. The modified code had to be
+ recompiled and redeployed. Just as importantly, the code of the
+ <code>DOMConfigurator</code> consisted of loops dealing with
+ children elements containing many interspersed if/else
+ statements. One could not help but notice that that particular
+ code reeked of redundancy and duplication. The <a
+ href="http://jakarta.apache.org/commons/digester/">commons-digester
+ project</a> had shown us that it was possible to parse XML files
+ using pattern matching rules. At parse time, digester would apply
+ rules that matched designated patterns. Rule classes were usually
+ quite small and specialized. Consequently, they were relatively
+ easy to understand and maintain.
+ </p>
+
+ <p>Armed with the <code>DOMConfigurator</code> experience, we
+ began developing <code>Joran</code>, a powerful configuration
+ framework to be used in logback. Joran was largely inspired by the
+ commons-digester project. Nevertheless, it uses a slightly
+ different terminology. In commons-digester, a rule can be seen as
+ consisting of a pattern and a rule, as shown by the
<code>Digester.addRule(String pattern, Rule rule)</code>
method. We find it unnecessarily confusing to have a rule to
consist of itself, not recursively but with a different
@@ -86,19 +95,10 @@
pattern. This relation between patterns and actions lies at the
core of Joran. Quite remarkably, one can deal with quite complex
requirements by using simple patterns, or more precisely with
- exact matches and wildcard matches. For example, the pattern
- <em>a/b</em> will match a <code><b></code> element nested
- within an <code><a></code> element but not a
- <code><c></code> element, even if nested within a
- <code><b></code> element. It is also possible to match a
- particular XML element, regardless of its nesting level, by using
- the <em>*</em> wildcard character. For example, the pattern
- <em>*/a</em> will match an <code><a></code> element at any
- nesting position within the document. Other types of patterns, for
- example <em>a/*</em>, are not currently supported by Joran.
+ exact matches and wildcard matches.
</p>
- <h2>SAX or DOM?</h2>
+ <h3>SAX or DOM?</h3>
<p>Due to the event-based architecture of the SAX API, a tool based
on SAX cannot easily deal with forward references, that is,
@@ -118,19 +118,47 @@
order.</em>
</p>
- <p>Joran was first implemented in DOM. However, the author migrated
- to SAX in order to benefit location information, available only with
- the SAX API. Location information allows Joran to display the exact
- line and column number where an error occured, which comes in quite
- handy when hunting down problems.
+ <p>Joran was first implemented in DOM. However, the author
+ migrated to SAX in order to benefit from element location
+ information, available only with the SAX API. Location information
+ allows Joran to display the exact line and column number where an
+ error occured, which comes in very handy in indentifying parsing
+ problems.
</p>
- <h2>Actions</h2>
+ <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>
+
+ <p>Wildcards can be used to match suffixes or prefixes. For
+ example, the "*/a" pattern can be used to match any suffix ending
+ with "a", that is any <code><a></code> element within an XML
+ document but not any elements nested within <code><a></code>.
+ The "a/*" pattern will match any element prefixed by
+ <code><a></code>, that is any element nested within an
+ <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>Actions extend the
- <code>ch.qos.logback.core.joran.action.Action</code> class which
- consists of the following abstract methods.
+ <p>As mentioned above, Joran parsing rules consists of the
+ association of patterns. Actions extend the <a
+ href="../xref/ch/qos/logback/core/joran/action/Action.html"><code>Action</code></a>
+ class, consisting of the following abstract methods. Other methods
+ have been omitted for berevity.
</p>
@@ -142,135 +170,143 @@
public abstract class Action {
- /**
- * Called when the parser first encounters an element.
- */
- public abstract void begin(ExecutionContext ec,
- String name,
- Attributes attributes);
-
- /**
- * Called when the parser encounters the element end. At
- * this stage, we can assume that child elements, if any,
- * have been processed.
- */
- public abstract void end(ExecutionContext ec, String name);
+ /**
+ * Called when the parser encounters an element matching a
+ * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
+ */
+ public abstract void begin(InterpretationContext ec, String name,
+ Attributes attributes) throws ActionException;
+
+ /*
+ * Called when the parser encounters an endElement event matching a
+ * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
+ */
+ public abstract void end(InterpretationContext ec, String name)
+ throws ActionException;
}</p>
<p>Thus, every action must implement the begin and end methods.</p>
- <h2>Execution context</h2>
+ <h3><a name="ruleStore" href="#ruleStore">RuleStore</a> </h3>
+
+
+
+ <h2>Interpretation context</h2>
<p>To allow various actions to collaborate, the invocation of begin
- and end methods include an execution context as the first
- parameter. The execution context includes an object stack, an object
- map, an error list and a reference to the Joran interpreter invoking
- the action. Please see the
- <code>ch.qos.logback.core.joran.spi.ExecutionContext</code> class
- for the exact list of fields contained in the execution context.
+ and end methods include an interpretation context as the first
+ parameter. The interpretation context includes an object stack, an
+ object map, an error list and a reference to the Joran interpreter
+ invoking the action. Please see the <a
+ href="../xref/ch/qos/logback/core/joran/spi/InterpretationContext.html"><code>InterpretationContext</code></a>
+ class for the exact list of fields contained in the interpretation
+ context.
</p>
<p>Actions can collaborate together by fetching, pushing or popping
objects from the common object stack, or by putting and fetching
keyed objects on the common object map. Actions can report any error
- conditions by adding error items on the execution context's
+ conditions by adding error items on the interpretation context's
<code>StatusManager</code>.
</p>
- <a name="helloWorld"></a>
- <h3>A hello world example</h3>
+ <h3><a name="helloWorld" href="#helloWorld">Hello world</a></h3>
- <p>The <em>logback-examples/src/main/java/chapter3/helloWorld/</em>
- directory includes a trivial action and Joran interpreter setup
- which just displays <em>Hello World</em> when a <hello-world>
- element is encountered in an XML file. It also includes the basic
- steps which are necessary to set up and invoke a Joran interpreter.
+ <p>The first example in this chapter illustrates the minimal
+ plumbing required for using Joran. The example consists of a
+ trivial action called <a
+ href="../xref/chapter10/helloWorld/HelloWorldAction.html">
+ <code>HelloWorldAction</code></a> which prints "Hello World" on the
+ console when it's <code>begin()</code> method is invoked. The
+ parsing of XML files is done by a configurator. For the purposes of
+ this chapter, we have developped a very simple configurator called
+ <a
+ href="../xref/chapter10/SimpleConfigurator.html"><code>SimpleConfigurator</code></a>.
+ The <a
+ href="../xref/chapter10/helloWorld/HelloWorld.html"><code>HelloWorld</code></a>
+ application brings all pieces together.
</p>
- <p>The <em>hello.xml</em> file contains only one element, without
- any other nested elements. The <a
- href="../xref/chapter3/helloWorld/HelloWorldAction.html">
- <code>HelloWorldAction</code></a> class is a trivial implementation:
- it only prints "Hello World" in the console when it's
- <code>begin()</code> method is called.
- </p>
-
- <p> <a
- href="../xref/chapter3/helloWorld/HelloWorld.html"><code>HelloWorld</code></a>
- is a class that sets up the Joran interpreter, with the minimal
- steps necessary:
- </p>
-
- <ul>
- <li>It creates a <code>RuleStore</code> and a <code>Context</code></li>
- <li>It adds the <em>hello-world</em> pattern, with it's corresponding action</li>
- <li>It creates a Joran interpreter, and passes the <code>RuleStore</code></li>
- <li>It creates a SAX parser and parses the given file, specifying the newly created
- Joran interpreter as the <code>ContentHandler</code></li>
- </ul>
-
- <p>It's last step is to print the content of the
- <code>Context</code>. Since Joran uses logback's powerfull
- <code>Status</code> objects for error reporting, one can have a good
- feedback on what happened during the parsing.
- </p>
+ <ul>
+ <li>It creates a map of rules and a <code>Context</code></li>
+ <li>It creates a parsing rule by associating the
+ <em>hello-world</em> pattern with a corresponding
+ <code>HelloWorldAction</code> instance</li>
+ <li>It creates a <code>SimpleConfigutator</code>, passing it the
+ aforementioned rules map</li>
+ <li>it then invokes the <code>doConfigure</code> method of the
+ configurator, passing the designated XML file as parameter
+ </li>
+ <li>as a last step, the accumulated Status message in the context,
+ if any, are printed</li>
+ </ul>
- <p>In this example, the parsing is rather simple. The
- <em>hello-world</em> element will activate
- <code>HelloWorldAction</code>'s <code>begin()</code> and
- <code>end()</code> methods. In the first method, a simple call to
- <code>System.out.println()</code> will be issued, displaying
- <em>Hello World</em> in the console.
- </p>
- <a name="calculator"></a>
- <h3>Collaborating actions</h3>
+
+ <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>
+ folder for exact contents.
+ </p>
+
+ <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>The <em>logback-examples/src/main/java/joran/calculator/</em>
- directory includes several actions which collaborate together
- through the common object stack in order to accomplish simple
- computations.
- </p>
+ <h3><a name="calculator" href="#calculator">Collaborating
+ actions</a></h3>
+
+ <p>The <em>logback-examples/src/main/java/joran/calculator/</em>
+ directory includes several actions which collaborate together
+ through the common object stack in order to accomplish simple
+ computations.
+ </p>
- <p>The <em>calculator1.xml</em> file contains a <code>computation</code>
- element, with a nested <code>literal</code> element.
- </p>
+ <p>The <em>calculator1.xml</em> file contains a
+ <code>computation</code> element, with a nested
+ <code>literal</code> element.
+ </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:
- </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:
+ </p>
- <ul>
- <li>The <a href="../xref/chapter3/calculator/ComputationAction1.html">
- <code>ComputationAction1</code></a> class' <code>begin()</code> method
- is called</li>
- <li>The <a href="../xref/chapter3/calculator/LiteralAction.html">
- <code>LiteralAction</code></a> class' <code>begin()</code> and <code>end()</code>
- methods are called</li>
- <li>The <a href="../xref/chapter3/calculator/ComputationAction1.html">
- <code>ComputationAction1</code></a> class' <code>end()</code> method
- 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
- <code>ExecutionContext</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>
+ <ul>
+ <li>The <a
+ href="../xref/chapter3/calculator/ComputationAction1.html">
+ <code>ComputationAction1</code></a> class' <code>begin()</code>
+ method is called</li>
+ <li>The <a href="../xref/chapter3/calculator/LiteralAction.html">
+ <code>LiteralAction</code></a> class' <code>begin()</code> and <code>end()</code>
+ methods are called</li>
+ <li>The <a href="../xref/chapter3/calculator/ComputationAction1.html">
+ <code>ComputationAction1</code></a> class' <code>end()</code> method
+ 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
+ <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>
- <p>The <em>calculator2.xml</em> file is a bit more complex, but much
- more interesting.</p>
+ <p>The <em>calculator2.xml</em> file is a bit more complex, but
+ much more interesting.</p>
- <p>It contains the following elements:</p>
+ <p>It contains the following elements:</p>
- <em>Example 3.<span class="autoEx"/>: Calculator configuration file (logback-examples/src/main/java/chapter3/calculator/calculator2.xml)</em>
+ <em>Example 3.<span class="autoEx"/>: Calculator configuration
+ file
+ (logback-examples/src/main/java/chapter3/calculator/calculator2.xml)</em>
<div class="source"><pre><computation name="toto">
<literal value="7"/>
<literal value="3"/>
@@ -326,67 +362,7 @@
by one <code>begin()</code> will be consumed only by the matching
<code>end()</code> method.</p>
- <a name="newRule"></a>
-
- <h3>New-rule action</h3>
-
- <p>Joran includes an action which allows the Joran interpreter to
- lean new rules on the fly while interpreting the XML file containing
- the new rules. See the
- <em>logback-examples/src/main/java/joran/newRule/</em> directory for
- sample code.
- </p>
-
- <p>In this package, the <a
- href="../xref/chapter3/newRule/NewRuleCalculator.html">
- <code>NewRuleCalculator</code></a> class contains the same setup as
- we have seen so far, but for one line:</p>
-
- <p class="source">ruleStore.addRule(new
- Pattern("/computation/new-rule"), new NewRuleAction());</p>
-
- <p>By adding this line, we ask Joran to allow new rules to be learnt
- at parsing time. It works pretty much like the other rules: it has a
- <code>begin()</code> and <code>end()</code> method, and is called each time
- the parser finds a <em>new-rule</em> element.</p>
-
- <p>When called, the <code>begin()</code> method looks for a
- <em>pattern</em> and a <em>actionClass</em> attribute. The action
- class is then instanciated and added to the <code>RuleStore</code>,
- along with its corresponding pattern.</p>
-
- <p>Here is how new rules can be declared in an xml file:</p>
-
-<div class="source"><pre><new-rule pattern="*/computation/literal"
-actionClass="chapter3.calculator.LiteralAction"/></pre></div>
-
- <p>Using new rule declarations, the preceding example, involving the
- calculation, could be expressed this way:</p>
-
- <em>Example 3.<span class="autoEx"/>: Configuration file using new
- rules on the fly
- (logback-examples/src/main/java/chapter3/newrule/new-rule.xml)</em>
-
-<div class="source"><pre><computation name="toto">
- <new-rule pattern="*/computation/literal"
- actionClass="chapter3.calculator.LiteralAction"/>
- <new-rule pattern="*/computation/add"
- actionClass="chapter3.calculator.AddAction"/>
- <new-rule pattern="*/computation/multiply"
- actionClass="chapter3.calculator.MultiplyAction"/>
-
- <computation>
- <literal value="7"/>
- <literal value="3"/>
- <add/>
- </computation>
-
- <literal value="3"/>
- <multiply/>
-</computation></pre></div>
-
- <a name="implicit"></a>
- <h3>Implicit actions </h3>
+ <h3><a name="implicit" href="#implicit">Implicit actions</a></h3>
<p>The rules defined thus far are called explicit rules because they
require an explicit pattern, hence fixing the tag name of the
@@ -503,12 +479,72 @@
<div class="source"><pre>Element <xyz> asked to be printed.
Element <abc> asked to be printed.
-ERROR in ch.qos.logback.core.joran.spi.ExecutionContext@1c5c1 - no applicable action \
+ERROR in ch.qos.logback.core.joran.spi.InterpretationContext@1c5c1 - no applicable action \
for <xyz>, current pattern is [/foo/xyz]</pre></div>
<p>The last line was printed because of a call to
<code>StatusPrinter</code> at the end of the main class.</p>
+ <a name="newRule"></a>
+
+ <h3>New-rule action</h3>
+
+ <p>Joran includes an action which allows the Joran interpreter to
+ lean new rules on the fly while interpreting the XML file containing
+ the new rules. See the
+ <em>logback-examples/src/main/java/joran/newRule/</em> directory for
+ sample code.
+ </p>
+
+ <p>In this package, the <a
+ href="../xref/chapter3/newRule/NewRuleCalculator.html">
+ <code>NewRuleCalculator</code></a> class contains the same setup as
+ we have seen so far, but for one line:</p>
+
+ <p class="source">ruleStore.addRule(new
+ Pattern("/computation/new-rule"), new NewRuleAction());</p>
+
+ <p>By adding this line, we ask Joran to allow new rules to be learnt
+ at parsing time. It works pretty much like the other rules: it has a
+ <code>begin()</code> and <code>end()</code> method, and is called each time
+ the parser finds a <em>new-rule</em> element.</p>
+
+ <p>When called, the <code>begin()</code> method looks for a
+ <em>pattern</em> and a <em>actionClass</em> attribute. The action
+ class is then instanciated and added to the <code>RuleStore</code>,
+ along with its corresponding pattern.</p>
+
+ <p>Here is how new rules can be declared in an xml file:</p>
+
+ <p class="source"><new-rule pattern="*/computation/literal"
+actionClass="chapter10.calculator.LiteralAction"/></p>
+
+ <p>Using new rule declarations, the preceding example, involving the
+ calculation, could be expressed this way:</p>
+
+ <em>Example 3.<span class="autoEx"/>: Configuration file using new
+ rules on the fly
+ (logback-examples/src/main/java/chapter3/newrule/new-rule.xml)</em>
+
+<div class="source"><pre><computation name="toto">
+ <new-rule pattern="*/computation/literal"
+ actionClass="chapter3.calculator.LiteralAction"/>
+ <new-rule pattern="*/computation/add"
+ actionClass="chapter3.calculator.AddAction"/>
+ <new-rule pattern="*/computation/multiply"
+ actionClass="chapter3.calculator.MultiplyAction"/>
+
+ <computation>
+ <literal value="7"/>
+ <literal value="3"/>
+ <add/>
+ </computation>
+
+ <literal value="3"/>
+ <multiply/>
+</computation></pre></div>
+
+
<h3>Non goals</h3>
<p>The Joran API is not intended to be used to parse documents with
1
0

svn commit: r2134 - in logback/trunk/logback-examples/src/main/java: chapter10 chapter10/calculator chapter10/helloWorld chapter10/implicit chapter10/newRule chapter3/calculator chapter3/helloWorld chapter3/implicit chapter3/newRule
by noreply.ceki@qos.ch 26 Jan '09
by noreply.ceki@qos.ch 26 Jan '09
26 Jan '09
Author: ceki
Date: Mon Jan 26 17:57:29 2009
New Revision: 2134
Added:
logback/trunk/logback-examples/src/main/java/chapter10/
logback/trunk/logback-examples/src/main/java/chapter10/calculator/
- copied from r2131, /logback/trunk/logback-examples/src/main/java/chapter3/calculator/
logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/
- copied from r2131, /logback/trunk/logback-examples/src/main/java/chapter3/helloWorld/
logback/trunk/logback-examples/src/main/java/chapter10/implicit/
- copied from r2131, /logback/trunk/logback-examples/src/main/java/chapter3/implicit/
logback/trunk/logback-examples/src/main/java/chapter10/newRule/
- copied from r2131, /logback/trunk/logback-examples/src/main/java/chapter3/newRule/
Removed:
logback/trunk/logback-examples/src/main/java/chapter3/calculator/
logback/trunk/logback-examples/src/main/java/chapter3/helloWorld/
logback/trunk/logback-examples/src/main/java/chapter3/implicit/
logback/trunk/logback-examples/src/main/java/chapter3/newRule/
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/Calculator2.java
logback/trunk/logback-examples/src/main/java/chapter10/calculator/ComputationAction1.java
logback/trunk/logback-examples/src/main/java/chapter10/calculator/ComputationAction2.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/helloWorld/HelloWorld.java
logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorldAction.java
logback/trunk/logback-examples/src/main/java/chapter10/implicit/NOPAction.java
logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMe.java
logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMeImplicitAction.java
logback/trunk/logback-examples/src/main/java/chapter10/newRule/NewRuleCalculator.java
Log:
Moving joran related examples to chapter 10
Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/AddAction.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/calculator/AddAction.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/AddAction.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.calculator;
+package chapter10.calculator;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator1.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/calculator/Calculator1.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator1.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.calculator;
+package chapter10.calculator;
import java.util.HashMap;
import java.util.Map;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator2.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/calculator/Calculator2.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/Calculator2.java Mon Jan 26 17:57:29 2009
@@ -7,7 +7,7 @@
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-package chapter3.calculator;
+package chapter10.calculator;
import java.util.HashMap;
import java.util.Map;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/ComputationAction1.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/calculator/ComputationAction1.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/ComputationAction1.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.calculator;
+package chapter10.calculator;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/ComputationAction2.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/calculator/ComputationAction2.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/ComputationAction2.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.calculator;
+package chapter10.calculator;
import java.util.Stack;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/LiteralAction.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/calculator/LiteralAction.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/LiteralAction.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.calculator;
+package chapter10.calculator;
import org.xml.sax.Attributes;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/calculator/MultiplyAction.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/calculator/MultiplyAction.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/calculator/MultiplyAction.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.calculator;
+package chapter10.calculator;
import org.xml.sax.Attributes;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorld.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/helloWorld/HelloWorld.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorld.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.helloWorld;
+package chapter10.helloWorld;
import java.util.HashMap;
import java.util.Map;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorldAction.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/helloWorld/HelloWorldAction.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/helloWorld/HelloWorldAction.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.helloWorld;
+package chapter10.helloWorld;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/implicit/NOPAction.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/implicit/NOPAction.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/implicit/NOPAction.java Mon Jan 26 17:57:29 2009
@@ -1,13 +1,13 @@
/**
- * 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
* Software Foundation.
*/
-package chapter3.implicit;
+package chapter10.implicit;
import org.xml.sax.Attributes;
@@ -15,7 +15,6 @@
import ch.qos.logback.core.joran.spi.InterpretationContext;
-
/**
* No operation (NOP) action that does strictly nothing.
*
@@ -26,7 +25,6 @@
public void begin(InterpretationContext ec, String name, Attributes attributes) {
}
-
public void end(InterpretationContext ec, String name) {
}
}
Modified: logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMe.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/implicit/PrintMe.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMe.java Mon Jan 26 17:57:29 2009
@@ -7,7 +7,7 @@
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-package chapter3.implicit;
+package chapter10.implicit;
import java.util.ArrayList;
import java.util.HashMap;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMeImplicitAction.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/implicit/PrintMeImplicitAction.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/implicit/PrintMeImplicitAction.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.implicit;
+package chapter10.implicit;
import org.xml.sax.Attributes;
Modified: logback/trunk/logback-examples/src/main/java/chapter10/newRule/NewRuleCalculator.java
==============================================================================
--- /logback/trunk/logback-examples/src/main/java/chapter3/newRule/NewRuleCalculator.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter10/newRule/NewRuleCalculator.java Mon Jan 26 17:57:29 2009
@@ -8,7 +8,7 @@
* Software Foundation.
*/
-package chapter3.newRule;
+package chapter10.newRule;
import java.util.HashMap;
import java.util.Map;
@@ -21,7 +21,7 @@
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.util.StatusPrinter;
import chapter3.SimpleConfigurator;
-import chapter3.calculator.ComputationAction2;
+import chapter10.calculator.ComputationAction2;
/**
1
0

svn commit: r2133 - logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action
by noreply.ceki@qos.ch 26 Jan '09
by noreply.ceki@qos.ch 26 Jan '09
26 Jan '09
Author: ceki
Date: Mon Jan 26 17:37:33 2009
New Revision: 2133
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
Log:
- changes in comments
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java Mon Jan 26 17:37:33 2009
@@ -1,7 +1,7 @@
/**
* Logback: the generic, reliable, fast and flexible logging framework for Java.
*
- * Copyright (C) 2000-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
@@ -20,9 +20,9 @@
/**
*
- * Most of the work for configuring log4j is done by Actions.
+ * Most of the work for configuring logback is done by Actions.
*
- * <p>Methods of an Action are invoked while an XML file is parsed through.
+ * <p>Action methods are invoked as the XML file is parsed.
*
* <p>This class is largely inspired from the relevant class in the
* commons-digester project of the Apache Software Foundation.
1
0

svn commit: r2132 - in logback/trunk/logback-site/src/site/pages: . manual
by noreply.ceki@qos.ch 25 Jan '09
by noreply.ceki@qos.ch 25 Jan '09
25 Jan '09
Author: ceki
Date: Sun Jan 25 19:33:24 2009
New Revision: 2132
Added:
logback/trunk/logback-site/src/site/pages/manual/configuration.html
- copied, changed from r2131, /logback/trunk/logback-site/src/site/pages/manual/joran.html
logback/trunk/logback-site/src/site/pages/manual/onJoran.html
- copied, changed from r2131, /logback/trunk/logback-site/src/site/pages/joran.html
Removed:
logback/trunk/logback-site/src/site/pages/joran.html
logback/trunk/logback-site/src/site/pages/manual/joran.html
Modified:
logback/trunk/logback-site/src/site/pages/.htaccess
logback/trunk/logback-site/src/site/pages/documentation.html
logback/trunk/logback-site/src/site/pages/manual/.htaccess
logback/trunk/logback-site/src/site/pages/manual/index.html
logback/trunk/logback-site/src/site/pages/manual/menu.js
Log:
- rearranging the chapter on Joran (it is now part of the manual)
Modified: logback/trunk/logback-site/src/site/pages/.htaccess
==============================================================================
--- logback/trunk/logback-site/src/site/pages/.htaccess (original)
+++ logback/trunk/logback-site/src/site/pages/.htaccess Sun Jan 25 19:33:24 2009
@@ -1 +1,2 @@
-Redirect jmxConfig.html http://logback.qos.ch/manual/jmxConfig.html
\ No newline at end of file
+Redirect jmxConfig.html http://logback.qos.ch/manual/jmxConfig.html
+Redirect joran.html http://logback.qos.ch/manual/onJoran.html
\ No newline at end of file
Modified: logback/trunk/logback-site/src/site/pages/documentation.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/documentation.html (original)
+++ logback/trunk/logback-site/src/site/pages/documentation.html Sun Jan 25 19:33:24 2009
@@ -40,10 +40,6 @@
</li>
<li>
- <a href="joran.html">Using Joran in your applications</a>
- </li>
-
- <li>
<a href="demo.html">Walk-through logback-demo webApp</a>
</li>
<li>
Modified: logback/trunk/logback-site/src/site/pages/manual/.htaccess
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/.htaccess (original)
+++ logback/trunk/logback-site/src/site/pages/manual/.htaccess Sun Jan 25 19:33:24 2009
@@ -1 +1,2 @@
-Redirect contextSelector.html http://logback.qos.ch/manual/loggingSeparation.html
\ No newline at end of file
+Redirect contextSelector.html http://logback.qos.ch/manual/loggingSeparation.html
+Redirect joran.html http://logback.qos.ch/manual/configuration.html
\ No newline at end of file
Copied: logback/trunk/logback-site/src/site/pages/manual/configuration.html (from r2131, /logback/trunk/logback-site/src/site/pages/manual/joran.html)
==============================================================================
--- /logback/trunk/logback-site/src/site/pages/manual/joran.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/configuration.html Sun Jan 25 19:33:24 2009
@@ -4,7 +4,7 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>Chapter3: Logback configuration & Joran</title>
+ <title>Chapter3: Logback configuration</title>
<link rel="stylesheet" type="text/css" href="../css/common.css" />
<link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
@@ -21,7 +21,7 @@
</div>
<div id="content" class="chapter">
- <h1>Chapter 3: Logback configuration & Joran</h1>
+ <h1>Chapter 3: Logback configuration</h1>
<div class="quote">
<p><em>In symbols one observes an advantage in discovery which
Modified: logback/trunk/logback-site/src/site/pages/manual/index.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/index.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/index.html Sun Jan 25 19:33:24 2009
@@ -36,7 +36,7 @@
<li><p>logback configuration scripts in XML format</p></li>
<li><p>appenders</p></li>
<li><p>layouts</p></li>
- <li><p>filter chains</p></li>
+ <li><p>filters</p></li>
<li><p>mapped diagnostic contexts</p></li>
<li><p>logback default initialization</p></li>
<li><p>logback in Servlet Containers</p></li>
@@ -81,7 +81,7 @@
<a href="architecture.html"><b>Chapter 2: Architecture</b></a>
</p></li>
<li><p>
- <a href="joran.html"><b>Chapter 3: Logback configuration with Joran</b></a>
+ <a href="configuration.html"><b>Chapter 3: Configuration</b></a>
</p></li>
<li><p>
@@ -107,6 +107,11 @@
<li><p>
<a href="jmxConfigurator.html"><b>Chapter 9: JMX Configurator</b></a>
</p></li>
+
+ <li><p>
+ <a href="onJoran.html"><b>Chapter 10: Joran</b></a>
+ </p></li>
+
</ul>
</div>
Modified: logback/trunk/logback-site/src/site/pages/manual/menu.js
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/menu.js (original)
+++ logback/trunk/logback-site/src/site/pages/manual/menu.js Sun Jan 25 19:33:24 2009
@@ -2,10 +2,11 @@
document.write('<p class="menu_header">Chapter Index</p>')
document.write('<p class="menu"><a href="introduction.html"><b>Ch1: Introduction to logback</b></a></p>');
document.write('<p class="menu"><a href="architecture.html"><b>Ch2: Architecture</b></a>');
-document.write('<p class="menu"><a href="joran.html"><b>Ch3: Logback configuration with Joran</b></a>');
+document.write('<p class="menu"><a href="configuration.html"><b>Ch3: Configuration</b></a>');
document.write('<p class="menu"><a href="appenders.html"><b>Ch4: Appenders</b></a>');
document.write('<p class="menu"><a href="layouts.html"><b>Ch5: Layouts</b></a>');
document.write('<p class="menu"><a href="filters.html"><b>Ch6: Filter chains</b></a>');
document.write('<p class="menu"><a href="mdc.html"><b>Ch7: Mapped Diagnostic Contexts</b></a>');
document.write('<p class="menu"><a href="loggingSeparation.html"><b>Ch8: Logging Separation</b></a>');
document.write('<p class="menu"><a href="jmxConfig.html"><b>Ch9: JMX Configurator</b></a>');
+document.write('<p class="menu"><a href="onJoran.html"><b>Ch9: Joran</b></a>');
Copied: logback/trunk/logback-site/src/site/pages/manual/onJoran.html (from r2131, /logback/trunk/logback-site/src/site/pages/joran.html)
==============================================================================
--- /logback/trunk/logback-site/src/site/pages/joran.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/onJoran.html Sun Jan 25 19:33:24 2009
@@ -4,25 +4,30 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <title>Using Joran</title>
- <link rel="stylesheet" type="text/css" href="css/common.css" />
- <link rel="stylesheet" type="text/css" href="css/screen.css" media="screen" />
- <link rel="stylesheet" type="text/css" href="css/_print.css" media="print" />
+ <title>Joran</title>
+ <link rel="stylesheet" type="text/css" href="../css/common.css" />
+ <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
+ <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
</head>
<body>
- <script type="text/javascript">prefix='./'</script>
- <script type="text/javascript" src="templates/header.js"></script>
+ <script type="text/javascript">
+ prefix='../';
+ </script>
+ <script src="../templates/header.js" type="text/javascript"></script>
<div id="left">
- <script type="text/javascript" src="templates/left.js"></script>
+ <script src="../templates/left.js" type="text/javascript"></script>
+ </div>
+ <div id="right">
+ <script src="menu.js" type="text/javascript"></script>
</div>
<div id="content">
- <h2>Using Joran in your own applications</h2>
+ <h2>Joran in your own applications</h2>
<p>As we've seen, logback relies on Joran, a mature, flexible and
powerful configuration framework. Many of the capabilities offered
- by logback modules are possible with the help of Joran.
+ by logback modules are only possible on account of Joran.
</p>
<p>Joran is actually a generic configuration system which can be
1
0

svn commit: r2044 - in logback-incubator/trunk/logback-as400/src/main/java/ch: . qos qos/logback qos/logback/as400 qos/logback/as400/io qos/logback/as400/print
by noreply.ravn@qos.ch 23 Jan '09
by noreply.ravn@qos.ch 23 Jan '09
23 Jan '09
Author: ravn
Date: Mon Dec 1 14:03:23 2008
New Revision: 2044
Added:
logback-incubator/trunk/logback-as400/src/main/java/ch/
logback-incubator/trunk/logback-as400/src/main/java/ch/qos/
logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/
logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/
logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/io/
logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/io/FixedWidthPrintStream.java
logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/print/
logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/print/QPrintAppender.java
Log:
initial skeletons for QPrintAppender
Added: logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/io/FixedWidthPrintStream.java
==============================================================================
--- (empty file)
+++ logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/io/FixedWidthPrintStream.java Mon Dec 1 14:03:23 2008
@@ -0,0 +1,85 @@
+package ch.qos.logback.as400.io;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * FixedWidthPrintStream is a stream wrapper which ensures that the output does
+ * not get wider than the specified number of columns.
+ *
+ */
+public class FixedWidthPrintStream {
+
+ protected static final int BEFORE_COLUMN_ZERO = -1;
+
+ private String indent = " +";
+ private int wrapColumn = 79;
+ private PrintStream originalStream;
+
+ private PrintStream thisStream;
+ /**
+ * @param originalStream
+ * @param wrapColumn - first column is column 0.
+ * @param indent
+ */
+
+ public PrintStream getStream() {
+ if (thisStream == null) {
+ thisStream = new PrintStream(new OutputStream() {
+
+ // Next char will go in 0
+ int currentColumn = BEFORE_COLUMN_ZERO;
+
+ public void write(int b) {
+ originalStream.write(b);
+ currentColumn = currentColumn + 1;
+
+ if (b == '\n') {
+ currentColumn = BEFORE_COLUMN_ZERO;
+ } else if (currentColumn >= wrapColumn) {
+ originalStream.write('\n');
+ currentColumn = BEFORE_COLUMN_ZERO;
+ for (int i = 0; i < indent.length(); i++) {
+ originalStream.write(indent.charAt(i));
+ currentColumn = currentColumn + 1;
+ }
+ }
+ }
+
+ public void close() {
+ originalStream.close();
+ }
+
+ public void flush() {
+ originalStream.flush();
+ }
+ });
+ }
+ return thisStream;
+ }
+
+ public int getWrapColumn() {
+ return wrapColumn;
+ }
+
+ public void setWrapColumn(int wrapColumn) {
+ this.wrapColumn = wrapColumn;
+ }
+
+ public PrintStream getOriginalStream() {
+ return originalStream;
+ }
+
+ public void setOriginalStream(PrintStream wrappedStream) {
+ this.originalStream = wrappedStream;
+ }
+
+ public String getIndent() {
+ return indent;
+ }
+
+ public void setIndent(String indent) {
+ this.indent = indent;
+ }
+
+}
Added: logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/print/QPrintAppender.java
==============================================================================
--- (empty file)
+++ logback-incubator/trunk/logback-as400/src/main/java/ch/qos/logback/as400/print/QPrintAppender.java Mon Dec 1 14:03:23 2008
@@ -0,0 +1,20 @@
+package ch.qos.logback.as400.print;
+
+import ch.qos.logback.core.AppenderBase;
+
+/**
+ *
+ *
+ */
+public class QPrintAppender extends AppenderBase {
+
+
+
+ @Override
+ protected void append(Object arg0) {
+
+ }
+
+
+
+}
2
1

[JIRA] Created: (LBCLASSIC-103) Accidental incompatible joran syntax for evaluator filters
by Michael Franz (JIRA) 23 Jan '09
by Michael Franz (JIRA) 23 Jan '09
23 Jan '09
Accidental incompatible joran syntax for evaluator filters
----------------------------------------------------------
Key: LBCLASSIC-103
URL: http://jira.qos.ch/browse/LBCLASSIC-103
Project: logback-classic
Issue Type: Bug
Components: joran
Affects Versions: 0.9.14
Reporter: Michael Franz
Assignee: Logback dev list
The release note for 0.9.14 states: "In addition, EvaluatorAction has been modified to accept evaluators of any type and not just instances of JaninoEvaluator."
Firstly: I could not found this documented within the manual.
Secondly:
The examples for evaluator filters within appenders from the manual do no longer work, e.g. logback-examples/src/main/java/chapter6/basicEventEvaluator.xml:
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator name="myEval">
<expression>message.contains("billing")</expression>
</evaluator>
<OnMismatch>NEUTRAL</OnMismatch>
<OnMatch>DENY</OnMatch>
</filter>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
%-4relative [%thread] %-5level %logger - %msg%n
</pattern>
</layout>
</appender>
The error message is: |-ERROR in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - No class name attribute in [evaluator]
After adding class="ch.qos.logback.classic.boolex.JaninoEventEvaluator" to the evaluator tag it works. But this should not be required.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
2
1
Author: ceki
Date: Fri Jan 23 14:56:31 2009
New Revision: 2131
Added:
logback/trunk/logback-access/src/test/input/joran/
logback/trunk/logback-access/src/test/input/joran/defaultLayout.xml
logback/trunk/logback-access/src/test/input/joran/smoke.xml
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/TeztConstants.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/joran/
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/joran/JoranConfiguratorTest.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java
logback/trunk/logback-classic/src/test/input/joran/sift/defaultLayoutRule.xml
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java
Removed:
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/testUtil/StringListAppender.java
Modified:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/StatusListenerConfigHelper.java
logback/trunk/logback-classic/src/test/input/joran/callerData.xml
logback/trunk/logback-classic/src/test/input/joran/conversionRule/htmlLayout0.xml
logback/trunk/logback-classic/src/test/input/joran/conversionRule/patternLayout0.xml
logback/trunk/logback-classic/src/test/input/joran/evaluatorFilter.xml
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/PatternLayoutTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java
Log:
- Moved StringListAppender from logback-classic/src/test to logback-core/src/test since
logback-access uses it as well.
- Added unit tests in relation with default component class mapping rules in Joran.
See also jira issue LBCLASSIC-103
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java Fri Jan 23 14:56:31 2009
@@ -11,12 +11,15 @@
package ch.qos.logback.access.joran;
+import ch.qos.logback.access.PatternLayout;
import ch.qos.logback.access.joran.action.ConfigurationAction;
import ch.qos.logback.access.joran.action.EvaluatorAction;
import ch.qos.logback.access.sift.SiftAction;
+import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.joran.JoranConfiguratorBase;
import ch.qos.logback.core.joran.action.AppenderRefAction;
import ch.qos.logback.core.joran.action.NOPAction;
+import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.joran.spi.RuleStore;
@@ -41,5 +44,10 @@
rs.addRule(new Pattern("configuration/evaluator"), new EvaluatorAction());
}
+ @Override
+ protected void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ registry.add(AppenderBase.class, "layout", PatternLayout.class);
+ }
}
Added: logback/trunk/logback-access/src/test/input/joran/defaultLayout.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/input/joran/defaultLayout.xml Fri Jan 23 14:56:31 2009
@@ -0,0 +1,13 @@
+<configuration>
+
+ <appender name="STR_LIST"
+ class="ch.qos.logback.core.testUtil.StringListAppender">
+ <!-- the fact that the layout class is not declared tests default component class
+ mapping rules -->
+ <layout>
+ <Pattern>%requestMethod</Pattern>
+ </layout>
+ </appender>
+
+ <appender-ref ref="STR_LIST" />
+</configuration>
\ No newline at end of file
Added: logback/trunk/logback-access/src/test/input/joran/smoke.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/input/joran/smoke.xml Fri Jan 23 14:56:31 2009
@@ -0,0 +1,5 @@
+<configuration>
+
+ <appender name="LIST" class="ch.qos.logback.core.read.ListAppender"/>
+ <appender-ref ref="LIST" />
+</configuration>
\ No newline at end of file
Added: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/TeztConstants.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/TeztConstants.java Fri Jan 23 14:56:31 2009
@@ -0,0 +1,6 @@
+package ch.qos.logback.access;
+
+public class TeztConstants {
+
+ public static final String TEST_DIR_PREFIX = "src/test/";
+}
Modified: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java
==============================================================================
--- logback/trunk/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java (original)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/db/DBAppenderIntegrationTest.java Fri Jan 23 14:56:31 2009
@@ -12,9 +12,7 @@
import org.junit.Ignore;
import org.junit.Test;
-import ch.qos.logback.access.dummy.DummyRequest;
-import ch.qos.logback.access.dummy.DummyResponse;
-import ch.qos.logback.access.dummy.DummyServerAdapter;
+import ch.qos.logback.access.dummy.DummyAccessEventBuilder;
import ch.qos.logback.access.joran.JoranConfigurator;
import ch.qos.logback.access.spi.AccessContext;
import ch.qos.logback.access.spi.AccessEvent;
@@ -59,7 +57,7 @@
Appender<AccessEvent> appender = context.getAppender("DB");
for (int i = 0; i < 10; i++) {
- AccessEvent event = createAccessEvent();
+ AccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
appender.doAppend(event);
}
@@ -128,13 +126,4 @@
doTest("src/test/input/integration/db/postgresql-with-driver.xml");
}
- private AccessEvent createAccessEvent() {
- DummyRequest request = new DummyRequest();
- DummyResponse response = new DummyResponse();
- DummyServerAdapter adapter = new DummyServerAdapter(request, response);
-
- AccessEvent ae = new AccessEvent(request, response, adapter);
- return ae;
- }
-
}
Added: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/joran/JoranConfiguratorTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/joran/JoranConfiguratorTest.java Fri Jan 23 14:56:31 2009
@@ -0,0 +1,73 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * 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
+ * Software Foundation.
+ */
+package ch.qos.logback.access.joran;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import ch.qos.logback.access.TeztConstants;
+import ch.qos.logback.access.dummy.DummyAccessEventBuilder;
+import ch.qos.logback.access.spi.AccessContext;
+import ch.qos.logback.access.spi.AccessEvent;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.testUtil.StringListAppender;
+
+public class JoranConfiguratorTest {
+
+ AccessContext context = new AccessContext();
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ jc.doConfigure(file);
+ }
+
+ @Test
+ public void smoke() throws Exception {
+ configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/smoke.xml");
+
+ ListAppender<AccessEvent> listAppender = (ListAppender<AccessEvent>) context
+ .getAppender("LIST");
+ AccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
+ listAppender.doAppend(event);
+
+ assertEquals(1, listAppender.list.size());
+
+ assertEquals(1, listAppender.list.size());
+ AccessEvent ae = (AccessEvent) listAppender.list.get(0);
+ assertNotNull(ae);
+ }
+
+ @Test
+ public void defaultLayout() throws Exception {
+ configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/defaultLayout.xml");
+ StringListAppender<AccessEvent> listAppender = (StringListAppender<AccessEvent>) context
+ .getAppender("STR_LIST");
+ AccessEvent event = DummyAccessEventBuilder.buildNewAccessEvent();
+ listAppender.doAppend(event);
+ assertEquals(1, listAppender.strList.size());
+ // the result contains a line separator at the end
+ assertTrue(listAppender.strList.get(0).startsWith("testMethod"));
+ }
+}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java Fri Jan 23 14:56:31 2009
@@ -10,8 +10,6 @@
package ch.qos.logback.classic.joran;
-import ch.qos.logback.classic.PatternLayout;
-import ch.qos.logback.classic.boolex.JaninoEventEvaluator;
import ch.qos.logback.classic.joran.action.ConfigurationAction;
import ch.qos.logback.classic.joran.action.ConsolePluginAction;
import ch.qos.logback.classic.joran.action.ContextNameAction;
@@ -23,8 +21,7 @@
import ch.qos.logback.classic.joran.action.RootLoggerAction;
import ch.qos.logback.classic.sift.SiftAction;
import ch.qos.logback.classic.spi.PlatformInfo;
-import ch.qos.logback.core.AppenderBase;
-import ch.qos.logback.core.filter.EvaluatorFilter;
+import ch.qos.logback.classic.util.DefaultNestedComponentRules;
import ch.qos.logback.core.joran.JoranConfiguratorBase;
import ch.qos.logback.core.joran.action.AppenderRefAction;
import ch.qos.logback.core.joran.action.IncludeAction;
@@ -89,10 +86,7 @@
@Override
protected void addDefaultNestedComponentRegistryRules(
DefaultNestedComponentRegistry registry) {
- registry.add(AppenderBase.class, "layout", PatternLayout.class);
- registry
- .add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class);
-
+ DefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
}
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java Fri Jan 23 14:56:31 2009
@@ -1,3 +1,12 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * 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
+ * Software Foundation.
+ */
package ch.qos.logback.classic.sift;
import java.util.Collection;
@@ -5,9 +14,11 @@
import java.util.Map;
import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.classic.util.DefaultNestedComponentRules;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.joran.action.ActionConst;
import ch.qos.logback.core.joran.action.AppenderAction;
+import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.joran.spi.RuleStore;
import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
@@ -32,6 +43,13 @@
rs.addRule(new Pattern("configuration/appender"), new AppenderAction());
}
+
+ @Override
+ protected void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ DefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
+ }
+
@Override
protected void buildInterpreter() {
super.buildInterpreter();
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java Fri Jan 23 14:56:31 2009
@@ -0,0 +1,37 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * 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
+ * Software Foundation.
+ */
+package ch.qos.logback.classic.util;
+
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.boolex.JaninoEventEvaluator;
+import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.filter.EvaluatorFilter;
+import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
+
+/**
+ * Contains mappings for the default type of nested components in
+ * logback-classic.
+ *
+ * @author Ceki Gulcu
+ *
+ */
+public class DefaultNestedComponentRules {
+
+ static public void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ // if you modify the rules here, then do not forget to modify
+ // SiftingJoranConfigurator as well.
+ registry.add(AppenderBase.class, "layout", PatternLayout.class);
+ registry
+ .add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class);
+
+ }
+
+}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/StatusListenerConfigHelper.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/StatusListenerConfigHelper.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/StatusListenerConfigHelper.java Fri Jan 23 14:56:31 2009
@@ -1,3 +1,12 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * 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
+ * Software Foundation.
+ */
package ch.qos.logback.classic.util;
import ch.qos.logback.classic.LoggerContext;
Modified: logback/trunk/logback-classic/src/test/input/joran/callerData.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/callerData.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/callerData.xml Fri Jan 23 14:56:31 2009
@@ -9,21 +9,23 @@
<name>m</name>
<regex>^hello.*</regex>
<CaseSensitive>false</CaseSensitive>
- </matcher>
+ </matcher>
</evaluator>
- <appender name="STR_LIST" class="ch.qos.logback.classic.testUtil.StringListAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
+ <appender name="STR_LIST"
+ class="ch.qos.logback.core.testUtil.StringListAppender">
+ <!-- the fact that the layout class is not declared tests default component class
+ mapping rules -->
+ <layout>
<Pattern>%caller{4, helloEval}%d %level - %m%n</Pattern>
</layout>
</appender>
-
+
<root>
<level value="DEBUG" />
<appender-ref ref="STR_LIST" />
</root>
-
-
-
+
+
+
</configuration>
-
\ No newline at end of file
Modified: logback/trunk/logback-classic/src/test/input/joran/conversionRule/htmlLayout0.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/conversionRule/htmlLayout0.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/conversionRule/htmlLayout0.xml Fri Jan 23 14:56:31 2009
@@ -3,7 +3,7 @@
<conversionRule conversionWord="sample"
converterClass="ch.qos.logback.classic.testUtil.SampleConverter" />
- <appender name="LIST" class="ch.qos.logback.classic.testUtil.StringListAppender">
+ <appender name="LIST" class="ch.qos.logback.core.testUtil.StringListAppender">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<Pattern>%sample%msg</Pattern>
</layout>
Modified: logback/trunk/logback-classic/src/test/input/joran/conversionRule/patternLayout0.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/conversionRule/patternLayout0.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/conversionRule/patternLayout0.xml Fri Jan 23 14:56:31 2009
@@ -3,7 +3,7 @@
<conversionRule conversionWord="sample"
converterClass="ch.qos.logback.classic.testUtil.SampleConverter" />
- <appender name="LIST" class="ch.qos.logback.classic.testUtil.StringListAppender">
+ <appender name="LIST" class="ch.qos.logback.core.testUtil.StringListAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%sample - %msg</Pattern>
</layout>
Modified: logback/trunk/logback-classic/src/test/input/joran/evaluatorFilter.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/evaluatorFilter.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/evaluatorFilter.xml Fri Jan 23 14:56:31 2009
@@ -6,7 +6,7 @@
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<Name>myFilter</Name>
<OnMatch>DENY</OnMatch>
- <Evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
+ <Evaluator>
<Name>mdcEvaluator</Name>
<Expression>"to be ignored".equals(message)</Expression>
</Evaluator>
Added: logback/trunk/logback-classic/src/test/input/joran/sift/defaultLayoutRule.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/defaultLayoutRule.xml Fri Jan 23 14:56:31 2009
@@ -0,0 +1,23 @@
+<configuration debug="true">
+
+ <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+
+ <discriminator>
+ <Key>userid</Key>
+ <defaultValue>default</defaultValue>
+ </discriminator>
+ <sift>
+ <appender name="LIST-${userid}"
+ class="ch.qos.logback.core.testUtil.StringListAppender">
+ <layout>
+ <Pattern>%level %msg</Pattern>
+ </layout>
+ </appender>
+ </sift>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="SIFT" />
+ </root>
+
+</configuration>
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/PatternLayoutTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/PatternLayoutTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/PatternLayoutTest.java Fri Jan 23 14:56:31 2009
@@ -25,12 +25,12 @@
import ch.qos.logback.classic.pattern.ConverterTest;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.testUtil.SampleConverter;
-import ch.qos.logback.classic.testUtil.StringListAppender;
import ch.qos.logback.classic.util.TeztConstants;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.pattern.PatternLayoutBase;
import ch.qos.logback.core.pattern.parser.AbstractPatternLayoutBaseTest;
+import ch.qos.logback.core.testUtil.StringListAppender;
public class PatternLayoutTest extends AbstractPatternLayoutBaseTest {
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java Fri Jan 23 14:56:31 2009
@@ -25,11 +25,12 @@
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.ThrowableDataPoint;
import ch.qos.logback.classic.spi.ThrowableProxy;
-import ch.qos.logback.classic.testUtil.StringListAppender;
import ch.qos.logback.classic.util.TeztConstants;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.testUtil.StringListAppender;
+import ch.qos.logback.core.util.StatusPrinter;
public class HTMLLayoutTest {
@@ -217,11 +218,14 @@
public void testConversionRuleSupportInHtmlLayout() throws JoranException {
configure(TeztConstants.TEST_DIR_PREFIX
+ "input/joran/conversionRule/htmlLayout0.xml");
+
root.getAppender("LIST");
String msg = "Simon says";
root.debug(msg);
- StringListAppender sla = (StringListAppender) root.getAppender("LIST");
+ StringListAppender<LoggingEvent> sla = (StringListAppender<LoggingEvent>) root
+ .getAppender("LIST");
assertNotNull(sla);
+ StatusPrinter.print(lc);
assertEquals(1, sla.strList.size());
assertFalse(sla.strList.get(0).contains("PARSER_ERROR"));
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java Fri Jan 23 14:56:31 2009
@@ -20,7 +20,6 @@
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.classic.testUtil.StringListAppender;
import ch.qos.logback.classic.turbo.DebugUsersTurboFilter;
import ch.qos.logback.classic.turbo.NOPTurboFilter;
import ch.qos.logback.classic.turbo.TurboFilter;
@@ -28,7 +27,7 @@
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.read.ListAppender;
-import ch.qos.logback.core.util.StatusPrinter;
+import ch.qos.logback.core.testUtil.StringListAppender;
public class JoranConfiguratorTest {
@@ -73,7 +72,7 @@
System.setProperty(propertyName, "INFO");
configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/rootLevelByProperty.xml");
- StatusPrinter.print(loggerContext);
+ //StatusPrinter.print(loggerContext);
ListAppender listAppender = (ListAppender) root.getAppender("LIST");
assertEquals(0, listAppender.list.size());
String msg = "hello world";
@@ -88,7 +87,7 @@
System.setProperty(propertyName, "DEBUG");
configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/loggerLevelByProperty.xml");
- StatusPrinter.print(loggerContext);
+ //StatusPrinter.print(loggerContext);
ListAppender listAppender = (ListAppender) root.getAppender("LIST");
assertEquals(0, listAppender.list.size());
String msg = "hello world";
@@ -100,7 +99,7 @@
@Test
public void testStatusListener() throws JoranException {
configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/statusListener.xml");
- StatusPrinter.print(loggerContext);
+ //StatusPrinter.print(loggerContext);
}
@Test
@@ -118,12 +117,12 @@
logger.debug("toto");
logger.debug(msg);
- StringListAppender slAppender = (StringListAppender) loggerContext
+ StringListAppender<LoggingEvent> slAppender = (StringListAppender<LoggingEvent>) loggerContext
.getLogger("root").getAppender("STR_LIST");
assertNotNull(slAppender);
assertEquals(2, slAppender.strList.size());
assertTrue(slAppender.strList.get(0).contains(" DEBUG - toto"));
-
+
String str1 = slAppender.strList.get(1);
assertTrue(str1.contains("Caller+0"));
assertTrue(str1.contains(" DEBUG - hello world"));
@@ -160,7 +159,7 @@
public void testLevelFilter() throws JoranException {
configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/levelFilter.xml");
- StatusPrinter.print(loggerContext);
+ //StatusPrinter.print(loggerContext);
logger.warn("hello");
logger.error("to be ignored");
@@ -180,7 +179,7 @@
public void testEvaluatorFilter() throws JoranException {
configure(TeztConstants.TEST_DIR_PREFIX + "input/joran/evaluatorFilter.xml");
- StatusPrinter.print(loggerContext);
+ //StatusPrinter.print(loggerContext);
logger.warn("hello");
logger.error("to be ignored");
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java Fri Jan 23 14:56:31 2009
@@ -27,12 +27,13 @@
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.read.ListAppender;
import ch.qos.logback.core.sift.AppenderTracker;
+import ch.qos.logback.core.testUtil.StringListAppender;
import ch.qos.logback.core.util.StatusPrinter;
public class SiftingAppenderTest {
static String PREFIX = TeztConstants.TEST_DIR_PREFIX + "input/joran/sift/";
-
+
LoggerContext loggerContext = new LoggerContext();
Logger logger = loggerContext.getLogger(this.getClass().getName());
Logger root = loggerContext.getLogger(LoggerContext.ROOT_NAME);
@@ -57,8 +58,9 @@
logger.debug("smoke");
long timestamp = 0;
SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
- ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.getAppenderTracker().get("smoke", timestamp);
-
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha
+ .getAppenderTracker().get("smoke", timestamp);
+
StatusPrinter.print(loggerContext);
assertNotNull(listAppender);
List<LoggingEvent> eventList = listAppender.list;
@@ -67,6 +69,22 @@
}
@Test
+ public void defaultLayoutRule() throws JoranException {
+ configure(PREFIX + "defaultLayoutRule.xml");
+ logger.debug("hello");
+ long timestamp = 0;
+ SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
+ StringListAppender<LoggingEvent> listAppender = (StringListAppender<LoggingEvent>) ha
+ .getAppenderTracker().get("default", timestamp);
+
+ StatusPrinter.print(loggerContext);
+ assertNotNull(listAppender);
+ List<String> strList = listAppender.strList;
+ assertEquals(1, strList.size());
+ assertEquals("DEBUG hello", strList.get(0));
+ }
+
+ @Test
public void testWholeCycle() throws JoranException {
String mdcKey = "cycle";
configure(PREFIX + "completeCycle.xml");
@@ -74,21 +92,22 @@
logger.debug("smoke");
long timestamp = System.currentTimeMillis();
SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
- ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.getAppenderTracker().get("a", timestamp);
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha
+ .getAppenderTracker().get("a", timestamp);
StatusPrinter.print(loggerContext);
-
+
assertNotNull(listAppender);
List<LoggingEvent> eventList = listAppender.list;
assertEquals(1, listAppender.list.size());
assertEquals("smoke", eventList.get(0).getMessage());
MDC.remove(mdcKey);
- LoggingEvent le = new LoggingEvent("x", logger, Level.INFO, "hello", null, null);
- le.setTimeStamp(timestamp+AppenderTracker.THRESHOLD*2);
+ LoggingEvent le = new LoggingEvent("x", logger, Level.INFO, "hello", null,
+ null);
+ le.setTimeStamp(timestamp + AppenderTracker.THRESHOLD * 2);
ha.doAppend(le);
assertFalse(listAppender.isStarted());
assertEquals(1, ha.getAppenderTracker().keyList().size());
assertEquals("cycleDefault", ha.getAppenderTracker().keyList().get(0));
-
}
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java Fri Jan 23 14:56:31 2009
@@ -29,7 +29,6 @@
import ch.qos.logback.core.status.StatusManager;
import ch.qos.logback.core.util.Constants;
import ch.qos.logback.core.util.FileUtil;
-import ch.qos.logback.core.util.StatusPrinter;
public class FileAppenderTest extends AbstractAppenderTest<Object> {
@@ -121,8 +120,7 @@
assertTrue("Got message [" + msg1 + "]", msg1
.startsWith("Setting \"Append\" property"));
- StatusPrinter.print(context);
-
+
appender.doAppend(new Object());
appender.stop();
assertTrue(file.exists());
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java Fri Jan 23 14:56:31 2009
@@ -16,7 +16,6 @@
import ch.qos.logback.core.util.AggregationType;
import ch.qos.logback.core.util.Duration;
import ch.qos.logback.core.util.FileSize;
-import ch.qos.logback.core.util.StatusPrinter;
public class PropertySetterTest {
@@ -137,7 +136,7 @@
setter.setContext(context);
setter.addBasicProperty("adjective", "nice");
setter.addBasicProperty("adjective", "big");
- StatusPrinter.print(context);
+
assertEquals(2, house.adjectiveList.size());
assertEquals("nice", house.adjectiveList.get(0));
assertEquals("big", house.adjectiveList.get(1));
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java Fri Jan 23 14:56:31 2009
@@ -29,7 +29,6 @@
import ch.qos.logback.core.layout.EchoLayout;
import ch.qos.logback.core.util.Compare;
import ch.qos.logback.core.util.Constants;
-import ch.qos.logback.core.util.StatusPrinter;
/**
* A rather exhaustive set of tests. Tests include leaving the file option
@@ -141,9 +140,6 @@
tbrp1.setCurrentTime(currentTime);
}
- StatusPrinter.print(context);
- //System.out.println(expectedFilenameList);
-
int i = 0;
for (String fn : expectedFilenameList) {
assertTrue(Compare.compare(fn, Constants.TEST_DIR_PREFIX
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java Fri Jan 23 14:56:31 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
@@ -18,7 +18,6 @@
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.util.StatusPrinter;
/**
* @author Ceki
@@ -44,7 +43,7 @@
// assertEquals("foo%", pp.convertInt(3));
pp = new FileNamePattern("%i foo", context);
- StatusPrinter.print(context.getStatusManager());
+
assertEquals("3 foo", pp.convertInt(3));
pp = new FileNamePattern("foo%i.xixo", context);
@@ -84,7 +83,7 @@
cal.set(2003, 4, 20, 17, 55);
FileNamePattern pp = new FileNamePattern("foo%d{yyyy.MM.dd}", context);
- StatusPrinter.print(context.getStatusManager());
+
assertEquals("foo2003.05.20", pp.convertDate(cal.getTime()));
pp = new FileNamePattern("foo%d{yyyy.MM.dd HH:mm}", context);
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java Fri Jan 23 14:56:31 2009
@@ -0,0 +1,46 @@
+package ch.qos.logback.core.testUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.Layout;
+
+public class StringListAppender<E> extends AppenderBase<E> {
+
+ Layout<E> layout;
+ public List<String> strList = new ArrayList<String>();
+
+ public StringListAppender() {
+
+ }
+
+ public void start() {
+ strList.clear();
+
+ if (layout == null || !layout.isStarted()) {
+ return;
+ }
+ super.start();
+ }
+
+ public void stop() {
+ super.stop();
+ }
+
+ @Override
+ protected void append(E eventObject) {
+ String res = layout.doLayout(eventObject);
+ strList.add(res);
+ }
+
+ @Override
+ public Layout<E> getLayout() {
+ return layout;
+ }
+
+ @Override
+ public void setLayout(Layout<E> layout) {
+ this.layout = layout;
+ }
+}
1
0

21 Jan '09
Author: ceki
Date: Wed Jan 21 23:06:57 2009
New Revision: 2130
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistry.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/HostClassAndPropertyDouble.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistryTest.java
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java
Log:
Fixing LBCLASSIC-103
Joran is now able to assume a default type for nested components according
to rules declared in a JoranConfigurator instance. The rules are located in
an instance of the DefaultNestedComponentRegistry class.
Thus, in many cases it will no longer be necessary to declare the class of a
component in configuration files.
Since the logback-classic and logback-access modes have their own JoranConfigurator
classes, it is now possible to register rules specific to each logback module.
For example, there is now a rule which maps the layout of an appender to a
c.q.l.classic.PatternLayout instance for all appenders in logback-classic and to
and instance of c.q.l.access.PatternLayout for all appenders in logback-access.
This is still ongoing and incomplete work.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java Wed Jan 21 23:06:57 2009
@@ -1,7 +1,7 @@
/**
- * LOGBack: the generic, reliable, fast and flexible logging framework.
+ * 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,27 +10,31 @@
package ch.qos.logback.classic.joran;
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.boolex.JaninoEventEvaluator;
import ch.qos.logback.classic.joran.action.ConfigurationAction;
import ch.qos.logback.classic.joran.action.ConsolePluginAction;
import ch.qos.logback.classic.joran.action.ContextNameAction;
import ch.qos.logback.classic.joran.action.EvaluatorAction;
import ch.qos.logback.classic.joran.action.InsertFromJNDIAction;
import ch.qos.logback.classic.joran.action.JMXConfiguratorAction;
-import ch.qos.logback.classic.joran.action.LayoutAction;
import ch.qos.logback.classic.joran.action.LevelAction;
import ch.qos.logback.classic.joran.action.LoggerAction;
import ch.qos.logback.classic.joran.action.RootLoggerAction;
import ch.qos.logback.classic.sift.SiftAction;
import ch.qos.logback.classic.spi.PlatformInfo;
+import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.filter.EvaluatorFilter;
import ch.qos.logback.core.joran.JoranConfiguratorBase;
import ch.qos.logback.core.joran.action.AppenderRefAction;
import ch.qos.logback.core.joran.action.IncludeAction;
import ch.qos.logback.core.joran.action.NOPAction;
+import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.joran.spi.RuleStore;
/**
- * A JoranConfigurator add few rules specific to the Classic module.
+ * This JoranConfiguratorclass adds rules specific to logback-classic.
*
* @author Ceki Gülcü
*/
@@ -46,14 +50,15 @@
rs.addRule(new Pattern("configuration"), new ConfigurationAction());
- rs.addRule(new Pattern("configuration/contextName"), new ContextNameAction());
- rs.addRule(new Pattern("configuration/insertFromJNDI"), new InsertFromJNDIAction());
+ rs.addRule(new Pattern("configuration/contextName"),
+ new ContextNameAction());
+ rs.addRule(new Pattern("configuration/insertFromJNDI"),
+ new InsertFromJNDIAction());
rs.addRule(new Pattern("configuration/evaluator"), new EvaluatorAction());
rs.addRule(new Pattern("configuration/appender/sift"), new SiftAction());
rs.addRule(new Pattern("configuration/appender/sift/*"), new NOPAction());
-
-
+
rs.addRule(new Pattern("configuration/logger"), new LoggerAction());
rs.addRule(new Pattern("configuration/logger/level"), new LevelAction());
@@ -63,19 +68,31 @@
new AppenderRefAction());
rs.addRule(new Pattern("configuration/root/appender-ref"),
new AppenderRefAction());
- rs
- .addRule(new Pattern("configuration/appender/layout"),
- new LayoutAction());
-
+
+ //rs
+ // .addRule(new Pattern("configuration/appender/layout"),
+ // new LayoutAction());
+
// add jmxConfigurator only if we have JMX available.
// If running under JDK 1.4 (retrotranslateed logback) then we
// might not have JMX.
- if(PlatformInfo.hasJMXObjectName()) {
- rs.addRule(new Pattern("configuration/jmxConfigurator"), new JMXConfiguratorAction());
+ if (PlatformInfo.hasJMXObjectName()) {
+ rs.addRule(new Pattern("configuration/jmxConfigurator"),
+ new JMXConfiguratorAction());
}
rs.addRule(new Pattern("configuration/include"), new IncludeAction());
-
- rs.addRule(new Pattern("configuration/consolePlugin"), new ConsolePluginAction());
+
+ rs.addRule(new Pattern("configuration/consolePlugin"),
+ new ConsolePluginAction());
+ }
+
+ @Override
+ protected void addDefaultNestedComponentRegistryRules(
+ DefaultNestedComponentRegistry registry) {
+ registry.add(AppenderBase.class, "layout", PatternLayout.class);
+ registry
+ .add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class);
+
}
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java Wed Jan 21 23:06:57 2009
@@ -1,7 +1,7 @@
/**
* Logback: the generic, reliable, fast and flexible logging framework.
*
- * Copyright (C) 1999-2007, 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
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java Wed Jan 21 23:06:57 2009
@@ -20,6 +20,7 @@
import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.event.SaxEventRecorder;
+import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
import ch.qos.logback.core.joran.spi.EventPlayer;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.spi.Interpreter;
@@ -79,6 +80,10 @@
abstract protected void addImplicitRules(Interpreter interpreter);
+ protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
+
+ }
+
protected Pattern initialPattern() {
return new Pattern();
}
@@ -90,6 +95,7 @@
InterpretationContext ec = interpreter.getInterpretationContext();
ec.setContext(context);
addImplicitRules(interpreter);
+ addDefaultNestedComponentRegistryRules(ec.getDefaultNestedComponentRegistry());
}
final public void doConfigure(final InputSource inputSource)
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java Wed Jan 21 23:06:57 2009
@@ -91,23 +91,32 @@
// perform variable name substitution
className = ec.subst(className);
- // guess class name via implicit rules
- if (OptionHelper.isEmpty(className)) {
- PropertySetter parentBean = actionData.parentBean;
- className = parentBean.getClassNameViaImplicitRules(actionData
- .getComplexPropertyName(), actionData.getAggregationType());
- }
+ Class componentClass = null;
+ try {
- if (OptionHelper.isEmpty(className)) {
- actionData.inError = true;
- String errMsg = "No class name attribute in [" + localName + "]";
- addError(errMsg);
- return;
- }
+ if (!OptionHelper.isEmpty(className)) {
+ componentClass = Loader.loadClass(className, context);
+ } else {
+ // guess class name via implicit rules
+ PropertySetter parentBean = actionData.parentBean;
+ componentClass = parentBean.getClassNameViaImplicitRules(actionData
+ .getComplexPropertyName(), actionData.getAggregationType(), ec
+ .getDefaultNestedComponentRegistry());
+ }
- try {
- actionData.setNestedComplexProperty(Loader.loadClass(className, context)
- .newInstance());
+ if (componentClass == null) {
+ actionData.inError = true;
+ String errMsg = "Could not find an appropriate class for property ["
+ + localName + "]";
+ addError(errMsg);
+ return;
+ }
+
+ if(OptionHelper.isEmpty(className)) {
+ addInfo("Assuming default type ["+componentClass.getName()+"] for ["+localName+"] property");
+ }
+
+ actionData.setNestedComplexProperty(componentClass.newInstance());
// pass along the repository
if (actionData.getNestedComplexProperty() instanceof ContextAware) {
@@ -118,12 +127,14 @@
addInfo("Pushing component [" + localName
+ "] on top of the object stack.");
ec.pushObject(actionData.getNestedComplexProperty());
+
} catch (Exception oops) {
actionData.inError = true;
String msg = "Could not create component [" + localName + "] of type ["
+ className + "]";
addError(msg, oops);
}
+
}
public void end(InterpretationContext ec, String tagName) {
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistry.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistry.java Wed Jan 21 23:06:57 2009
@@ -0,0 +1,49 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * 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
+ * Software Foundation.
+ */
+package ch.qos.logback.core.joran.spi;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A registry which maps a property in a host class to a default class.
+ *
+ * @author Cek Gülcü
+ *
+ */
+public class DefaultNestedComponentRegistry {
+
+ Map<HostClassAndPropertyDouble, Class> defaultComponentMap = new HashMap<HostClassAndPropertyDouble, Class>();
+
+ public void add(Class hostClass, String propertyName, Class componentClass) {
+ HostClassAndPropertyDouble hpDouble = new HostClassAndPropertyDouble(
+ hostClass, propertyName.toLowerCase());
+ defaultComponentMap.put(hpDouble, componentClass);
+ }
+
+ public Class findDefaultComponentType(Class hostClass, String propertyName) {
+ propertyName = propertyName.toLowerCase();
+ while (hostClass != null) {
+ Class componentClass = oneShotFind(hostClass, propertyName);
+ if (componentClass != null) {
+ return componentClass;
+ }
+ hostClass = hostClass.getSuperclass();
+ }
+ return null;
+ }
+
+ private Class oneShotFind(Class hostClass, String propertyName) {
+ HostClassAndPropertyDouble hpDouble = new HostClassAndPropertyDouble(
+ hostClass, propertyName);
+ return defaultComponentMap.get(hpDouble);
+ }
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/HostClassAndPropertyDouble.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/HostClassAndPropertyDouble.java Wed Jan 21 23:06:57 2009
@@ -0,0 +1,72 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * 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
+ * Software Foundation.
+ */
+package ch.qos.logback.core.joran.spi;
+
+/**
+ * A 2-tuple (a double) consisting of a Class and a String. The Class references
+ * the hosting class of a component and the String represents the property name
+ * under which a nested component is referenced the host.
+ *
+ * This class is used by {@link DefaultNestedComponentRegistry}.
+ *
+ * @author Ceki Gulcu
+ *
+ */
+public class HostClassAndPropertyDouble {
+
+ final Class hostClass;
+ final String propertyName;
+
+ public HostClassAndPropertyDouble(Class hostClass, String propertyName) {
+ this.hostClass = hostClass;
+ this.propertyName = propertyName;
+ }
+
+ public Class getHostClass() {
+ return hostClass;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((hostClass == null) ? 0 : hostClass.hashCode());
+ result = prime * result
+ + ((propertyName == null) ? 0 : propertyName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final HostClassAndPropertyDouble other = (HostClassAndPropertyDouble) obj;
+ if (hostClass == null) {
+ if (other.hostClass != null)
+ return false;
+ } else if (!hostClass.equals(other.hostClass))
+ return false;
+ if (propertyName == null) {
+ if (other.propertyName != null)
+ return false;
+ } else if (!propertyName.equals(other.propertyName))
+ return false;
+ return true;
+ }
+
+}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java Wed Jan 21 23:06:57 2009
@@ -43,7 +43,8 @@
Interpreter joranInterpreter;
final List<InPlayListener> listenerList = new ArrayList<InPlayListener>();
-
+ DefaultNestedComponentRegistry defaultNestedComponentRegistry = new DefaultNestedComponentRegistry();
+
public InterpretationContext(Context context, Interpreter joranInterpreter) {
this.context = context;
this.joranInterpreter = joranInterpreter;
@@ -52,6 +53,11 @@
propertiesMap = new HashMap<String, String>(5);
}
+
+ public DefaultNestedComponentRegistry getDefaultNestedComponentRegistry() {
+ return defaultNestedComponentRegistry;
+ }
+
void setPropertiesMap(Map<String, String> propertiesMap) {
this.propertiesMap = propertiesMap;
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java Wed Jan 21 23:06:57 2009
@@ -559,19 +559,17 @@
}
}
- String getDefaultClassNameByAnnonation(String name, Method relevantMethod) {
+ Class getDefaultClassNameByAnnonation(String name, Method relevantMethod) {
DefaultClass defaultClassAnnon = getAnnotation(name, DefaultClass.class,
relevantMethod);
if (defaultClassAnnon != null) {
Class defaultClass = defaultClassAnnon.value();
- if (defaultClass != null) {
- return defaultClass.getName();
- }
+ return defaultClass;
}
return null;
}
- String getByConcreteType(String name, Method relevantMethod) {
+ Class getByConcreteType(String name, Method relevantMethod) {
Class<?> paramType = getParameterClassForMethod(relevantMethod);
if (paramType == null) {
@@ -580,22 +578,26 @@
boolean isUnequivocallyInstantiable = isUnequivocallyInstantiable(paramType);
if(isUnequivocallyInstantiable) {
- return paramType.getName();
+ return paramType;
} else {
return null;
}
}
- public String getClassNameViaImplicitRules(String name,
- AggregationType aggregationType) {
+ public Class getClassNameViaImplicitRules(String name,
+ AggregationType aggregationType, DefaultNestedComponentRegistry registry) {
+ Class registryResult = registry.findDefaultComponentType(obj.getClass(), name);
+ if(registryResult!= null) {
+ return registryResult;
+ }
// find the relevant method for the given property name and aggregationType
Method relevantMethod = getRelevantMethod(name, aggregationType);
if (relevantMethod == null) {
-
+ return null;
}
- String byAnnotation = getDefaultClassNameByAnnonation(name, relevantMethod);
+ Class byAnnotation = getDefaultClassNameByAnnonation(name, relevantMethod);
if (byAnnotation != null) {
return byAnnotation;
}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistryTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/DefaultNestedComponentRegistryTest.java Wed Jan 21 23:06:57 2009
@@ -0,0 +1,37 @@
+package ch.qos.logback.core.joran.spi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DefaultNestedComponentRegistryTest {
+
+ DefaultNestedComponentRegistry registry = new DefaultNestedComponentRegistry();
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void smoke() {
+ String propertyName = "window";
+ registry.add(House.class, propertyName, Window.class);
+ Class result = registry.findDefaultComponentType(House.class, propertyName);
+ assertEquals(Window.class, result);
+ }
+
+ @Test
+ public void absent() {
+ registry.add(House.class, "a", Window.class);
+ Class result = registry.findDefaultComponentType(House.class, "other");
+ assertNull(result);
+ }
+}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java Wed Jan 21 23:06:57 2009
@@ -14,6 +14,7 @@
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-(a)SuiteClasses({PatternTest.class, SimpleStoreTest.class, PropertySetterTest.class})
+@SuiteClasses( { PatternTest.class, SimpleStoreTest.class,
+ PropertySetterTest.class, DefaultNestedComponentRegistryTest.class })
public class PackageTest {
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java Wed Jan 21 23:06:57 2009
@@ -20,6 +20,8 @@
public class PropertySetterTest {
+ DefaultNestedComponentRegistry defaultComponentRegistry = new DefaultNestedComponentRegistry();
+
@Test
public void testCanAggregateComponent() {
House house = new House();
@@ -112,23 +114,21 @@
public void testgetClassNameViaImplicitRules() {
House house = new House();
PropertySetter setter = new PropertySetter(house);
- String className = setter.getClassNameViaImplicitRules("door",
- AggregationType.AS_COMPLEX_PROPERTY);
- assertEquals(Door.class.getName(), className);
+ Class compClass = setter.getClassNameViaImplicitRules("door",
+ AggregationType.AS_COMPLEX_PROPERTY, defaultComponentRegistry);
+ assertEquals(Door.class, compClass);
}
-
-
@Test
public void testgetComplexPropertyColleClassNameViaImplicitRules() {
House house = new House();
PropertySetter setter = new PropertySetter(house);
- String className = setter.getClassNameViaImplicitRules("window",
- AggregationType.AS_COMPLEX_PROPERTY_COLLECTION);
- assertEquals(Window.class.getName(), className);
+ Class compClass = setter.getClassNameViaImplicitRules("window",
+ AggregationType.AS_COMPLEX_PROPERTY_COLLECTION,
+ defaultComponentRegistry);
+ assertEquals(Window.class, compClass);
}
-
@Test
public void testPropertyCollection() {
House house = new House();
@@ -208,13 +208,14 @@
Method relevantMethod = setter.getRelevantMethod("SwimmingPool",
AggregationType.AS_COMPLEX_PROPERTY);
assertNotNull(relevantMethod);
- String spClassName = setter.getDefaultClassNameByAnnonation("SwimmingPool",
+ Class spClass = setter.getDefaultClassNameByAnnonation("SwimmingPool",
relevantMethod);
- assertEquals(SwimmingPoolImpl.class.getName(), spClassName);
+ assertEquals(SwimmingPoolImpl.class, spClass);
- String classNameViaImplicitRules = setter.getClassNameViaImplicitRules(
- "SwimmingPool", AggregationType.AS_COMPLEX_PROPERTY);
- assertEquals(SwimmingPoolImpl.class.getName(), classNameViaImplicitRules);
+ Class classViaImplicitRules = setter.getClassNameViaImplicitRules(
+ "SwimmingPool", AggregationType.AS_COMPLEX_PROPERTY,
+ defaultComponentRegistry);
+ assertEquals(SwimmingPoolImpl.class, classViaImplicitRules);
}
}
1
0