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
March 2010
- 11 participants
- 188 discussions

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. release_0.9.19-16-gddd1b6a
by git-noreply@pixie.qos.ch 31 Mar '10
by git-noreply@pixie.qos.ch 31 Mar '10
31 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via ddd1b6a3c18099ba49d07e83be26a40a64116924 (commit)
from 4bca7fd336247b7752488f58f62500463be20579 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=ddd1b6a3c18099ba49d07e83…
http://github.com/ceki/logback/commit/ddd1b6a3c18099ba49d07e83be26a40a64116…
commit ddd1b6a3c18099ba49d07e83be26a40a64116924
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Wed Mar 31 16:41:52 2010 +0200
minor edits
diff --git a/logback-site/src/site/pages/download.html b/logback-site/src/site/pages/download.html
index 2514853..dc7bc51 100644
--- a/logback-site/src/site/pages/download.html
+++ b/logback-site/src/site/pages/download.html
@@ -82,6 +82,16 @@
</dl>
+
+ <hr/>
+
+ <h2>Forks</h2>
+
+ <p>At present time there are 13 forks of logback on github. If you
+ are the author of one of those forks and would like feedback from
+ potential users, plase drop us a line at logback-dev mailing list
+ with a brief description of your fork. We will gladly add a link to
+ your fork to the list below (currently empty).</p>
diff --git a/logback-site/src/site/pages/reasonsToSwitch.html b/logback-site/src/site/pages/reasonsToSwitch.html
index 8efa3d5..20c29bd 100644
--- a/logback-site/src/site/pages/reasonsToSwitch.html
+++ b/logback-site/src/site/pages/reasonsToSwitch.html
@@ -60,7 +60,8 @@
<h3><a name="docs" href="#docs">Extensive documentation</a></h3>
- <p>Logback ships with over two hundred pages of documentation.</p>
+ <p>Logback ships with over two hundred pages of constantly updated
+ documentation.</p>
<h3><a name="autoScan" href="#autoScan">Automatic reloading of
configuration files</a></h3>
-----------------------------------------------------------------------
Summary of changes:
logback-site/src/site/pages/download.html | 10 ++++++++++
logback-site/src/site/pages/reasonsToSwitch.html | 3 ++-
2 files changed, 12 insertions(+), 1 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. release_0.9.19-15-g4bca7fd
by git-noreply@pixie.qos.ch 31 Mar '10
by git-noreply@pixie.qos.ch 31 Mar '10
31 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 4bca7fd336247b7752488f58f62500463be20579 (commit)
via 18037a0e5175f739f861be85c2f341e5c249fbf2 (commit)
via 0348b40b4ea9e290ca147928a45bb20194f54dd4 (commit)
from a85c31bd64e687260888e5a9567340c084b01c6e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=4bca7fd336247b7752488f58…
http://github.com/ceki/logback/commit/4bca7fd336247b7752488f58f62500463be20…
commit 4bca7fd336247b7752488f58f62500463be20579
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Wed Mar 31 16:03:23 2010 +0200
Fixed LBCLASSIC-182 according to the patch suppllied by Aleksey Didik
diff --git a/logback-core/src/test/input/joran/define/good.xml b/logback-core/src/test/input/joran/define/good.xml
index be56cc2..60e9ca1 100644
--- a/logback-core/src/test/input/joran/define/good.xml
+++ b/logback-core/src/test/input/joran/define/good.xml
@@ -1,3 +1,3 @@
-<define name="foo" class="ch.qos.logback.core.joran.action.FooPropertyDefiner">
- <fooName>Monster</fooName>
-</define>
\ No newline at end of file
+<define name="foo" class="ch.qos.logback.core.joran.action.AsLowerCasePropertyDefiner">
+ <value>MONSTER</value>
+</define>
\ No newline at end of file
diff --git a/logback-core/src/test/input/joran/define/noclass.xml b/logback-core/src/test/input/joran/define/noclass.xml
index 300efaf..60156aa 100644
--- a/logback-core/src/test/input/joran/define/noclass.xml
+++ b/logback-core/src/test/input/joran/define/noclass.xml
@@ -1,3 +1,3 @@
-<define name="foo">
- <fooName>Monster</fooName>
+<define name="foo">
+ <fooName>Monster</fooName>
</define>
\ No newline at end of file
diff --git a/logback-core/src/test/input/joran/define/noname.xml b/logback-core/src/test/input/joran/define/noname.xml
index aed88c7..ba9793a 100644
--- a/logback-core/src/test/input/joran/define/noname.xml
+++ b/logback-core/src/test/input/joran/define/noname.xml
@@ -1,3 +1,3 @@
-<define class="ch.qos.logback.core.joran.action.FooPropertyDefiner">
- <fooName>Monster</fooName>
-</define>
\ No newline at end of file
+<define class="ch.qos.logback.core.joran.action.AsLowerCasePropertyDefiner">
+ <value>Monster</value>
+</define>
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/FooPropertyDefiner.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/AsLowerCasePropertyDefiner.java
similarity index 72%
rename from logback-core/src/test/java/ch/qos/logback/core/joran/action/FooPropertyDefiner.java
rename to logback-core/src/test/java/ch/qos/logback/core/joran/action/AsLowerCasePropertyDefiner.java
index e1aa240..361ed55 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/FooPropertyDefiner.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/AsLowerCasePropertyDefiner.java
@@ -15,15 +15,19 @@ package ch.qos.logback.core.joran.action;
import ch.qos.logback.core.PropertyDefinerBase;
-public class FooPropertyDefiner extends PropertyDefinerBase {
+public class AsLowerCasePropertyDefiner extends PropertyDefinerBase {
- private String fooName;
+ String val;
public String getPropertyValue() {
- return "Foo[" + fooName + "]";
+ if (val == null) {
+ return null;
+ } else {
+ return val.toLowerCase();
+ }
}
- public void setFooName(String fooName) {
- this.fooName = fooName;
+ public void setValue(String val) {
+ this.val = val;
}
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
index 4514317..ef1704e 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
@@ -18,7 +18,6 @@ import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.HashMap;
-import java.util.Iterator;
import org.junit.After;
import org.junit.Before;
@@ -30,7 +29,8 @@ import ch.qos.logback.core.joran.SimpleConfigurator;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.Pattern;
-import ch.qos.logback.core.status.ErrorStatus;
+import ch.qos.logback.core.status.Status;
+import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.util.CoreTestConstants;
/**
@@ -40,7 +40,7 @@ import ch.qos.logback.core.util.CoreTestConstants;
*/
public class DefinePropertyActionTest {
- private static final String DEFINE_XML_DIR = CoreTestConstants.JORAN_INPUT_PREFIX
+ private static final String DEFINE_INPUT_DIR = CoreTestConstants.JORAN_INPUT_PREFIX
+ "define/";
private static final String GOOD_XML = "good.xml";
private static final String NONAME_XML = "noname.xml";
@@ -48,82 +48,61 @@ public class DefinePropertyActionTest {
private static final String BADCLASS_XML = "badclass.xml";
SimpleConfigurator sc;
- Context context;
+ Context context = new ContextBase();
DefinePropertyAction definerAction;
InterpretationContext ic;
+ StatusChecker checker = new StatusChecker(context);
@Before
public void setUp() throws Exception {
- context = new ContextBase();
+
HashMap<Pattern, Action> rulesMap = new HashMap<Pattern, Action>();
rulesMap.put(new Pattern("define"), new DefinePropertyAction());
sc = new SimpleConfigurator(rulesMap);
sc.setContext(context);
+ }
+ @After
+ public void tearDown() throws Exception {
+ //StatusPrinter.printInCaseOfErrorsOrWarnings(context);
}
@Test
- public void testAllRight() throws JoranException {
- sc.doConfigure(DEFINE_XML_DIR + GOOD_XML);
+ public void good() throws JoranException {
+ sc.doConfigure(DEFINE_INPUT_DIR + GOOD_XML);
// get from context
String inContextFoo = context.getProperty("foo");
- // get from real class
- FooPropertyDefiner fooDefiner = new FooPropertyDefiner();
- fooDefiner.setFooName("Monster");
- String fromRealClassFoo = fooDefiner.getPropertyValue();
- assertEquals(inContextFoo, fromRealClassFoo);
+ assertEquals("monster", inContextFoo);
}
@Test
- public void testNoName() throws JoranException {
- sc.doConfigure(DEFINE_XML_DIR + NONAME_XML);
+ public void noName() throws JoranException {
+ sc.doConfigure(DEFINE_INPUT_DIR + NONAME_XML);
// get from context
String inContextFoo = context.getProperty("foo");
assertNull(inContextFoo);
// check context errors
- assertTrue(checkError("Missing property name for property definer. Near [define] line 1"));
+ assertTrue(checker.containsMatch(Status.ERROR,
+ "Missing property name for property definer. Near \\[define\\] line 1"));
}
@Test
- public void testNoClass() throws JoranException {
- sc.doConfigure(DEFINE_XML_DIR + NOCLASS_XML);
- // get from context
+ public void noClass() throws JoranException {
+ sc.doConfigure(DEFINE_INPUT_DIR + NOCLASS_XML);
String inContextFoo = context.getProperty("foo");
assertNull(inContextFoo);
- // check context errors
- assertTrue(checkError("Missing class name for property definer. Near [define] line 1"));
+ assertTrue(checker.containsMatch(Status.ERROR,
+ "Missing class name for property definer. Near \\[define\\] line 1"));
}
@Test
public void testBadClass() throws JoranException {
- sc.doConfigure(DEFINE_XML_DIR + BADCLASS_XML);
+ sc.doConfigure(DEFINE_INPUT_DIR + BADCLASS_XML);
// get from context
String inContextFoo = context.getProperty("foo");
assertNull(inContextFoo);
// check context errors
- assertTrue(checkBadClassError());
- }
-
- @After
- public void tearDown() throws Exception {
- context = null;
- sc = null;
- }
-
- private boolean checkError(String waitedMsg) {
- Iterator it = context.getStatusManager().getCopyOfStatusList().iterator();
- ErrorStatus es1 = (ErrorStatus) it.next();
- return waitedMsg.equals(es1.getMessage());
- }
-
- private boolean checkBadClassError() {
- Iterator it = context.getStatusManager().getCopyOfStatusList().iterator();
- // skip info about class instantiating
- it.next();
- // check error status
- ErrorStatus es1 = (ErrorStatus) it.next();
- return "Could not create an PropertyDefiner of type [a.b.c.Foo]."
- .equals(es1.getMessage());
+ checker.containsMatch(Status.ERROR, "Could not create an PropertyDefiner of type");
}
}
diff --git a/logback-site/src/site/pages/manual/configuration.html b/logback-site/src/site/pages/manual/configuration.html
index a1fad9c..86167e4 100644
--- a/logback-site/src/site/pages/manual/configuration.html
+++ b/logback-site/src/site/pages/manual/configuration.html
@@ -1238,13 +1238,13 @@ public class MyApp3 {
As it often comes in handy, the variable ${HOSTNAME} is
automatically defined.</p>
- <h4>properties are inserted into the logger context</h4>
+ <h4>Properties are inserted into the logger context</h4>
<p>Note that the values defined via <code><property></code>
element are actually inserted into the logger context. In other
words, they become properties of the logger context. Consequently,
- they will be available in all logging events as well as remotely
- after serialization.</p>
+ they will be available in all logging events, including those sent
+ to remote hosts via serialization.</p>
<p>The next example shows a variable, a.k.a. a substitution
property, declared the beginning of the configuration file. It is
@@ -1367,7 +1367,6 @@ public class MyApp3 {
properties file shown below gives an example.
</p>
-
<em>Example: Nested variable references
(logback-examples/src/main/java/chapters/configuration/variables2.properties)</em>
@@ -1400,9 +1399,9 @@ fileName=myApp.log
</root>
</configuration></pre>
- <h4><a name="defaultValuesForVariables"
+ <h3><a name="defaultValuesForVariables"
href="#defaultValuesForVariables">Default substitution values for
- variables</a></h4>
+ variables</a></h3>
<p>Under certain circumstances, it may be desirable for a variable
to have a default value in case it is not declared or its value is
@@ -1412,6 +1411,57 @@ fileName=myApp.log
operator. For example, assuming <em>aKey</em> is not defined,
<code>"${aKey<b>:-golden</b>}"</code> will be interpreted as
"golden".</p>
+
+
+ <!-- ============================================================== -->
+ <h3><a name="hostname" href="#hostname">HOSTNAME property</a></h3>
+
+ <p>As it often comes in handy, the <code>HOSTNAME</code> property is
+ defined automatically during configuration.</p>
+
+ <!-- ============================================================== -->
+
+ <h3><a name="timestamp" href="#timestamp">Setting a timestamp</a></h3>
+
+ <p>The <em>timestamp</em> element can define a property according to
+ current date and time. The <em>timestamp</em> element is <a
+ href="appenders.html#uniquelyNamed">explained in a subsequent
+ chapter</a>.</p>
+
+ <!-- ============================================================== -->
+ <h3><a name="definingPropsOnTheFly"
+ href="#definingPropsOnTheFly">Defining properties on the
+ fly</a></h3>
+
+ <p>You may define properties from within the configuration file
+ using the <code><define></code> element. The define element takes
+ mandatory attributes: <span class="attr">name</span> and <span
+ class="attr">class</span>. The <span class="attr">name</span>
+ attribute designates the name of the property to set whereas the
+ <span class="attr">class</span> attribute designates any class
+ implementing the <a
+ href="../xref/ch/qos/logback/core/spi/PropertyDefiner.html">PropertyDefiner</a>
+ interface. The value returned by the <code>getPropertyValue</code>()
+ method of the <code>PropertyDefiner</code> will be placed into the
+ named property.
+ </p>
+
+ <p>Here is an example.</p>
+
+ <pre class="prettyprint source"><configuration>
+
+ <define name="rootLevel" class="a.class.implementing.PropertyDefiner">
+ <aProperty>of a.class.implementing.PropertyDefiner</aProperty>
+ </define>
+
+ <root level="${rootLevel}"/>
+</configuration></pre>
+
+ <p>At present time, logback does not ship with any classes
+ implementing <code>PropertyDefiner</code>. We merely provide an
+ extension point so that you may define properties dynamically.
+ </p>
+
<!-- ============================================================== -->
<h3><a name="conditional" href="#conditional">Conditional
@@ -1517,7 +1567,6 @@ Nevertheless, recognizing the
readers of your configuration files, including yourself.
</p>
-
<!-- ============================================================== -->
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index 28310bc..c419888 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -38,6 +38,12 @@
<p>Logback now supports <a
href="manual/configuration.html#conditional">conditional
processing</a> of configuration files.</p>
+
+ <p>A new extension point for <a
+ href="manual/configuration.html#definingPropsOnTheFly">defining
+ properties on the fly</a> has been added. The code for this
+ enhancement was provided by Aleksey Didik in <a
+ href="http://jira.qos.ch/browse/LBCLASSIC-182">LBCLASSIC-182</a>.</p>
<p>Logback now provides <a
href="http://logback.qos.ch/manual/loggingSeparation.html">an
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=18037a0e5175f739f861be85…
http://github.com/ceki/logback/commit/18037a0e5175f739f861be85c2f341e5c249f…
commit 18037a0e5175f739f861be85c2f341e5c249fbf2
Merge: a85c31b 0348b40
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Wed Mar 31 14:29:47 2010 +0200
Merge branch 'lbclassic182'
-----------------------------------------------------------------------
Summary of changes:
.../ch/qos/logback/core/PropertyDefinerBase.java | 13 +++
.../logback/core/joran/JoranConfiguratorBase.java | 25 ++---
.../core/joran/action/DefinePropertyAction.java | 98 ++++++++++++++++++
.../Condition.java => spi/PropertyDefiner.java} | 12 ++-
.../src/test/input/joran/define/badclass.xml | 1 +
logback-core/src/test/input/joran/define/good.xml | 3 +
.../src/test/input/joran/define/noclass.xml | 3 +
.../src/test/input/joran/define/noname.xml | 3 +
.../joran/action/AsLowerCasePropertyDefiner.java} | 21 +++--
.../joran/action/DefinePropertyActionTest.java | 108 ++++++++++++++++++++
.../src/site/pages/manual/configuration.html | 63 ++++++++++--
logback-site/src/site/pages/news.html | 6 +
12 files changed, 325 insertions(+), 31 deletions(-)
create mode 100644 logback-core/src/main/java/ch/qos/logback/core/PropertyDefinerBase.java
create mode 100644 logback-core/src/main/java/ch/qos/logback/core/joran/action/DefinePropertyAction.java
copy logback-core/src/main/java/ch/qos/logback/core/{joran/conditional/Condition.java => spi/PropertyDefiner.java} (66%)
create mode 100644 logback-core/src/test/input/joran/define/badclass.xml
create mode 100644 logback-core/src/test/input/joran/define/good.xml
create mode 100644 logback-core/src/test/input/joran/define/noclass.xml
create mode 100644 logback-core/src/test/input/joran/define/noname.xml
copy logback-core/src/{main/java/ch/qos/logback/core/joran/conditional/ElseAction.java => test/java/ch/qos/logback/core/joran/action/AsLowerCasePropertyDefiner.java} (57%)
create mode 100644 logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. release_0.9.19-12-ga85c31b
by git-noreply@pixie.qos.ch 31 Mar '10
by git-noreply@pixie.qos.ch 31 Mar '10
31 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via a85c31bd64e687260888e5a9567340c084b01c6e (commit)
from 60bd9dfb27e27cd509e6a18aa1de80ec6f1379d8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=a85c31bd64e687260888e5a9…
http://github.com/ceki/logback/commit/a85c31bd64e687260888e5a9567340c084b01…
commit a85c31bd64e687260888e5a9567340c084b01c6e
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Wed Mar 31 14:27:13 2010 +0200
- added gradle to the list of projects using logback
- edits to manual/configuration.html
diff --git a/logback-site/src/site/pages/index.html b/logback-site/src/site/pages/index.html
index 86904a4..c675bc3 100644
--- a/logback-site/src/site/pages/index.html
+++ b/logback-site/src/site/pages/index.html
@@ -69,7 +69,8 @@
<li><a href="http://www.jfrog.org/products.php">Artifactory</a></li>
<li><a href="http://cia.sourceforge.net/">Citizen Intelligence Agency</a></li>
<li><a href="http://www.geomajas.org/">Geomajas</a></li>
- <li><a href="http://jmxmonitor.sourceforge.net/">jmxmonitor</a></li>
+ <li><a href="http://www.gradle.org/">Gradle</a></li>
+ <li><a href="http://jmxmonitor.sourceforge.net/">JMX Monitor</a></li>
<li><a href="http://code.google.com/p/openmeetings/">OpenMeetings</a></li>
</ul>
</td>
diff --git a/logback-site/src/site/pages/manual/configuration.html b/logback-site/src/site/pages/manual/configuration.html
index 914f52e..a1fad9c 100644
--- a/logback-site/src/site/pages/manual/configuration.html
+++ b/logback-site/src/site/pages/manual/configuration.html
@@ -1417,8 +1417,21 @@ fileName=myApp.log
<h3><a name="conditional" href="#conditional">Conditional
processing of configuration files</a></h3>
- <p>XML syntax is awfully cumbersome to serve as a basis for a
- general purpose programming language. Nevertheless, recognizing the
+ <p>Developers often need to juggle between several logback
+ configuration files targeting different environments such as
+ development, testing and production. These configuration files have
+ substantial parts in common differing only in a few places. To avoid
+ duplication, logback supports conditional processing of
+ configuration files with the help of <code><if></code>,
+ <code><then></code> and <code><else></code> elements so that a
+ single configuration file can adequately target several
+ environments.
+ </p>
+
+XML syntax is awfully cumbersome to serve as a basis for a
+ general purpose programming language. Developers often need to juggle between several logback configuration files targeting different environments such as development, testing and production
+
+Nevertheless, recognizing the
fact that developers need to juggle between several configuration
files targeting different environments, e.g. development, testing
and production. Often the different files have substantial parts in
@@ -1497,11 +1510,14 @@ fileName=myApp.log
<p>Conditional processing is supported everywhere within the
<code><configuration></code> element. Nested if-then-else
- statements are also supported. However, as mentioned earlier, XML is
- not a good basis for scripting, and too many conditionals can
- quickly render your configuration files ungrokable.
+ statements are also supported. However, XML syntax is awfully
+ cumbersome and is ill suited as the foundation of a general purpose
+ programming langiage. Consequently, too many conditionals will
+ quickly render your configuration files ungrokable to subsequent
+ readers of your configuration files, including yourself.
</p>
+
<!-- ============================================================== -->
diff --git a/logback-site/src/site/pages/reasonsToSwitch.html b/logback-site/src/site/pages/reasonsToSwitch.html
index 14e401c..8efa3d5 100644
--- a/logback-site/src/site/pages/reasonsToSwitch.html
+++ b/logback-site/src/site/pages/reasonsToSwitch.html
@@ -101,15 +101,16 @@
<h3><a name="conditional" href="#conditional">Conditional
prcessing of configuration files</a></h3>
- <p>Recognizing the fact that developers need to juggle between
- several configuration files targeting different environments,
- e.g. development, testing and production. Often the different
- files have substantial parts in common differing only in a few
+ <p>Developers often need to juggle between several logback
+ configuration files targeting different environments such as
+ development, testing and production. These configuration files
+ have substantial parts in common differing only in a few
places. To avoid duplication, logback supports <a
href="manual/configuration.html#conditional">conditional
processing of configuration files</a> with the help of
<code><if></code>, <code><then></code> and
- <code><else></code> elements.
+ <code><else></code> elements so that a single configuration
+ file can adequately target several environments.
</p>
-----------------------------------------------------------------------
Summary of changes:
logback-site/src/site/pages/index.html | 3 +-
.../src/site/pages/manual/configuration.html | 26 ++++++++++++++++----
logback-site/src/site/pages/reasonsToSwitch.html | 11 ++++----
3 files changed, 29 insertions(+), 11 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

30 Mar '10
Add if then else capability to joran
------------------------------------
Key: LBCORE-140
URL: http://jira.qos.ch/browse/LBCORE-140
Project: logback-core
Issue Type: New Feature
Components: Joran
Reporter: Ceki Gulcu
Assignee: Logback dev list
Example:
<confiugure>
<if condition="">
<propertyX>...</propertyX>
<then>
<appender name="FILE" ...>
<file>A.log</file>
</appender>
<then>
<else>
<appender name="FILE" ...>
<file>B.log</file>
</appender>
<else>
</if>
</configuration>
Support for nested ifs would be nice.
--
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
1
1

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. release_0.9.19-11-g60bd9df
by git-noreply@pixie.qos.ch 30 Mar '10
by git-noreply@pixie.qos.ch 30 Mar '10
30 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 60bd9dfb27e27cd509e6a18aa1de80ec6f1379d8 (commit)
from 91737bd88e2830f2d20d016f166d701ffd8ad5b3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=60bd9dfb27e27cd509e6a18a…
http://github.com/ceki/logback/commit/60bd9dfb27e27cd509e6a18aa1de80ec6f137…
commit 60bd9dfb27e27cd509e6a18aa1de80ec6f1379d8
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Wed Mar 31 00:06:32 2010 +0200
- documenting conditional processing
- additional test cases for conditional processing
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
index be99ad2..dcb46b5 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -37,69 +38,83 @@ import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
import ch.qos.logback.core.util.StatusPrinter;
-
public class ConditionalTest {
LoggerContext context = new LoggerContext();
Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME);
-
int diff = RandomUtil.getPositiveInt();
String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
-
+
@Before
public void setUp() throws UnknownHostException {
- context.setName("c"+diff);
+ context.setName("c" + diff);
context.putProperty("randomOutputDir", randomOutputDir);
- InetAddress localhost = InetAddress.getLocalHost();
- context.putProperty("aHost", localhost.getCanonicalHostName());
}
-
-
+
+ @After
+ public void tearDown() {
+ StatusPrinter.printIfErrorsOccured(context);
+ }
+
void configure(String file) throws JoranException {
JoranConfigurator jc = new JoranConfigurator();
jc.setContext(context);
jc.doConfigure(file);
}
-
+
@Test
- public void conditionalConsoleApp_THEN() throws JoranException, IOException,
- InterruptedException {
+ public void conditionalConsoleApp_IF_THEN_True() throws JoranException,
+ IOException, InterruptedException {
+ InetAddress localhost = InetAddress.getLocalHost();
+ context.putProperty("aHost", localhost.getCanonicalHostName());
String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ "conditional/conditionalConsoleApp.xml";
configure(configFileAsStr);
FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
assertNotNull(fileAppender);
-
+
ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
assertNotNull(consoleAppender);
- StatusPrinter.printIfErrorsOccured(context);
StatusChecker checker = new StatusChecker(context);
assertTrue(checker.isErrorFree());
}
-
+
+ @Test
+ public void conditionalConsoleApp_IF_THEN_False() throws JoranException,
+ IOException, InterruptedException {
+
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/conditionalConsoleApp.xml";
+ configure(configFileAsStr);
+ FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
+ assertNotNull(fileAppender);
+
+ ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
+ assertNull(consoleAppender);
+ StatusChecker checker = new StatusChecker(context);
+ assertTrue(checker.isErrorFree());
+ }
+
@Test
- public void conditionalConsoleApp_ELSE() throws JoranException, IOException,
- InterruptedException {
+ public void conditionalConsoleApp_IF_THEN_ELSE() throws JoranException,
+ IOException, InterruptedException {
String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ "conditional/conditionalConsoleApp_ELSE.xml";
configure(configFileAsStr);
-
- StatusPrinter.print(context);
-
-
+
FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
assertNotNull(fileAppender);
-
+
ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
assertNull(consoleAppender);
-
+
ListAppender listAppender = (ListAppender) root.getAppender("LIST");
assertNotNull(listAppender);
-
- //StatusPrinter.printIfErrorsOccured(context);
+
+ // StatusPrinter.printIfErrorsOccured(context);
StatusChecker checker = new StatusChecker(context);
assertTrue(checker.isErrorFree());
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
index 7898f4d..b65a139 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
@@ -87,9 +87,12 @@ public class IfAction extends Action {
if (!state.boolResult) {
listToPlay = state.elseSaxEventList;
}
-
- // insert past this event
- interpreter.addEventsDynamically(listToPlay, 1);
+
+ // if boolResult==false & missing else, listToPlay may be null
+ if(listToPlay != null) {
+ // insert past this event
+ interpreter.addEventsDynamically(listToPlay, 1);
+ }
}
diff --git a/logback-core/src/test/input/joran/conditional/ifWithoutElse.xml b/logback-core/src/test/input/joran/conditional/ifWithoutElse.xml
new file mode 100644
index 0000000..ef1a39f
--- /dev/null
+++ b/logback-core/src/test/input/joran/conditional/ifWithoutElse.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<x>
+ <stack name="BEGIN"/>
+ <if condition='p("Ki1").equals("Val1")'>
+ <then>
+ <stack name="a"/>
+ </then>
+ </if>
+ <stack name="END"/>
+</x>
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
index 5d3f98b..3a414e8 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
@@ -15,6 +15,7 @@ package ch.qos.logback.core.joran.conditional;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.HashMap;
@@ -32,6 +33,7 @@ import ch.qos.logback.core.joran.action.NOPAction;
import ch.qos.logback.core.joran.action.ext.StackAction;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
import ch.qos.logback.core.util.StatusPrinter;
@@ -62,6 +64,7 @@ public class IfThenElseTest {
@After
public void tearDown() throws Exception {
+ StatusPrinter.printIfErrorsOccured(context);
StackAction.reset();
}
@@ -69,7 +72,6 @@ public class IfThenElseTest {
public void if0_Then() throws JoranException {
context.putProperty("Ki1", "Val1");
tc.doConfigure(CONDITIONAL_DIR_PREFIX+"if0.xml");
- StatusPrinter.printIfErrorsOccured(context);
verifyConfig(new String[] {"BEGIN", "a", "END"});
}
@@ -80,6 +82,22 @@ public class IfThenElseTest {
}
@Test
+ public void ifWithoutElse_True() throws JoranException {
+ context.putProperty("Ki1", "Val1");
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"ifWithoutElse.xml");
+ verifyConfig(new String[] {"BEGIN", "a", "END"});
+ }
+
+ @Test
+ public void ifWithoutElse_False() throws JoranException {
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"ifWithoutElse.xml");
+ verifyConfig(new String[] {"BEGIN", "END"});
+ StatusChecker checker = new StatusChecker(context);
+ assertTrue(checker.isErrorFree());
+ }
+
+
+ @Test
public void nestedIf() throws JoranException {
tc.doConfigure(CONDITIONAL_DIR_PREFIX+"nestedIf.xml");
StatusPrinter.printIfErrorsOccured(context);
diff --git a/logback-site/src/site/pages/manual/configuration.html b/logback-site/src/site/pages/manual/configuration.html
index 8208a53..914f52e 100644
--- a/logback-site/src/site/pages/manual/configuration.html
+++ b/logback-site/src/site/pages/manual/configuration.html
@@ -129,8 +129,8 @@
<code>MyApp1</code>.
</p>
- <em>Example 3.<span class="autoEx"/>: Simple example of
- <code>BasicConfigurator</code> usage <a
+ <em>Example: Simple example of <code>BasicConfigurator</code>
+ usage <a
href="../xref/chapters/configuration/MyApp1.html">(logback-examples/src/main/java/chapters/configuration/MyApp1.java)</a></em>
<pre class="prettyprint source">package manual.configuration;
@@ -154,7 +154,7 @@ public class MyApp1 {
instantiates a Foo object. The Foo class is listed below:
</p>
- <em>Example 3.<span class="autoEx"/>: Small class doing logging
+ <em>Example: Small class doing logging
<a href="../xref/chapters/configuration/Foo.html">(logback-examples/src/main/java/chapters/configuration/Foo.java)</a>
</em>
@@ -231,7 +231,7 @@ public class Foo {
seen.
</p>
- <p><em>Example 3.<span class="autoEx"/>: Basic configuration file
+ <p><em>Example: Basic configuration file
(logback-examples/src/main/java/chapters/configuration/sample0.xml)</em></p>
@@ -276,7 +276,7 @@ public class Foo {
addition of two lines of code for printing internal status
data.</p>
- <em>Example 3.<span class="autoEx"/>: Print logback's internal status information
+ <em>Example: Print logback's internal status information
<a
href="../xref/chapters/configuration/MyApp2.html">(logback-examples/src/main/java/chapters/configuration/MyApp2.java)</a></em>
@@ -325,7 +325,7 @@ public class Foo {
</p>
- <em>Example 3.<span class="autoEx"/>: Basic configuration file
+ <em>Example: Basic configuration file
using debug mode
(logback-examples/src/main/java/chapters/configuration/sample1.xml)</em>
@@ -399,7 +399,7 @@ public class Foo {
<code><configuration></code> element to true, as shown next.
</p>
- <em>Example 3.<span class="autoEx"/>: Scanning for changes in
+ <em>Example: Scanning for changes in
configuration file and automatic re-configuraion
(logback-examples/src/main/java/chapters/configuration/scan1.xml)</em>
@@ -416,7 +416,7 @@ public class Foo {
units of milliseconds, seconds, minutes or hours. Here is an
example:</p>
- <em>Example 3.<span class="autoEx"/>: Specifying a different
+ <em>Example: Specifying a different
scanning period
(logback-examples/src/main/java/chapters/configuration/scan2.xml)</em>
@@ -468,7 +468,7 @@ public class Foo {
application, <em>MyApp3</em>, invokes JoranConfigurator on a
configuration file passed as a parameter.</p>
- <p><em>Example 3.<span class="autoEx"/>: Invoking
+ <p><em>Example: Invoking
<code>JoranConfigurator</code> directly <a
href="../xref/chapters/configuration/MyApp3.html">(logback-examples/src/main/java/chapters/configuration/MyApp3.java)</a></em></p>
@@ -605,7 +605,7 @@ public class MyApp3 {
<p>It is also possible to register one or more status listeners
within a configuration file. Here is an example.</p>
- <p><em>Example 3.<span class="autoEx"/>: Registering a status listener (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</em></p>
+ <p><em>Example: Registering a status listener (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</em></p>
<pre class="prettyprint source"><configuration>
<b><statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /></b>
@@ -762,7 +762,7 @@ public class MyApp3 {
following configuration file shows how to achieve that.
</p>
-<em>Example 3.<span class="autoEx"/>: Setting the level of a logger (logback-examples/src/main/java/chapters/configuration/sample2.xml)</em>
+<em>Example: Setting the level of a logger (logback-examples/src/main/java/chapters/configuration/sample2.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
@@ -800,7 +800,7 @@ public class MyApp3 {
of the <em>chapters.configuration.Foo</em> logger to <code>DEBUG</code>.
</p>
-<em>Example 3.<span class="autoEx"/>: Setting the level of multiple loggers (logback-examples/src/main/java/chapters/configuration/sample3.xml)</em>
+<em>Example: Setting the level of multiple loggers (logback-examples/src/main/java/chapters/configuration/sample3.xml)</em>
<pre class="source prettyprint"><configuration>
<appender name="STDOUT"
@@ -879,7 +879,7 @@ public class MyApp3 {
<em>sample4.xml</em> is a case in point:
</p>
- <em>Example 3.<span class="autoEx"/>: Logger level sample
+ <em>Example: Logger level sample
(logback-examples/src/main/java/chapters/configuration/sample4.xml)</em>
<pre class="prettyprint source"><configuration>
@@ -1003,7 +1003,7 @@ public class MyApp3 {
configuration file illustrates:
</p>
-<em>Example 3.<span class="autoEx"/>: Multiple loggers (logback-examples/src/main/java/chapters/configuration/multiple.xml)</em>
+<em>Example: Multiple loggers (logback-examples/src/main/java/chapters/configuration/multiple.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
@@ -1055,7 +1055,7 @@ public class MyApp3 {
duplicated.
</p>
- <em>Example 3.<span class="autoEx"/>: Duplicate appender
+ <em>Example: Duplicate appender
(logback-examples/src/main/java/chapters/configuration/duplicate.xml)</em>
<pre class="prettyprint source"><configuration>
@@ -1101,7 +1101,7 @@ public class MyApp3 {
set of loggers flow into a specific appender.
</p>
- <em>Example 3.<span class="autoEx"/>: Multiple appender
+ <em>Example: Multiple appender
(logback-examples/src/main/java/chapters/configuration/restricted.xml)</em>
<pre class="prettyprint source"><configuration>
@@ -1146,7 +1146,7 @@ public class MyApp3 {
of the tree.
</p>
-<em>Example 3.<span class="autoEx"/>: Additivity flag (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</em>
+<em>Example: Additivity flag (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
@@ -1184,6 +1184,44 @@ public class MyApp3 {
<em>foo.log</em> file and only in that file.
</p>
+
+ <h3><a name="contextName" href="#contextName">Setting the context name</a></h3>
+
+ <p>As mentioned <a href="architecture.html#LoggerContext">in an
+ earlier chapter</a>, every logger is attached to logger context. By
+ default, the logger context is called "default". However, you can
+ set a different name with the help of the
+ <code><contextName></code> configuration directive. Note that
+ once set, the logger context name <a
+ href="../apidocs/ch/qos/logback/core/ContextBase.html#setName(java.lang.String)">cannot
+ be changed</a>. Setting the context name is a simple and
+ straightforward method in order to distinguish between multiple
+ applications logging to the same target.
+ </p>
+
+ <em>Example: Set the context name and display it
+ (logback-examples/src/main/java/chapters/configuration/contextName.xml)</em>
+ <pre class="prettyprint source"><configuration>
+ <b><contextName>myAppName</contextName></b>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d <b>%contextName</b> [%t] %level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration></pre>
+
+ <p>This last examples illustrates naming of the logger
+ context. Adding the the <a
+ href="layouts.html#conversionWord">contextName conversion word</a>
+ in layout's pattern will output the said name.</p>
+
+ <!-- =============================================================== -->
+
+
<h4><a name="variableSubstitution"
href="#variableSubstitution">Variable substitution</a></h4>
@@ -1214,7 +1252,7 @@ public class MyApp3 {
output file.
</p>
- <em>Example 3.<span class="autoEx"/>: Simple Variable substitution
+ <em>Example: Simple Variable substitution
(logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml)
</em>
@@ -1243,7 +1281,7 @@ public class MyApp3 {
<p class="source">java -DUSER_HOME="/home/sebastien" MyApp2</p>
- <em>Example 3.<span class="autoEx"/>: System Variable substitution
+ <em>Example: System Variable substitution
(logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml)
</em>
@@ -1267,7 +1305,7 @@ public class MyApp3 {
how one can do such a setup.
</p>
- <em>Example 3.<span class="autoEx"/>: Variable substitution using a
+ <em>Example: Variable substitution using a
separate file
(logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml)
</em>
@@ -1295,7 +1333,7 @@ public class MyApp3 {
file might look like.
</p>
- <em>Example 3.<span class="autoEx"/>: Variable file
+ <em>Example: Variable file
(logback-examples/src/main/java/chapters/configuration/variables1.properties)</em>
<pre class="source">USER_HOME=/home/sebastien</pre>
@@ -1330,7 +1368,7 @@ public class MyApp3 {
</p>
- <em>Example 3.<span class="autoEx"/>: Nested variable references
+ <em>Example: Nested variable references
(logback-examples/src/main/java/chapters/configuration/variables2.properties)</em>
<pre class="source">USER_HOME=/home/sebastien
@@ -1342,7 +1380,7 @@ fileName=myApp.log
"fileName".
</p>
- <em>Example 3.<span class="autoEx"/>: Variable substitution using
+ <em>Example: Variable substitution using
a separate file
(logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml)</em>
@@ -1374,9 +1412,134 @@ fileName=myApp.log
operator. For example, assuming <em>aKey</em> is not defined,
<code>"${aKey<b>:-golden</b>}"</code> will be interpreted as
"golden".</p>
+ <!-- ============================================================== -->
+
+ <h3><a name="conditional" href="#conditional">Conditional
+ processing of configuration files</a></h3>
+ <p>XML syntax is awfully cumbersome to serve as a basis for a
+ general purpose programming language. Nevertheless, recognizing the
+ fact that developers need to juggle between several configuration
+ files targeting different environments, e.g. development, testing
+ and production. Often the different files have substantial parts in
+ common differing only in a few places. To avoid duplication, logback
+ supports conditional processing of configuration files with the help
+ of <code><if></code>, <code><then></code> and
+ <code><else></code> elements.</p>
+
+ <p>The general format for conditional statements is shown below.</p>
+
+ <pre class="prettyprint source"><configuration>
+
+ <!-- if-then form -->
+ <if condition="some conditional expression">
+ <then>
+ ...
+ </then>
+ </if>
+
+ <!-- if-then-else form -->
+ <if condition="some conditional expression">
+ <then>
+ ...
+ </then>
+ <else>
+ ...
+ </else>
+ </if>
+
+</configuration></pre>
+
+ <p>The condition is a java expression where only context properties
+ or system properties are accessible. For a key passed as argument,
+ the <code>property</code>() or its shorter equivalent
+ <code>p</code>() methods return the String value of the property.
+ For example, to access the value a property with key "k", you would
+ write <code>property("k")</code> or equivalently
+ <code>p("k")</code>. If the property with key "k" is undefined, the
+ property method will return the empty string and not null. This
+ avoids the need to to check for null values.</p>
+
+ <p>In the next example, the <code>ConsoleAppender</code> will be
+ attached to the root logger, but only if the HOSTNAME is
+ "torino". Note that the <code>FileAppender</code> named "FILE" is
+ attached to the root logger in any case.
+ </p>
+
+
+ <pre class="prettyprint source"><configuration>
+
+ <b><if condition='property("HOSTNAME").contains("torino")'></b>
+ <b><then></b>
+ <appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d %-5level %logger{35} - %msg %n</pattern>
+ </encoder>
+ </appender>
+ <root>
+ <appender-ref ref="CON" />
+ </root>
+ <b></then></b>
+ <b></if></b>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${randomOutputDir}/conditional.log</file>
+ <encoder>
+ <pattern>%d %-5level %logger{35} - %msg %n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="ERROR">
+ <appender-ref ref="FILE" />
+ </root>
+</configuration></pre>
+
+
+ <p>Conditional processing is supported everywhere within the
+ <code><configuration></code> element. Nested if-then-else
+ statements are also supported. However, as mentioned earlier, XML is
+ not a good basis for scripting, and too many conditionals can
+ quickly render your configuration files ungrokable.
+ </p>
+
+
+ <!-- ============================================================== -->
+
+ <h3><a name="insertFromJNDI" href="#insertFromJNDI">Obtaining
+ variables from JNDI</a></h3>
+
+ <p>Under certain circumstances, you may want to make use of
+ env-entries stored in JNDI. The <code><insertFromJNDI></code>
+ configuration directive extracts an env-entry stored in JNDI and
+ inserts it as variable as specified by the <span
+ class="attr">as</span> attribute.
+ </p>
+
+ <em>Example: Insert as properties env-entries obtained via JNDI
+ (logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml)</em>
+ <pre class="prettyprint source"><configuration>
+ <b><insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
+ <b><contextName><span class="green">${appName}</span></contextName></b>
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d %contextName %level %msg %logger{50}%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
+</configuration></pre>
+
+ <p>In this last example, the "java:comp/env/appName" env-entry is
+ inserted as the <span class="variable">appName</span> property. Note
+ that the <code><contextName></code> directive sets the context
+ name based on the value of the <span class="variable">appName</span>
+ property inserted by the previous <code><insertFromJNDI></code>
+ directive.
+ </p>
-
<h3><a name="fileInclusion" href="#fileInclusion">File
inclusion</a></h3>
@@ -1385,7 +1548,7 @@ fileName=myApp.log
element, as shown below:
</p>
- <em>Example 3.<span class="autoEx"/>: File include
+ <em>Example: File include
(logback-examples/src/main/java/chapters/configuration/containingConfig.xml)</em>
<pre class="prettyprint source"><configuration>
@@ -1402,7 +1565,7 @@ fileName=myApp.log
<code>ConsoleAppender</code> could be declared as:
</p>
- <em>Example 3.<span class="autoEx"/>: File include
+ <em>Example: File include
(logback-examples/src/main/java/chapters/configuration/includedConfig.xml)</em>
<pre class="source"><b class="green big"><included></b>
@@ -1445,77 +1608,6 @@ fileName=myApp.log
</ul>
-
- <h3><a name="contextName" href="#contextName">Setting the context name</a></h3>
-
- <p>As mentioned <a href="architecture.html#LoggerContext">in an
- earlier chapter</a>, every logger is attached to logger context. By
- default, the logger context is called "default". However, you can
- set a different name with the help of the
- <code><contextName></code> configuration directive. Note that
- once set, the logger context name <a
- href="../apidocs/ch/qos/logback/core/ContextBase.html#setName(java.lang.String)">cannot
- be changed</a>. Setting the context name is a simple and
- straightforward method in order to distinguish between multiple
- applications logging to the same target.
- </p>
-
- <em>Example 3.<span class="autoEx"/>: Set the context name and display it
- (logback-examples/src/main/java/chapters/configuration/contextName.xml)</em>
- <pre class="prettyprint source"><configuration>
- <b><contextName>myAppName</contextName></b>
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d <b>%contextName</b> [%t] %level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="debug">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration></pre>
-
- <p>This last examples illustrates naming of the logger
- context. Adding the the <a
- href="layouts.html#conversionWord">contextName conversion word</a>
- in layout's pattern will output the said name.</p>
-
- <h3><a name="insertFromJNDI" href="#insertFromJNDI">Obtaining
- variables from JNDI</a></h3>
-
- <p>Under certain circumstances, you may want to make use of
- env-entries stored in JNDI. The <code><insertFromJNDI></code>
- configuration directive extracts an env-entry stored in JNDI and
- inserts it as variable as specified by the <span
- class="attr">as</span> attribute.
- </p>
-
- <em>Example 3.<span class="autoEx"/>: Insert as properties env-entries obtained via JNDI
- (logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml)</em>
- <pre class="prettyprint source"><configuration>
- <b><insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
- <b><contextName><span class="green">${appName}</span></contextName></b>
-
- <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d %contextName %level %msg %logger{50}%n</pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="CONSOLE" />
- </root>
-</configuration></pre>
-
- <p>In this last example, the "java:comp/env/appName" env-entry is
- inserted as the <span class="variable">appName</span> property. Note
- that the <code><contextName></code> directive sets the context
- name based on the value of the <span class="variable">appName</span>
- property inserted by the previous <code><insertFromJNDI></code>
- directive..
-
-</p>
-
<script src="../templates/footer.js" type="text/javascript"></script>
</div>
</body>
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index 5599a10..28310bc 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -34,6 +34,10 @@
<p>Fixed issue related to charsets in
<code>LayoutWrappingEncoder</code> not being recognized in config
files.</p>
+
+ <p>Logback now supports <a
+ href="manual/configuration.html#conditional">conditional
+ processing</a> of configuration files.</p>
<p>Logback now provides <a
href="http://logback.qos.ch/manual/loggingSeparation.html">an
@@ -42,7 +46,6 @@
href="http://jira.qos.ch/browse/LBCLASSIC-166">LBCLASSIC-166</a>
and <a
href="http://jira.qos.ch/browse/LBCLASSIC-87">LBCLASSIC-87</a>.
-
</p>
diff --git a/logback-site/src/site/pages/reasonsToSwitch.html b/logback-site/src/site/pages/reasonsToSwitch.html
index 877887d..14e401c 100644
--- a/logback-site/src/site/pages/reasonsToSwitch.html
+++ b/logback-site/src/site/pages/reasonsToSwitch.html
@@ -98,6 +98,20 @@
working again.
</p>
+ <h3><a name="conditional" href="#conditional">Conditional
+ prcessing of configuration files</a></h3>
+
+ <p>Recognizing the fact that developers need to juggle between
+ several configuration files targeting different environments,
+ e.g. development, testing and production. Often the different
+ files have substantial parts in common differing only in a few
+ places. To avoid duplication, logback supports <a
+ href="manual/configuration.html#conditional">conditional
+ processing of configuration files</a> with the help of
+ <code><if></code>, <code><then></code> and
+ <code><else></code> elements.
+ </p>
+
<h3><a name="filters" href="#filters">Filters</a></h3>
-----------------------------------------------------------------------
Summary of changes:
.../classic/joran/conditional/ConditionalTest.java | 63 +++--
.../logback/core/joran/conditional/IfAction.java | 9 +-
.../conditional/{if0.xml => ifWithoutElse.xml} | 5 +-
.../core/joran/conditional/IfThenElseTest.java | 20 ++-
.../src/site/pages/manual/configuration.html | 286 +++++++++++++-------
logback-site/src/site/pages/news.html | 5 +-
logback-site/src/site/pages/reasonsToSwitch.html | 14 +
7 files changed, 272 insertions(+), 130 deletions(-)
copy logback-core/src/test/input/joran/conditional/{if0.xml => ifWithoutElse.xml} (75%)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. release_0.9.19-10-g91737bd
by git-noreply@pixie.qos.ch 30 Mar '10
by git-noreply@pixie.qos.ch 30 Mar '10
30 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 91737bd88e2830f2d20d016f166d701ffd8ad5b3 (commit)
from db3e3e278df194d84b0259458515b9709fe0510d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=91737bd88e2830f2d20d016f…
http://github.com/ceki/logback/commit/91737bd88e2830f2d20d016f166d701ffd8ad…
commit 91737bd88e2830f2d20d016f166d701ffd8ad5b3
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Tue Mar 30 21:16:23 2010 +0200
- added scalate project to the list of project using logback
diff --git a/logback-site/src/site/pages/index.html b/logback-site/src/site/pages/index.html
index 9e1b898..86904a4 100644
--- a/logback-site/src/site/pages/index.html
+++ b/logback-site/src/site/pages/index.html
@@ -62,33 +62,30 @@
logback, in alphabetical order:
</p>
- <ul>
-
- <li><a href="http://www.jfrog.org/products.php">Artifactory</a></li>
-
- <li><a href="http://cia.sourceforge.net/">Citizen Intelligence Agency</a></li>
-
- <li><a href="http://www.geomajas.org/">Geomajas</a></li>
-
- <li><a href="http://jmxmonitor.sourceforge.net/">jmxmonitor</a></li>
-
-
- <li><a href="http://code.google.com/p/openmeetings/">OpenMeetings</a></li>
-
- <li><a href="http://liftweb.net/">Lift</a></li>
-
- <li><a href="http://www.red5.org">Red5</a></li>
-
- <li><a href="http://sonar.codehaus.org/">Sonar</a>
- </li>
-
-
- <li><a
- href="http://static.springsource.org/s2-dmserver/2.0.x/user-guide/htmlsingle/user…">SpringSource
- dm Server</a></li>
-
- </ul>
-
+ <table border="0">
+ <tr>
+ <td valign="top">
+ <ul>
+ <li><a href="http://www.jfrog.org/products.php">Artifactory</a></li>
+ <li><a href="http://cia.sourceforge.net/">Citizen Intelligence Agency</a></li>
+ <li><a href="http://www.geomajas.org/">Geomajas</a></li>
+ <li><a href="http://jmxmonitor.sourceforge.net/">jmxmonitor</a></li>
+ <li><a href="http://code.google.com/p/openmeetings/">OpenMeetings</a></li>
+ </ul>
+ </td>
+ <td>
+ <ul>
+ <li><a href="http://liftweb.net/">Lift</a></li>
+ <li><a href="http://www.red5.org">Red5</a></li>
+ <li><a href="http://http://scalate.fusesource.org/">Scalate</a></li>
+ <li><a href="http://sonar.codehaus.org/">Sonar</a></li>
+ <li><a
+ href="http://static.springsource.org/s2-dmserver/2.0.x/user-guide/htmlsingle/user…">SpringSource
+ dm Server</a></li>
+ </ul>
+ </td>
+ </tr>
+ </table>
<script src="templates/footer.js" type="text/javascript"></script>
</div>
</body>
-----------------------------------------------------------------------
Summary of changes:
logback-site/src/site/pages/index.html | 51 +++++++++++++++-----------------
1 files changed, 24 insertions(+), 27 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, lbclassic182, created. release_0.9.19-10-g0348b40
by git-noreply@pixie.qos.ch 30 Mar '10
by git-noreply@pixie.qos.ch 30 Mar '10
30 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, lbclassic182 has been created
at 0348b40b4ea9e290ca147928a45bb20194f54dd4 (commit)
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=0348b40b4ea9e290ca147928…
http://github.com/ceki/logback/commit/0348b40b4ea9e290ca147928a45bb20194f54…
commit 0348b40b4ea9e290ca147928a45bb20194f54dd4
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Tue Mar 30 20:45:43 2010 +0200
Applied Aleksey Didik's patch for LBCLASSIC-182
diff --git a/logback-core/src/main/java/ch/qos/logback/core/PropertyDefinerBase.java b/logback-core/src/main/java/ch/qos/logback/core/PropertyDefinerBase.java
new file mode 100644
index 0000000..d2f53c9
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/PropertyDefinerBase.java
@@ -0,0 +1,13 @@
+package ch.qos.logback.core;
+
+import ch.qos.logback.core.spi.ContextAwareBase;
+import ch.qos.logback.core.spi.PropertyDefiner;
+
+/**
+ * Set a skeleton implementation for property definers
+ * just for have ContextAwareBase.
+ *
+ * @author Aleksey Didik
+ */
+public abstract class PropertyDefinerBase extends ContextAwareBase implements PropertyDefiner {
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java b/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
index 2bb626a..37e3dcf 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
@@ -22,6 +22,7 @@ import ch.qos.logback.core.joran.action.AppenderAction;
import ch.qos.logback.core.joran.action.AppenderRefAction;
import ch.qos.logback.core.joran.action.ContextPropertyAction;
import ch.qos.logback.core.joran.action.ConversionRuleAction;
+import ch.qos.logback.core.joran.action.DefinePropertyAction;
import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
import ch.qos.logback.core.joran.action.NestedComplexPropertyIA;
import ch.qos.logback.core.joran.action.NewRuleAction;
@@ -48,7 +49,6 @@ import ch.qos.logback.core.joran.spi.RuleStore;
* @author Ceki Gülcü
*/
abstract public class JoranConfiguratorBase extends GenericConfigurator {
-
public List getErrorList() {
return null;
@@ -56,29 +56,27 @@ abstract public class JoranConfiguratorBase extends GenericConfigurator {
@Override
protected void addInstanceRules(RuleStore rs) {
-
- rs.addRule(new Pattern("configuration/property"),
- new PropertyAction());
-
+
+ rs.addRule(new Pattern("configuration/property"), new PropertyAction());
+
rs.addRule(new Pattern("configuration/substitutionProperty"),
new PropertyAction());
-
- rs.addRule(new Pattern("configuration/timestamp"),
- new TimestampAction());
-
+
+ rs.addRule(new Pattern("configuration/timestamp"), new TimestampAction());
+
+ rs.addRule(new Pattern("configuration/define"), new DefinePropertyAction());
+
// the contextProperty pattern is deprecated. It is undocumented
// and will be dropped in future versions of logback
rs.addRule(new Pattern("configuration/contextProperty"),
new ContextPropertyAction());
-
+
rs.addRule(new Pattern("configuration/conversionRule"),
new ConversionRuleAction());
rs.addRule(new Pattern("configuration/statusListener"),
new StatusListenerAction());
-
-
rs.addRule(new Pattern("configuration/appender"), new AppenderAction());
rs.addRule(new Pattern("configuration/appender/appender-ref"),
new AppenderRefAction());
@@ -101,7 +99,8 @@ abstract public class JoranConfiguratorBase extends GenericConfigurator {
@Override
protected void buildInterpreter() {
super.buildInterpreter();
- Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
+ Map<String, Object> omap = interpreter.getInterpretationContext()
+ .getObjectMap();
omap.put(ActionConst.APPENDER_BAG, new HashMap());
omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/DefinePropertyAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/DefinePropertyAction.java
new file mode 100644
index 0000000..12b6bb7
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/DefinePropertyAction.java
@@ -0,0 +1,98 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under either
+ * the terms of the Eclipse Public License v1.0 as published by the Eclipse
+ * Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.joran.action;
+
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.joran.spi.ActionException;
+import ch.qos.logback.core.util.OptionHelper;
+import ch.qos.logback.core.spi.PropertyDefiner;
+import org.xml.sax.Attributes;
+
+/**
+ * Instantiate class for define property value. Get future property name and
+ * property definer class from attributes. Some property definer properties
+ * could be used. After defining put new property to context.
+ *
+ * @author Aleksey Didik
+ */
+public class DefinePropertyAction extends Action {
+
+ String propertyName;
+ PropertyDefiner definer;
+ boolean inError;
+
+ public void begin(InterpretationContext ec, String localName,
+ Attributes attributes) throws ActionException {
+ // reset variables
+ propertyName = null;
+ definer = null;
+ inError = false;
+
+ // read future property name
+ propertyName = attributes.getValue(NAME_ATTRIBUTE);
+ if (OptionHelper.isEmpty(propertyName)) {
+ addError("Missing property name for property definer. Near [" + localName
+ + "] line " + getLineNumber(ec));
+ inError = true;
+ return;
+ }
+
+ // read property definer class name
+ String className = attributes.getValue(CLASS_ATTRIBUTE);
+ if (OptionHelper.isEmpty(className)) {
+ addError("Missing class name for property definer. Near [" + localName
+ + "] line " + getLineNumber(ec));
+ inError = true;
+ return;
+ }
+
+ // try to instantiate property definer
+ try {
+ addInfo("About to instantiate property definer of type [" + className
+ + "]");
+ definer = (PropertyDefiner) OptionHelper.instantiateByClassName(
+ className, PropertyDefiner.class, context);
+ definer.setContext(context);
+ ec.pushObject(definer);
+ } catch (Exception oops) {
+ inError = true;
+ addError("Could not create an PropertyDefiner of type [" + className
+ + "].", oops);
+ throw new ActionException(oops);
+ }
+ }
+
+ /**
+ * Now property definer is initialized by all properties and we can put
+ * property value to context
+ */
+ public void end(InterpretationContext ec, String name) {
+ if (inError) {
+ return;
+ }
+
+ Object o = ec.peekObject();
+
+ if (o != definer) {
+ addWarn("The object at the of the stack is not the property definer for property named ["
+ + propertyName + "] pushed earlier.");
+ } else {
+ addInfo("Popping property definer for property named [" + propertyName
+ + "] from the object stack");
+ ec.popObject();
+ // let's put defined property and value to context
+ context.putProperty(propertyName, definer.getPropertyValue());
+ }
+ }
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyDefiner.java b/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyDefiner.java
new file mode 100644
index 0000000..01f90c1
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyDefiner.java
@@ -0,0 +1,24 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under either
+ * the terms of the Eclipse Public License v1.0 as published by the Eclipse
+ * Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.spi;
+
+public interface PropertyDefiner extends ContextAware {
+
+ /**
+ * Get the property value, defined by this property definer
+ *
+ * @return defined property value
+ */
+ String getPropertyValue();
+}
diff --git a/logback-core/src/test/input/joran/define/badclass.xml b/logback-core/src/test/input/joran/define/badclass.xml
new file mode 100644
index 0000000..fde9b69
--- /dev/null
+++ b/logback-core/src/test/input/joran/define/badclass.xml
@@ -0,0 +1 @@
+<define name="foo" class="a.b.c.Foo"/>
diff --git a/logback-core/src/test/input/joran/define/good.xml b/logback-core/src/test/input/joran/define/good.xml
new file mode 100644
index 0000000..be56cc2
--- /dev/null
+++ b/logback-core/src/test/input/joran/define/good.xml
@@ -0,0 +1,3 @@
+<define name="foo" class="ch.qos.logback.core.joran.action.FooPropertyDefiner">
+ <fooName>Monster</fooName>
+</define>
\ No newline at end of file
diff --git a/logback-core/src/test/input/joran/define/noclass.xml b/logback-core/src/test/input/joran/define/noclass.xml
new file mode 100644
index 0000000..300efaf
--- /dev/null
+++ b/logback-core/src/test/input/joran/define/noclass.xml
@@ -0,0 +1,3 @@
+<define name="foo">
+ <fooName>Monster</fooName>
+</define>
\ No newline at end of file
diff --git a/logback-core/src/test/input/joran/define/noname.xml b/logback-core/src/test/input/joran/define/noname.xml
new file mode 100644
index 0000000..aed88c7
--- /dev/null
+++ b/logback-core/src/test/input/joran/define/noname.xml
@@ -0,0 +1,3 @@
+<define class="ch.qos.logback.core.joran.action.FooPropertyDefiner">
+ <fooName>Monster</fooName>
+</define>
\ No newline at end of file
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
new file mode 100644
index 0000000..4514317
--- /dev/null
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/DefinePropertyActionTest.java
@@ -0,0 +1,129 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under either
+ * the terms of the Eclipse Public License v1.0 as published by the Eclipse
+ * Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.joran.action;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.joran.SimpleConfigurator;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.status.ErrorStatus;
+import ch.qos.logback.core.util.CoreTestConstants;
+
+/**
+ * Test {@link DefinePropertyAction}.
+ *
+ * @author Aleksey Didik
+ */
+public class DefinePropertyActionTest {
+
+ private static final String DEFINE_XML_DIR = CoreTestConstants.JORAN_INPUT_PREFIX
+ + "define/";
+ private static final String GOOD_XML = "good.xml";
+ private static final String NONAME_XML = "noname.xml";
+ private static final String NOCLASS_XML = "noclass.xml";
+ private static final String BADCLASS_XML = "badclass.xml";
+
+ SimpleConfigurator sc;
+ Context context;
+ DefinePropertyAction definerAction;
+ InterpretationContext ic;
+
+ @Before
+ public void setUp() throws Exception {
+ context = new ContextBase();
+ HashMap<Pattern, Action> rulesMap = new HashMap<Pattern, Action>();
+ rulesMap.put(new Pattern("define"), new DefinePropertyAction());
+ sc = new SimpleConfigurator(rulesMap);
+ sc.setContext(context);
+
+ }
+
+ @Test
+ public void testAllRight() throws JoranException {
+ sc.doConfigure(DEFINE_XML_DIR + GOOD_XML);
+ // get from context
+ String inContextFoo = context.getProperty("foo");
+ // get from real class
+ FooPropertyDefiner fooDefiner = new FooPropertyDefiner();
+ fooDefiner.setFooName("Monster");
+ String fromRealClassFoo = fooDefiner.getPropertyValue();
+ assertEquals(inContextFoo, fromRealClassFoo);
+ }
+
+ @Test
+ public void testNoName() throws JoranException {
+ sc.doConfigure(DEFINE_XML_DIR + NONAME_XML);
+ // get from context
+ String inContextFoo = context.getProperty("foo");
+ assertNull(inContextFoo);
+ // check context errors
+ assertTrue(checkError("Missing property name for property definer. Near [define] line 1"));
+ }
+
+ @Test
+ public void testNoClass() throws JoranException {
+ sc.doConfigure(DEFINE_XML_DIR + NOCLASS_XML);
+ // get from context
+ String inContextFoo = context.getProperty("foo");
+ assertNull(inContextFoo);
+ // check context errors
+ assertTrue(checkError("Missing class name for property definer. Near [define] line 1"));
+ }
+
+ @Test
+ public void testBadClass() throws JoranException {
+ sc.doConfigure(DEFINE_XML_DIR + BADCLASS_XML);
+ // get from context
+ String inContextFoo = context.getProperty("foo");
+ assertNull(inContextFoo);
+ // check context errors
+ assertTrue(checkBadClassError());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ context = null;
+ sc = null;
+ }
+
+ private boolean checkError(String waitedMsg) {
+ Iterator it = context.getStatusManager().getCopyOfStatusList().iterator();
+ ErrorStatus es1 = (ErrorStatus) it.next();
+ return waitedMsg.equals(es1.getMessage());
+ }
+
+ private boolean checkBadClassError() {
+ Iterator it = context.getStatusManager().getCopyOfStatusList().iterator();
+ // skip info about class instantiating
+ it.next();
+ // check error status
+ ErrorStatus es1 = (ErrorStatus) it.next();
+ return "Could not create an PropertyDefiner of type [a.b.c.Foo]."
+ .equals(es1.getMessage());
+ }
+
+}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/FooPropertyDefiner.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/FooPropertyDefiner.java
new file mode 100644
index 0000000..e1aa240
--- /dev/null
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/FooPropertyDefiner.java
@@ -0,0 +1,29 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under either
+ * the terms of the Eclipse Public License v1.0 as published by the Eclipse
+ * Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.joran.action;
+
+import ch.qos.logback.core.PropertyDefinerBase;
+
+public class FooPropertyDefiner extends PropertyDefinerBase {
+
+ private String fooName;
+
+ public String getPropertyValue() {
+ return "Foo[" + fooName + "]";
+ }
+
+ public void setFooName(String fooName) {
+ this.fooName = fooName;
+ }
+}
-----------------------------------------------------------------------
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. release_0.9.19-9-gdb3e3e2
by git-noreply@pixie.qos.ch 30 Mar '10
by git-noreply@pixie.qos.ch 30 Mar '10
30 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via db3e3e278df194d84b0259458515b9709fe0510d (commit)
from c9f58e8f6a1372a08fef830ac1c3e8faa38c5abf (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=db3e3e278df194d84b025945…
http://github.com/ceki/logback/commit/db3e3e278df194d84b0259458515b9709fe05…
commit db3e3e278df194d84b0259458515b9709fe0510d
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Tue Mar 30 18:38:48 2010 +0200
- added support for <if> statement nested within <if> statements or
or <include> statement nested <if> statements or <if> nested within
<include>
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ElseAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ElseAction.java
index 63ede3f..83db5ee 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ElseAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ElseAction.java
@@ -1,44 +1,28 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under either
+ * the terms of the Eclipse Public License v1.0 as published by the Eclipse
+ * Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ */
package ch.qos.logback.core.joran.conditional;
-import java.util.ArrayList;
import java.util.List;
-import org.xml.sax.Attributes;
-
-import ch.qos.logback.core.joran.action.Action;
-import ch.qos.logback.core.joran.event.InPlayListener;
import ch.qos.logback.core.joran.event.SaxEvent;
-import ch.qos.logback.core.joran.spi.ActionException;
-import ch.qos.logback.core.joran.spi.InterpretationContext;
-
-public class ElseAction extends Action implements InPlayListener {
- List<SaxEvent> saxEventList;
-
- @Override
- public void begin(InterpretationContext ic, String name, Attributes attributes)
- throws ActionException {
- saxEventList = new ArrayList<SaxEvent>();
- ic.addInPlayListener(this);
- }
+public class ElseAction extends ThenOrElseActionBase {
@Override
- public void end(InterpretationContext ic, String name) throws ActionException {
- ic.removeInPlayListener(this);
- Object o = ic.peekObject();
- if (o instanceof IfAction) {
- IfAction ifAction = (IfAction) o;
- removeFirstLastFromList();
- ifAction.setElseSaxEventList(saxEventList);
- }
+ void registerEventList(IfAction ifAction, List<SaxEvent> eventList) {
+ ifAction.setElseSaxEventList(eventList);
+
}
- public void inPlay(SaxEvent event) {
- saxEventList.add(event);
- }
-
- void removeFirstLastFromList() {
- saxEventList.remove(0);
- saxEventList.remove(saxEventList.size() - 1);
- }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
index 2c35649..7898f4d 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
@@ -1,6 +1,7 @@
package ch.qos.logback.core.joran.conditional;
import java.util.List;
+import java.util.Stack;
import org.xml.sax.Attributes;
@@ -14,14 +15,22 @@ import ch.qos.logback.core.util.OptionHelper;
public class IfAction extends Action {
private static final String CONDITION_ATTR = "condition";
- Boolean boolResult;
- List<SaxEvent> thenSaxEventList;
- List<SaxEvent> elseSaxEventList;
+ Stack<IfState> stack = new Stack<IfState>();
+
@Override
public void begin(InterpretationContext ic, String name, Attributes attributes)
throws ActionException {
+ IfState state = new IfState();
+ boolean emptyStack = stack.isEmpty();
+ stack.push(state);
+
+ if(!emptyStack) {
+ return;
+ }
+
+ state.active = true;
ic.pushObject(this);
Condition condition = null;
@@ -37,7 +46,7 @@ public class IfAction extends Action {
}
if(condition!=null) {
- boolResult = condition.evaluate();
+ state.boolResult = condition.evaluate();
}
}
@@ -47,6 +56,12 @@ public class IfAction extends Action {
@Override
public void end(InterpretationContext ic, String name) throws ActionException {
+ IfState state = stack.pop();
+ if(!state.active) {
+ return;
+ }
+
+
Object o = ic.peekObject();
if (o == null) {
throw new IllegalStateException("Unexpected null object on stack");
@@ -62,15 +77,15 @@ public class IfAction extends Action {
}
ic.popObject();
- if (boolResult == null) {
+ if (state.boolResult == null) {
addError("Failed to determine \"if then else\" result");
return;
}
Interpreter interpreter = ic.getJoranInterpreter();
- List<SaxEvent> listToPlay = thenSaxEventList;
- if (!boolResult) {
- listToPlay = elseSaxEventList;
+ List<SaxEvent> listToPlay = state.thenSaxEventList;
+ if (!state.boolResult) {
+ listToPlay = state.elseSaxEventList;
}
// insert past this event
@@ -80,11 +95,29 @@ public class IfAction extends Action {
public void setThenSaxEventList(List<SaxEvent> thenSaxEventList) {
- this.thenSaxEventList = thenSaxEventList;
+ IfState state = stack.firstElement();
+ if(state.active) {
+ state.thenSaxEventList = thenSaxEventList;
+ } else {
+ throw new IllegalStateException("setThenSaxEventList() invoked on inactive IfAction");
+ }
}
public void setElseSaxEventList(List<SaxEvent> elseSaxEventList) {
- this.elseSaxEventList = elseSaxEventList;
+ IfState state = stack.firstElement();
+ if(state.active) {
+ state.elseSaxEventList = elseSaxEventList;
+ } else {
+ throw new IllegalStateException("setElseSaxEventList() invoked on inactive IfAction");
+ }
+
}
}
+
+class IfState {
+ Boolean boolResult;
+ List<SaxEvent> thenSaxEventList;
+ List<SaxEvent> elseSaxEventList;
+ boolean active;
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenAction.java
index 5e5f99b..4a95833 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenAction.java
@@ -1,46 +1,28 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under either
+ * the terms of the Eclipse Public License v1.0 as published by the Eclipse
+ * Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ */
package ch.qos.logback.core.joran.conditional;
-import java.util.ArrayList;
import java.util.List;
-import org.xml.sax.Attributes;
-
-import ch.qos.logback.core.joran.action.Action;
-import ch.qos.logback.core.joran.event.InPlayListener;
import ch.qos.logback.core.joran.event.SaxEvent;
-import ch.qos.logback.core.joran.spi.ActionException;
-import ch.qos.logback.core.joran.spi.InterpretationContext;
-
-public class ThenAction extends Action implements InPlayListener {
- List<SaxEvent> eventList;
-
- @Override
- public void begin(InterpretationContext ic, String name, Attributes attributes)
- throws ActionException {
- eventList = new ArrayList<SaxEvent>();
- ic.addInPlayListener(this);
- }
+public class ThenAction extends ThenOrElseActionBase {
@Override
- public void end(InterpretationContext ic, String name) throws ActionException {
- ic.removeInPlayListener(this);
- Object o = ic.peekObject();
- if (o instanceof IfAction) {
- IfAction ifAction = (IfAction) o;
- removeFirstLastFromList();
- ifAction.setThenSaxEventList(eventList);
- } else {
- throw new IllegalStateException("Missing IfAction on top of stack");
- }
+ void registerEventList(IfAction ifAction, List<SaxEvent> eventList) {
+ ifAction.setThenSaxEventList(eventList);
+
}
- public void inPlay(SaxEvent event) {
- eventList.add(event);
- }
-
- void removeFirstLastFromList() {
- eventList.remove(0);
- eventList.remove(eventList.size() - 1);
- }
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenOrElseActionBase.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenOrElseActionBase.java
new file mode 100644
index 0000000..1b52a8c
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenOrElseActionBase.java
@@ -0,0 +1,76 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under either
+ * the terms of the Eclipse Public License v1.0 as published by the Eclipse
+ * Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.joran.conditional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.event.InPlayListener;
+import ch.qos.logback.core.joran.event.SaxEvent;
+import ch.qos.logback.core.joran.spi.ActionException;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+
+abstract public class ThenOrElseActionBase extends Action {
+
+ Stack<ThenActionState> stateStack = new Stack<ThenActionState>();
+
+ @Override
+ public void begin(InterpretationContext ic, String name, Attributes attributes)
+ throws ActionException {
+ ThenActionState state = new ThenActionState();
+ if (ic.isListenerListEmpty()) {
+ ic.addInPlayListener(state);
+ state.isRegistered = true;
+ }
+ stateStack.push(state);
+ }
+
+ @Override
+ public void end(InterpretationContext ic, String name) throws ActionException {
+ ThenActionState state = stateStack.pop();
+ if (state.isRegistered) {
+ ic.removeInPlayListener(state);
+ Object o = ic.peekObject();
+ if (o instanceof IfAction) {
+ IfAction ifAction = (IfAction) o;
+ removeFirstAndLastFromList(state.eventList);
+ registerEventList(ifAction, state.eventList);
+ } else {
+ throw new IllegalStateException("Missing IfAction on top of stack");
+ }
+ }
+ }
+
+ abstract void registerEventList(IfAction ifAction, List<SaxEvent> eventList);
+
+ void removeFirstAndLastFromList(List<SaxEvent> eventList) {
+ eventList.remove(0);
+ eventList.remove(eventList.size() - 1);
+ }
+
+}
+
+class ThenActionState implements InPlayListener {
+
+ List<SaxEvent> eventList = new ArrayList<SaxEvent>();
+ boolean isRegistered = false;
+
+ public void inPlay(SaxEvent event) {
+ eventList.add(event);
+ }
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
index ccdc9a3..a594014 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
@@ -173,6 +173,13 @@ public class InterpretationContext extends ContextAwareBase implements
return OptionHelper.substVars(value, this);
}
+
+
+
+ public boolean isListenerListEmpty() {
+ return listenerList.isEmpty();
+ }
+
public void addInPlayListener(InPlayListener ipl) {
if (listenerList.contains(ipl)) {
addWarn("InPlayListener " + ipl + " has been already registered");
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
index b720312..599c776 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
@@ -337,29 +337,6 @@ public class Interpreter {
player.addEventsDynamically(eventList, offset);
}
}
-
- /**
- * Pop from the stack if the top most element matches 'name'. Returns whether
- * the top most element matched.
- *
- * @param name
- * @return whether the top most element matched 'name'
- */
- public boolean popIfMatch(String name) {
- boolean match = pattern.peekLast().equals(name);
- if (match) {
- pattern.pop();
- }
- return match;
- }
-
- /**
- * Intended for internal use.
- * @param name
- */
- public void patternPush(String name) {
- pattern.push(name);
- }
}
/**
diff --git a/logback-core/src/test/input/joran/conditional/if0.xml b/logback-core/src/test/input/joran/conditional/if0.xml
index 0273e59..b843dcc 100644
--- a/logback-core/src/test/input/joran/conditional/if0.xml
+++ b/logback-core/src/test/input/joran/conditional/if0.xml
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<x>
+ <stack name="BEGIN"/>
<if condition='p("Ki1").equals("Val1")'>
<then>
- <inc increment="1"/>
+ <stack name="a"/>
</then>
<else>
- <inc increment="1"/>
- <inc increment="1"/>
+ <stack name="b"/>
</else>
</if>
+ <stack name="END"/>
</x>
diff --git a/logback-core/src/test/input/joran/conditional/if2.xml b/logback-core/src/test/input/joran/conditional/if2.xml
deleted file mode 100644
index bc70e1f..0000000
--- a/logback-core/src/test/input/joran/conditional/if2.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<x>
- <if class="">
- <a>asd</a>
- <then>
- <inc increment="1"/>
- </then>
- <else>
- <inc increment="1"/>
- <inc increment="1"/>
- </else>
- </if>
-</x>
diff --git a/logback-core/src/test/input/joran/inclusion/included.xml b/logback-core/src/test/input/joran/conditional/includedA.xml
similarity index 51%
copy from logback-core/src/test/input/joran/inclusion/included.xml
copy to logback-core/src/test/input/joran/conditional/includedA.xml
index 7dfb5fe..ecb4360 100644
--- a/logback-core/src/test/input/joran/inclusion/included.xml
+++ b/logback-core/src/test/input/joran/conditional/includedA.xml
@@ -2,8 +2,6 @@
<!DOCTYPE included>
<included>
-
- <inc increment="1"/>
- <inc increment="1"/>
-
+ <stack name="IncludedA0"/>
+ <stack name="IncludedA1"/>
</included>
\ No newline at end of file
diff --git a/logback-core/src/test/input/joran/inclusion/second.xml b/logback-core/src/test/input/joran/conditional/includedB.xml
similarity index 63%
copy from logback-core/src/test/input/joran/inclusion/second.xml
copy to logback-core/src/test/input/joran/conditional/includedB.xml
index 3351857..84974b7 100644
--- a/logback-core/src/test/input/joran/inclusion/second.xml
+++ b/logback-core/src/test/input/joran/conditional/includedB.xml
@@ -2,7 +2,5 @@
<!DOCTYPE included>
<included>
-
- <inc increment="1"/>
-
+ <stack name="IncludedB0"/>
</included>
\ No newline at end of file
diff --git a/logback-core/src/test/input/joran/conditional/nestedIf.xml b/logback-core/src/test/input/joran/conditional/nestedIf.xml
new file mode 100644
index 0000000..0751237
--- /dev/null
+++ b/logback-core/src/test/input/joran/conditional/nestedIf.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+
+<x>
+ <stack name="BEGIN"/>
+
+ <if condition='1 == 1'>
+ <then>
+ <stack name="a"/>
+ <if condition='1 != 1'>
+ <then>
+ <stack name="b"/>
+ </then>
+ <else>
+ <stack name="c"/>
+ </else>
+ </if>
+ </then>
+ <else>
+ <stack name="d"/>
+ </else>
+ </if>
+ <stack name="END"/>
+
+</x>
+
diff --git a/logback-core/src/test/input/joran/conditional/nestedInclude.xml b/logback-core/src/test/input/joran/conditional/nestedInclude.xml
new file mode 100644
index 0000000..4aa8617
--- /dev/null
+++ b/logback-core/src/test/input/joran/conditional/nestedInclude.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+
+<x>
+ <stack name="BEGIN"/>
+
+ <if condition='1 != 1'>
+ <then>
+ <stack name="t0"/>
+ <include file="${thenFileToInclude}"/>
+ <stack name="t1"/>
+ </then>
+ <else>
+ <stack name="e0"/>
+ <include file="${elseFileToInclude}"/>
+ <stack name="e1"/>
+ </else>
+ </if>
+ <stack name="END"/>
+
+</x>
+
diff --git a/logback-core/src/test/input/joran/inclusion/included.xml b/logback-core/src/test/input/joran/inclusion/included.xml
index 7dfb5fe..8ce1cd1 100644
--- a/logback-core/src/test/input/joran/inclusion/included.xml
+++ b/logback-core/src/test/input/joran/inclusion/included.xml
@@ -3,7 +3,7 @@
<included>
- <inc increment="1"/>
- <inc increment="1"/>
+ <stack name="IA"/>
+ <stack name="IB"/>
</included>
\ No newline at end of file
diff --git a/logback-core/src/test/input/joran/inclusion/intermediaryByFile.xml b/logback-core/src/test/input/joran/inclusion/intermediaryByFile.xml
new file mode 100644
index 0000000..dce2acb
--- /dev/null
+++ b/logback-core/src/test/input/joran/inclusion/intermediaryByFile.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE x>
+
+<included>
+ <stack name="a"/>
+ <include file="${subFileKey}" />
+ <stack name="c"/>
+</included>
diff --git a/logback-core/src/test/input/joran/inclusion/second.xml b/logback-core/src/test/input/joran/inclusion/second.xml
index 3351857..32beaf0 100644
--- a/logback-core/src/test/input/joran/inclusion/second.xml
+++ b/logback-core/src/test/input/joran/inclusion/second.xml
@@ -3,6 +3,6 @@
<included>
- <inc increment="1"/>
+ <stack name="SECOND"/>
</included>
\ No newline at end of file
diff --git a/logback-core/src/test/input/joran/inclusion/subByFile.xml b/logback-core/src/test/input/joran/inclusion/subByFile.xml
index 5f82d77..b351583 100644
--- a/logback-core/src/test/input/joran/inclusion/subByFile.xml
+++ b/logback-core/src/test/input/joran/inclusion/subByFile.xml
@@ -1,6 +1,3 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE included>
-
<included>
- <include file="${includeKey}" />
-</<included>
+ <stack name="b"/>
+</included>
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
index d65ac45..ad7a3f6 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
@@ -23,7 +23,9 @@ import org.junit.runners.Suite.SuiteClasses;
ch.qos.logback.core.joran.util.PackageTest.class,
ch.qos.logback.core.joran.spi.PackageTest.class,
ch.qos.logback.core.joran.replay.PackageTest.class,
- ch.qos.logback.core.joran.implicitAction.PackageTest.class
+ ch.qos.logback.core.joran.implicitAction.PackageTest.class,
+ ch.qos.logback.core.joran.conditional.PackageTest.class,
+
})
public class PackageTest {
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
index 372a00b..1f31383 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
@@ -23,7 +23,9 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.Stack;
import org.junit.After;
import org.junit.Before;
@@ -33,7 +35,7 @@ import org.xml.sax.SAXParseException;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.joran.TrivialConfigurator;
-import ch.qos.logback.core.joran.action.ext.IncAction;
+import ch.qos.logback.core.joran.action.ext.StackAction;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.status.Status;
@@ -57,6 +59,9 @@ public class IncludeActionTest {
static final String TOP_BY_FILE = INCLUSION_DIR_PREFIX + "topByFile.xml";
+ static final String INTERMEDIARY_FILE = INCLUSION_DIR_PREFIX + "intermediaryByFile.xml";
+
+
static final String SUB_FILE = INCLUSION_DIR_PREFIX + "subByFile.xml";
static final String MULTI_INCLUDE_BY_FILE = INCLUSION_DIR_PREFIX
@@ -82,43 +87,42 @@ public class IncludeActionTest {
public void setUp() throws Exception {
HashMap<Pattern, Action> rulesMap = new HashMap<Pattern, Action>();
rulesMap.put(new Pattern("x"), new NOPAction());
- rulesMap.put(new Pattern("x/inc"), new IncAction());
rulesMap.put(new Pattern("x/include"), new IncludeAction());
-
+ rulesMap.put(new Pattern("x/stack"), new StackAction());
+
tc = new TrivialConfigurator(rulesMap);
tc.setContext(context);
- IncAction.reset();
}
@After
public void tearDown() throws Exception {
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
context = null;
System.clearProperty(INCLUDE_KEY);
System.clearProperty(SECOND_FILE_KEY);
System.clearProperty(SUB_FILE_KEY);
+ StackAction.reset();
}
@Test
public void basicFile() throws JoranException {
System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
tc.doConfigure(TOP_BY_FILE);
- verifyConfig(2);
+ verifyConfig(new String[] {"IA", "IB"});
}
@Test
public void basicResource() throws JoranException {
System.setProperty(INCLUDE_KEY, INCLUDED_AS_RESOURCE);
tc.doConfigure(INCLUDE_BY_RESOURCE);
- StatusPrinter.print(context);
- verifyConfig(2);
+ verifyConfig(new String[] {"AR_A", "AR_B"});
}
@Test
public void basicURL() throws JoranException {
System.setProperty(INCLUDE_KEY, URL_TO_INCLUDE);
tc.doConfigure(TOP_BY_URL);
- StatusPrinter.print(context);
- verifyConfig(2);
+ verifyConfig(new String[] {"IA", "IB"});
}
@Test
@@ -184,37 +188,28 @@ public class IncludeActionTest {
@Test
public void nestedInclude() throws JoranException {
- System.setProperty(SUB_FILE_KEY, INCLUDED_FILE);
- System.setProperty(INCLUDE_KEY, SECOND_FILE);
+ System.setProperty(SUB_FILE_KEY, SUB_FILE);
+ System.setProperty(INCLUDE_KEY, INTERMEDIARY_FILE);
tc.doConfigure(TOP_BY_FILE);
- StatusPrinter.print(context);
- verifyConfig(1);
-
- }
+ Stack<String> witness = new Stack<String>();
+ witness.push("a");
+ witness.push("b");
+ witness.push("c");
+ assertEquals(witness, StackAction.stack);
+ }
@Test
public void multiInclude() throws JoranException {
System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
System.setProperty(SECOND_FILE_KEY, SECOND_FILE);
tc.doConfigure(MULTI_INCLUDE_BY_FILE);
- verifyConfig(3);
- }
-
- @Test
- public void saxParseException() throws JoranException {
- System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
- System.setProperty(SECOND_FILE_KEY, SECOND_FILE);
- tc.doConfigure(MULTI_INCLUDE_BY_FILE);
- verifyConfig(3);
- }
-
- @Test
- public void errorInDoBegin() {
-
+ verifyConfig(new String[] {"IA", "IB", "SECOND"});
}
-
- void verifyConfig(int expected) {
- assertEquals(expected, IncAction.beginCount);
- assertEquals(expected, IncAction.endCount);
+
+ void verifyConfig(String[] expected) {
+ Stack<String> witness = new Stack<String>();
+ witness.addAll(Arrays.asList(expected));
+ assertEquals(witness, StackAction.stack);
}
+
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackCounterAction.java b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackAction.java
similarity index 73%
rename from logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackCounterAction.java
rename to logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackAction.java
index 48beaff..e198345 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackCounterAction.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/StackAction.java
@@ -14,30 +14,27 @@
package ch.qos.logback.core.joran.action.ext;
+import java.util.Stack;
+
import org.xml.sax.Attributes;
-import ch.qos.logback.core.Layout;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-public class StackCounterAction extends Action {
- Layout layout;
-
+public class StackAction extends Action {
- public StackCounterAction() {
- }
+ public static Stack<String> stack = new Stack<String>();
public void begin(InterpretationContext ec, String name, Attributes attributes) {
- //String str = "Pushing "+name+"-begin";
- ec.pushObject(name+"-begin");
+ stack.push(attributes.getValue("name"));
}
public void end(InterpretationContext ec, String name) {
- ec.pushObject(name+"-end");
}
- public void finish(InterpretationContext ec) {
+ static public void reset() {
+ stack.clear();
}
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseAndIncludeCompositionTest.java
similarity index 59%
copy from logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
copy to logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseAndIncludeCompositionTest.java
index bf9aa89..c354999 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseAndIncludeCompositionTest.java
@@ -13,10 +13,11 @@
*/
package ch.qos.logback.core.joran.conditional;
-
import static org.junit.Assert.assertEquals;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.Stack;
import org.junit.After;
import org.junit.Before;
@@ -26,33 +27,42 @@ import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.joran.TrivialConfigurator;
import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.action.IncludeAction;
import ch.qos.logback.core.joran.action.NOPAction;
-import ch.qos.logback.core.joran.action.ext.IncAction;
+import ch.qos.logback.core.joran.action.ext.StackAction;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
import ch.qos.logback.core.util.StatusPrinter;
-public class IfThenElseTest {
+public class IfThenElseAndIncludeCompositionTest {
Context context = new ContextBase();
TrivialConfigurator tc;
int diff = RandomUtil.getPositiveInt();
static final String CONDITIONAL_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX
- + "conditional/";
+ + "conditional/";
+ final static String THEN_FILE_TO_INCLUDE_KEY = "thenFileToInclude";
+ final static String ELSE_FILE_TO_INCLUDE_KEY = "elseFileToInclude";
+
+ static final String NESTED_INCLUDE_FILE = CONDITIONAL_DIR_PREFIX+"nestedInclude.xml";
+ static final String THEN_FILE_TO_INCLUDE = CONDITIONAL_DIR_PREFIX+"includedA.xml";
+ static final String ELSE_FILE_TO_INCLUDE = CONDITIONAL_DIR_PREFIX+"includedB.xml";
+
@Before
public void setUp() throws Exception {
HashMap<Pattern, Action> rulesMap = new HashMap<Pattern, Action>();
rulesMap.put(new Pattern("x"), new NOPAction());
- rulesMap.put(new Pattern("x/inc"), new IncAction());
+ rulesMap.put(new Pattern("x/stack"), new StackAction());
rulesMap.put(new Pattern("*/if"), new IfAction());
rulesMap.put(new Pattern("*/if/then"), new ThenAction());
rulesMap.put(new Pattern("*/if/then/*"), new NOPAction());
rulesMap.put(new Pattern("*/if/else"), new ElseAction());
rulesMap.put(new Pattern("*/if/else/*"), new NOPAction());
+ rulesMap.put(new Pattern("x/include"), new IncludeAction());
tc = new TrivialConfigurator(rulesMap);
tc.setContext(context);
@@ -60,29 +70,24 @@ public class IfThenElseTest {
@After
public void tearDown() throws Exception {
- IncAction.reset();
- }
-
- @Test
- public void if0_Then() throws JoranException {
- context.putProperty("Ki1", "Val1");
- tc.doConfigure(CONDITIONAL_DIR_PREFIX+"if0.xml");
- verifyConfig(1);
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ context = null;
+ StackAction.reset();
}
-
- @Test
- public void if0_Else() throws JoranException {
- tc.doConfigure(CONDITIONAL_DIR_PREFIX+"if0.xml");
- StatusPrinter.print(context);
- verifyConfig(2);
- }
-
- void verifyConfig(int expected) {
- assertEquals(expected, IncAction.beginCount);
- assertEquals(expected, IncAction.endCount);
+ @Test
+ public void includeNestedWithinIf() throws JoranException {
+ context.putProperty(THEN_FILE_TO_INCLUDE_KEY, THEN_FILE_TO_INCLUDE);
+ context.putProperty(ELSE_FILE_TO_INCLUDE_KEY, ELSE_FILE_TO_INCLUDE);
+ tc.doConfigure(NESTED_INCLUDE_FILE);
+ verifyConfig(new String[] {"BEGIN", "e0", "IncludedB0", "e1", "END"});
}
+ void verifyConfig(String[] expected) {
+ Stack<String> witness = new Stack<String>();
+ witness.addAll(Arrays.asList(expected));
+ assertEquals(witness, StackAction.stack);
+ }
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
index bf9aa89..5d3f98b 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/IfThenElseTest.java
@@ -16,7 +16,9 @@ package ch.qos.logback.core.joran.conditional;
import static org.junit.Assert.assertEquals;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.Stack;
import org.junit.After;
import org.junit.Before;
@@ -27,7 +29,7 @@ import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.joran.TrivialConfigurator;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.action.NOPAction;
-import ch.qos.logback.core.joran.action.ext.IncAction;
+import ch.qos.logback.core.joran.action.ext.StackAction;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.testUtil.RandomUtil;
@@ -47,7 +49,7 @@ public class IfThenElseTest {
public void setUp() throws Exception {
HashMap<Pattern, Action> rulesMap = new HashMap<Pattern, Action>();
rulesMap.put(new Pattern("x"), new NOPAction());
- rulesMap.put(new Pattern("x/inc"), new IncAction());
+ rulesMap.put(new Pattern("x/stack"), new StackAction());
rulesMap.put(new Pattern("*/if"), new IfAction());
rulesMap.put(new Pattern("*/if/then"), new ThenAction());
rulesMap.put(new Pattern("*/if/then/*"), new NOPAction());
@@ -60,27 +62,34 @@ public class IfThenElseTest {
@After
public void tearDown() throws Exception {
- IncAction.reset();
+ StackAction.reset();
}
@Test
public void if0_Then() throws JoranException {
context.putProperty("Ki1", "Val1");
tc.doConfigure(CONDITIONAL_DIR_PREFIX+"if0.xml");
- verifyConfig(1);
+ StatusPrinter.printIfErrorsOccured(context);
+ verifyConfig(new String[] {"BEGIN", "a", "END"});
}
@Test
public void if0_Else() throws JoranException {
tc.doConfigure(CONDITIONAL_DIR_PREFIX+"if0.xml");
- StatusPrinter.print(context);
- verifyConfig(2);
+ verifyConfig(new String[] {"BEGIN", "b", "END"});
}
+ @Test
+ public void nestedIf() throws JoranException {
+ tc.doConfigure(CONDITIONAL_DIR_PREFIX+"nestedIf.xml");
+ StatusPrinter.printIfErrorsOccured(context);
+ verifyConfig(new String[] {"BEGIN", "a", "c", "END"});
+ }
- void verifyConfig(int expected) {
- assertEquals(expected, IncAction.beginCount);
- assertEquals(expected, IncAction.endCount);
+ void verifyConfig(String[] expected) {
+ Stack<String> witness = new Stack<String>();
+ witness.addAll(Arrays.asList(expected));
+ assertEquals(witness, StackAction.stack);
}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PackageTest.java
similarity index 59%
copy from logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
copy to logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PackageTest.java
index d65ac45..0a5b973 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/joran/conditional/PackageTest.java
@@ -11,20 +11,15 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
-package ch.qos.logback.core.joran;
+package ch.qos.logback.core.joran.conditional;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-(a)SuiteClasses({SkippingInInterpreterTest.class, TrivialConfiguratorTest.class, ch.qos.logback.core.joran.action.PackageTest.class,
- ch.qos.logback.core.joran.event.PackageTest.class,
- ch.qos.logback.core.joran.util.PackageTest.class,
- ch.qos.logback.core.joran.spi.PackageTest.class,
- ch.qos.logback.core.joran.replay.PackageTest.class,
- ch.qos.logback.core.joran.implicitAction.PackageTest.class
- })
+@SuiteClasses( { PropertyEvalScriptBuilderTest.class, IfThenElseTest.class,
+ IfThenElseAndIncludeCompositionTest.class })
public class PackageTest {
}
diff --git a/logback-core/src/test/resources/asResource/joran/inclusion/includedAsResource.xml b/logback-core/src/test/resources/asResource/joran/inclusion/includedAsResource.xml
index 1b80687..e80121e 100644
--- a/logback-core/src/test/resources/asResource/joran/inclusion/includedAsResource.xml
+++ b/logback-core/src/test/resources/asResource/joran/inclusion/includedAsResource.xml
@@ -3,7 +3,7 @@
<included>
- <inc increment="1"/>
- <inc increment="1"/>
+ <stack name="AR_A" />
+ <stack name="AR_B" />
</included>
\ No newline at end of file
-----------------------------------------------------------------------
Summary of changes:
.../logback/core/joran/conditional/ElseAction.java | 50 +++++---------
.../logback/core/joran/conditional/IfAction.java | 53 +++++++++++---
.../logback/core/joran/conditional/ThenAction.java | 52 +++++---------
.../joran/conditional/ThenOrElseActionBase.java | 76 ++++++++++++++++++++
.../core/joran/spi/InterpretationContext.java | 7 ++
.../ch/qos/logback/core/joran/spi/Interpreter.java | 23 ------
.../src/test/input/joran/conditional/if0.xml | 7 +-
.../src/test/input/joran/conditional/if2.xml | 14 ----
.../included.xml => conditional/includedA.xml} | 6 +-
.../second.xml => conditional/includedB.xml} | 4 +-
.../src/test/input/joran/conditional/nestedIf.xml | 26 +++++++
.../test/input/joran/conditional/nestedInclude.xml | 22 ++++++
.../src/test/input/joran/inclusion/included.xml | 4 +-
.../input/joran/inclusion/intermediaryByFile.xml | 8 ++
.../src/test/input/joran/inclusion/second.xml | 2 +-
.../src/test/input/joran/inclusion/subByFile.xml | 7 +--
.../ch/qos/logback/core/joran/PackageTest.java | 4 +-
.../core/joran/action/IncludeActionTest.java | 61 +++++++---------
.../{StackCounterAction.java => StackAction.java} | 17 ++---
...va => IfThenElseAndIncludeCompositionTest.java} | 53 ++++++++------
.../core/joran/conditional/IfThenElseTest.java | 27 +++++---
.../conditional}/PackageTest.java | 5 +-
.../joran/inclusion/includedAsResource.xml | 4 +-
23 files changed, 318 insertions(+), 214 deletions(-)
create mode 100644 logback-core/src/main/java/ch/qos/logback/core/joran/conditional/ThenOrElseActionBase.java
delete mode 100644 logback-core/src/test/input/joran/conditional/if2.xml
copy logback-core/src/test/input/joran/{inclusion/included.xml => conditional/includedA.xml} (51%)
copy logback-core/src/test/input/joran/{inclusion/second.xml => conditional/includedB.xml} (63%)
create mode 100644 logback-core/src/test/input/joran/conditional/nestedIf.xml
create mode 100644 logback-core/src/test/input/joran/conditional/nestedInclude.xml
create mode 100644 logback-core/src/test/input/joran/inclusion/intermediaryByFile.xml
rename logback-core/src/test/java/ch/qos/logback/core/joran/action/ext/{StackCounterAction.java => StackAction.java} (73%)
copy logback-core/src/test/java/ch/qos/logback/core/joran/conditional/{IfThenElseTest.java => IfThenElseAndIncludeCompositionTest.java} (59%)
copy logback-core/src/test/java/ch/qos/logback/core/{helpers => joran/conditional}/PackageTest.java (78%)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. release_0.9.19-8-gc9f58e8
by git-noreply@pixie.qos.ch 30 Mar '10
by git-noreply@pixie.qos.ch 30 Mar '10
30 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via c9f58e8f6a1372a08fef830ac1c3e8faa38c5abf (commit)
from 199e8d6d8218c1bf526c224e867891110ac0ecbb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=c9f58e8f6a1372a08fef830a…
http://github.com/ceki/logback/commit/c9f58e8f6a1372a08fef830ac1c3e8faa38c5…
commit c9f58e8f6a1372a08fef830ac1c3e8faa38c5abf
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Tue Mar 30 14:33:46 2010 +0200
all tests pass
diff --git a/logback-classic/src/test/input/joran/conditional/conditionalConsoleApp_ELSE.xml b/logback-classic/src/test/input/joran/conditional/conditionalConsoleApp_ELSE.xml
new file mode 100644
index 0000000..426fc24
--- /dev/null
+++ b/logback-classic/src/test/input/joran/conditional/conditionalConsoleApp_ELSE.xml
@@ -0,0 +1,41 @@
+
+<configuration>
+
+ <if condition='property("HOSTNAME").equals("XYZ87")'>
+ <then>
+
+ <appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d %-5level %logger{35} - %msg %n</pattern>
+ </encoder>
+ </appender>
+ <root>
+ <appender-ref ref="CON" />
+ </root>
+
+ </then>
+ <else>
+
+ <appender name="LIST" class="ch.qos.logback.core.read.ListAppender"/>
+ <root>
+ <appender-ref ref="LIST" />
+ </root>
+
+ </else>
+ </if>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${randomOutputDir}/conditional.log</file>
+ <encoder>
+ <pattern>%d %-5level %logger{35} - %msg %n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="ERROR">
+ <appender-ref ref="FILE" />
+ </root>
+
+
+
+
+</configuration>
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/JaninoEventEvaluatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/JaninoEventEvaluatorTest.java
index 5b4b8c7..e9d6a07 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/JaninoEventEvaluatorTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/JaninoEventEvaluatorTest.java
@@ -110,7 +110,7 @@ public class JaninoEventEvaluatorTest {
String k = "key"+diff;
MDC.put("key"+diff, "value"+diff);
- jee.setExpression("mdc.get(\""+k+"\").contains(\"alue\")");
+ jee.setExpression("((String) mdc.get(\""+k+"\")).contains(\"alue\")");
jee.start();
StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
index 5ece151..8235d72 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
@@ -17,8 +17,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
-
@RunWith(Suite.class)
-@SuiteClasses( { JoranConfiguratorTest.class, EvaluatorJoranTest.class})
+@SuiteClasses( { JoranConfiguratorTest.class, EvaluatorJoranTest.class,
+ ch.qos.logback.classic.joran.conditional.PackageTest.class })
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
index 0c1329c..be99ad2 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/ConditionalTest.java
@@ -14,6 +14,8 @@
package ch.qos.logback.classic.joran.conditional;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.InetAddress;
@@ -29,6 +31,8 @@ import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.status.StatusChecker;
import ch.qos.logback.core.testUtil.RandomUtil;
import ch.qos.logback.core.util.CoreTestConstants;
import ch.qos.logback.core.util.StatusPrinter;
@@ -59,7 +63,7 @@ public class ConditionalTest {
}
@Test
- public void conditionalConsoleApp() throws JoranException, IOException,
+ public void conditionalConsoleApp_THEN() throws JoranException, IOException,
InterruptedException {
String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
@@ -71,7 +75,33 @@ public class ConditionalTest {
ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
assertNotNull(consoleAppender);
StatusPrinter.printIfErrorsOccured(context);
+ StatusChecker checker = new StatusChecker(context);
+ assertTrue(checker.isErrorFree());
+ }
+
+ @Test
+ public void conditionalConsoleApp_ELSE() throws JoranException, IOException,
+ InterruptedException {
-
+ String configFileAsStr = ClassicTestConstants.JORAN_INPUT_PREFIX
+ + "conditional/conditionalConsoleApp_ELSE.xml";
+ configure(configFileAsStr);
+
+ StatusPrinter.print(context);
+
+
+ FileAppender fileAppender = (FileAppender) root.getAppender("FILE");
+ assertNotNull(fileAppender);
+
+ ConsoleAppender consoleAppender = (ConsoleAppender) root.getAppender("CON");
+ assertNull(consoleAppender);
+
+ ListAppender listAppender = (ListAppender) root.getAppender("LIST");
+ assertNotNull(listAppender);
+
+ //StatusPrinter.printIfErrorsOccured(context);
+ StatusChecker checker = new StatusChecker(context);
+ assertTrue(checker.isErrorFree());
}
+
}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/PackageTest.java
similarity index 85%
copy from logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
copy to logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/PackageTest.java
index 5ece151..3e1ecce 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional/PackageTest.java
@@ -11,7 +11,7 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
-package ch.qos.logback.classic.joran;
+package ch.qos.logback.classic.joran.conditional;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -19,6 +19,6 @@ import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-@SuiteClasses( { JoranConfiguratorTest.class, EvaluatorJoranTest.class})
+@SuiteClasses( { ConditionalTest.class})
public class PackageTest {
}
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
index 51aa4df..befbdc3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
@@ -65,7 +65,8 @@ public class IncludeAction extends Action {
// remove the <included> tag from the beginning and </included> from the end
trimHeadAndTail(recorder);
- ec.getJoranInterpreter().addEventsDynamically(recorder.saxEventList);
+ // offset = 2, because we need to get past this element as well as the end element
+ ec.getJoranInterpreter().addEventsDynamically(recorder.saxEventList, 2);
}
void close(InputStream in) {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
index 513d350..2c35649 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/IfAction.java
@@ -73,14 +73,12 @@ public class IfAction extends Action {
listToPlay = elseSaxEventList;
}
- if (interpreter.pattern.peekLast().equals("if")) {
- interpreter.pattern.pop();
- interpreter.play(listToPlay);
- interpreter.pattern.push("if");
- }
+ // insert past this event
+ interpreter.addEventsDynamically(listToPlay, 1);
}
+
public void setThenSaxEventList(List<SaxEvent> thenSaxEventList) {
this.thenSaxEventList = thenSaxEventList;
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilder.java b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilder.java
index e29c414..64f7716 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/conditional/PropertyEvalScriptBuilder.java
@@ -9,7 +9,6 @@ import org.codehaus.janino.ClassBodyEvaluator;
import org.codehaus.janino.CompileException;
import org.codehaus.janino.Parser.ParseException;
import org.codehaus.janino.Scanner.ScanException;
-import org.junit.Before;
import ch.qos.logback.core.spi.ContextAwareBase;
@@ -24,7 +23,6 @@ public class PropertyEvalScriptBuilder extends ContextAwareBase {
Map<String, String> map = new HashMap<String, String>();
- @Before
public Condition build(String script) throws IllegalAccessException,
CompileException, ParseException, ScanException, InstantiationException,
SecurityException, NoSuchMethodException, IllegalArgumentException,
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
index 7f383f6..528e4fd 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
@@ -55,7 +55,7 @@ public class EventPlayer {
}
}
- public void addEventsDynamically(List<SaxEvent> eventList) {
- this.eventList.addAll(currentIndex+2, eventList);
+ public void addEventsDynamically(List<SaxEvent> eventList, int offset) {
+ this.eventList.addAll(currentIndex+offset, eventList);
}
}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
index a19603b..b720312 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
@@ -72,7 +72,7 @@ public class Interpreter {
final private InterpretationContext interpretationContext;
final private ArrayList<ImplicitAction> implicitActions;
final private CAI_WithLocatorSupport cai;
- public Pattern pattern;
+ private Pattern pattern;
Locator locator;
EventPlayer player;
@@ -102,17 +102,19 @@ public class Interpreter {
actionListStack = new Stack<List>();
player = new EventPlayer(this);
}
-
- public void setInterpretationContextPropertiesMap(Map<String, String> propertiesMap) {
+
+ public void setInterpretationContextPropertiesMap(
+ Map<String, String> propertiesMap) {
interpretationContext.setPropertiesMap(propertiesMap);
}
+
/**
* @deprecated replaced by {@link #getInterpretationContext()}
*/
public InterpretationContext getExecutionContext() {
return getInterpretationContext();
}
-
+
public InterpretationContext getInterpretationContext() {
return interpretationContext;
}
@@ -149,9 +151,9 @@ public class Interpreter {
cai.addError(errMsg);
}
}
-
+
/**
- * This method is used to
+ * This method is used to
*/
private void pushEmptyActionList() {
actionListStack.add(EMPTY_LIST);
@@ -179,10 +181,11 @@ public class Interpreter {
}
private void endElement(String namespaceURI, String localName, String qName) {
- // given that an action list is always pushed for every startElement, we need
+ // given that an action list is always pushed for every startElement, we
+ // need
// to always pop for every endElement
List applicableActionList = (List) actionListStack.pop();
-
+
if (skip != null) {
if (skip.equals(pattern)) {
skip = null;
@@ -248,7 +251,8 @@ public class Interpreter {
// logger.debug("set of applicable patterns: " + applicableActionList);
if (applicableActionList == null) {
- applicableActionList = lookupImplicitAction(pattern, attributes, interpretationContext);
+ applicableActionList = lookupImplicitAction(pattern, attributes,
+ interpretationContext);
}
return applicableActionList;
@@ -328,10 +332,33 @@ public class Interpreter {
player.play(eventList);
}
- public void addEventsDynamically(List<SaxEvent> eventList) {
+ public void addEventsDynamically(List<SaxEvent> eventList, int offset) {
if (player != null) {
- player.addEventsDynamically(eventList);
+ player.addEventsDynamically(eventList, offset);
+ }
+ }
+
+ /**
+ * Pop from the stack if the top most element matches 'name'. Returns whether
+ * the top most element matched.
+ *
+ * @param name
+ * @return whether the top most element matched 'name'
+ */
+ public boolean popIfMatch(String name) {
+ boolean match = pattern.peekLast().equals(name);
+ if (match) {
+ pattern.pop();
}
+ return match;
+ }
+
+ /**
+ * Intended for internal use.
+ * @param name
+ */
+ public void patternPush(String name) {
+ pattern.push(name);
}
}
-----------------------------------------------------------------------
Summary of changes:
...nsoleApp.xml => conditionalConsoleApp_ELSE.xml} | 36 ++++++++++-----
.../classic/boolex/JaninoEventEvaluatorTest.java | 2 +-
.../ch/qos/logback/classic/joran/PackageTest.java | 4 +-
.../classic/joran/conditional/ConditionalTest.java | 34 +++++++++++++-
.../classic/joran/conditional}/PackageTest.java | 8 ++--
.../logback/core/joran/action/IncludeAction.java | 3 +-
.../logback/core/joran/conditional/IfAction.java | 8 +--
.../conditional/PropertyEvalScriptBuilder.java | 2 -
.../ch/qos/logback/core/joran/spi/EventPlayer.java | 4 +-
.../ch/qos/logback/core/joran/spi/Interpreter.java | 49 +++++++++++++++----
10 files changed, 108 insertions(+), 42 deletions(-)
copy logback-classic/src/test/input/joran/conditional/{conditionalConsoleApp.xml => conditionalConsoleApp_ELSE.xml} (71%)
copy {logback-core/src/test/java/ch/qos/logback/core/helpers => logback-classic/src/test/java/ch/qos/logback/classic/joran/conditional}/PackageTest.java (87%)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
Hello all,
I began implementing if-then-else support in Joran. If you wish to
enable part of a config file in one environment and disable it
another, now you can.
Here is an example,
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
<if condition='property("HOSTNAME").contains("mydevHost")'>
<then>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root incremental="true">
<appender-ref ref="STDOUT" />
</root>
</then>
</if>
</configuration>
Thus, the ConsoleAppender will be attached to the root logger only on
"mydevHost" but not on other hosts.
This feature is still experimental. Your feedback is welcome.
--
Ceki
2
3