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
- 9940 discussions

svn commit: r860 - logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi
by noreply.ceki@qos.ch 02 Nov '06
by noreply.ceki@qos.ch 02 Nov '06
02 Nov '06
Author: ceki
Date: Thu Nov 2 22:14:02 2006
New Revision: 860
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachable.java
Log:
minor fix
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachable.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachable.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachable.java Thu Nov 2 22:14:02 2006
@@ -8,7 +8,7 @@
import ch.qos.logback.core.spi.FilterReply;
/**
- * Interface for attaching ClassicFilter instances to objects.
+ * Interface for attaching {@link TurboFilter} instances to objects.
*
* @author Ceki Gülcü
*/
1
0

svn commit: r859 - in logback/trunk: logback-core/src/main/java/ch/qos/logback/core/rolling logback-site/src/site/fml
by noreply.seb@qos.ch 02 Nov '06
by noreply.seb@qos.ch 02 Nov '06
02 Nov '06
Author: seb
Date: Thu Nov 2 21:03:48 2006
New Revision: 859
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
logback/trunk/logback-site/src/site/fml/codes.fml
Log:
Moved tests to getNewActiveFileName method
Added an entry to codes.fml when filename is not set
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java Thu Nov 2 21:03:48 2006
@@ -21,7 +21,7 @@
* according to a fixed window algorithm as described below.
*
* <p>
- * The <b>ActiveFileName</b> property, which is required, represents the name
+ * The <b>File</b> property, which is required, represents the name
* of the file where current logging output will be written. The
* <b>FileNamePattern</b> option represents the file name pattern for the
* archived (rolled over) log files. If present, the <b>FileNamePattern</b>
@@ -54,6 +54,7 @@
public class FixedWindowRollingPolicy extends RollingPolicyBase {
static final String FNP_NOT_SET = "The FileNamePattern option must be set before using FixedWindowRollingPolicy. ";
static final String SEE_FNP_NOT_SET = "See also http://logback.qos.ch/codes.html#tbr_fnp_not_set";
+ static final String SEE_PARENT_FN_NOT_SET = "Please refer to http://logback.qos.ch/codes.html#fwrp_parentFileName_not_set";
int maxIndex;
int minIndex;
RenameUtil util = new RenameUtil();
@@ -82,9 +83,10 @@
addWarn(SEE_FNP_NOT_SET);
throw new IllegalStateException(FNP_NOT_SET + SEE_FNP_NOT_SET);
}
- // if (activeFileName == null) {
- if (getNewActiveFileName() == null) {
- addWarn("The ActiveFile name option must be set before using this rolling policy.");
+
+ if (getParentFileName() == null) {
+ addWarn("The File name option must be set before using this rolling policy.");
+ addWarn(SEE_PARENT_FN_NOT_SET);
throw new IllegalStateException("The ActiveFileName option must be set.");
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java Thu Nov 2 21:03:48 2006
@@ -81,9 +81,7 @@
if (rollingPolicy != null) {
//if no active file name was set, then it's the responsability of the
//rollingPolicy to create one.
- if (getFile() == null) {
- setFile(rollingPolicy.getNewActiveFileName());
- }
+ setFile(rollingPolicy.getNewActiveFileName());
activeFileCache = new File(getFile());
addInfo("Active log file name: "+ getFile());
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java Thu Nov 2 21:03:48 2006
@@ -246,11 +246,9 @@
}
}
- //if we already generated a name, then we have to update
- //the fileAppender with a new active file name.
- if (getParentFileName() == lastGeneratedFileName) {
- setParentFileName(getNewActiveFileName());
- }
+ //let's update the parent active file name
+ setParentFileName(getNewActiveFileName());
+
}
/**
@@ -273,16 +271,16 @@
* the RollingPolicy knows it's responsible for the change of the
* file name.
*
- *
- * tmp note: !!!!! This is called only once at the start of the appender,
- * and only if the parent file name is null, so no test is required.
- *
*/
public String getNewActiveFileName() {
- String newName = activeFileNamePattern.convertDate(lastCheck);
- addInfo("Generated a new name for RollingFileAppender: " + newName);
- lastGeneratedFileName = newName;
- return newName;
+ if (getParentFileName() == null || getParentFileName() == lastGeneratedFileName) {
+ String newName = activeFileNamePattern.convertDate(lastCheck);
+ addInfo("Generated a new name for RollingFileAppender: " + newName);
+ lastGeneratedFileName = newName;
+ return newName;
+ } else {
+ return getParentFileName();
+ }
}
public boolean isTriggeringEvent(File file, final Object event) {
Modified: logback/trunk/logback-site/src/site/fml/codes.fml
==============================================================================
--- logback/trunk/logback-site/src/site/fml/codes.fml (original)
+++ logback/trunk/logback-site/src/site/fml/codes.fml Thu Nov 2 21:03:48 2006
@@ -39,8 +39,31 @@
for more information.
</p>
</answer>
-
</faq>
+
+ <faq id="fwrp_parentFileName_not_set">
+
+ <question>
+ <p>The File name option must be set before <code>FixedWindowRollingPolicy</code>.</p>
+ </question>
+
+ <answer>
+ <p>
+ The <span class="option">File</span> option is mandatory with <code>FixedWindowRollingPolicy</code>. Moreover, the File option must be
+ set before the declaration configuring <code>FixedWindowRollingPolicy</code>.
+ </p>
+ <p>
+ See the logback manual's chapter about
+ <a
+ href="http://logback.qos.ch/manual/appenders.html#FixedWindowRollingPolicy">
+ FixedWindowRollingPolicy
+ </a>
+ for more information.
+ </p>
+ </answer>
+ </faq>
+
+
<faq id="socket_no_host">
<question>
No remote host or address is set for
1
0

svn commit: r858 - in logback/trunk: logback-examples logback-examples/src/main/java/chapter4 logback-site/src/site/xdocTemplates/manual logback-skin/src/main/resources/css
by noreply.seb@qos.ch 02 Nov '06
by noreply.seb@qos.ch 02 Nov '06
02 Nov '06
Author: seb
Date: Thu Nov 2 20:36:44 2006
New Revision: 858
Added:
logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java
logback/trunk/logback-examples/src/main/java/chapter4/IO.java
logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml
Modified:
logback/trunk/logback-examples/ (props changed)
logback/trunk/logback-examples/pom.xml
logback/trunk/logback-skin/src/main/resources/css/site.css
Log:
on going work, documenting appenders (chapter4)
modified css to display appender options
Modified: logback/trunk/logback-examples/pom.xml
==============================================================================
--- logback/trunk/logback-examples/pom.xml (original)
+++ logback/trunk/logback-examples/pom.xml Thu Nov 2 20:36:44 2006
@@ -31,18 +31,28 @@
</licenses>
<dependencies>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <classifier>tests</classifier>
+ </dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
</dependency>
+
</dependencies>
<build>
Added: logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java Thu Nov 2 20:36:44 2006
@@ -0,0 +1,41 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ *
+ * Copyright (C) 1999-2006, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package chapter4;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+import org.slf4j.Logger;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.core.WriterAppender;
+import ch.qos.logback.core.layout.EchoLayout;
+
+
+
+public class ExitWoes {
+
+ public static void main(String[] args) throws Exception {
+ LoggerContext lc = new LoggerContext();
+ WriterAppender writerAppender = new WriterAppender();
+ writerAppender.setContext(lc);
+ writerAppender.setLayout(new EchoLayout());
+
+ OutputStream os = new FileOutputStream("exitWoes1.log");
+ writerAppender.setWriter(new OutputStreamWriter(os));
+ writerAppender.setImmediateFlush(false);
+ writerAppender.start();
+
+ Logger logger = lc.getLogger(ExitWoes.class);
+
+ logger.debug("Hello world.");
+ }
+}
Added: logback/trunk/logback-examples/src/main/java/chapter4/IO.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter4/IO.java Thu Nov 2 20:36:44 2006
@@ -0,0 +1,176 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ *
+ * Copyright (C) 1999-2006, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package chapter4;
+
+import org.slf4j.Logger;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.core.FileAppender;
+import ch.qos.logback.core.layout.EchoLayout;
+
+
+
+public class IO extends Thread {
+ static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
+ static String msgShort = "Hello";
+ static boolean scarceCPU;
+ static int numThreads;
+ static long l;
+ static boolean longMessage;
+ long len;
+ boolean buffered;
+ boolean immediateFlush;
+ Logger logger;
+ LoggerContext context;
+ double throughput;
+
+ public IO(boolean _buffered, boolean _immediateFlush, long _len) {
+ this.len = _len;
+ this.buffered = _buffered;
+ this.immediateFlush = _immediateFlush;
+ context = new LoggerContext();
+ logger = context.getLogger("logger-" + getName());
+
+ // A FileAppender is created according to the buffering and
+ // immediate flush setting of this IO instance.
+ FileAppender fa = new FileAppender();
+
+ if (longMessage) {
+ PatternLayout pa = new PatternLayout();
+ pa.setPattern("%r %5p %c [%t] - %m%n");
+ fa.setLayout(pa);
+ } else {
+ fa.setLayout(new EchoLayout());
+ }
+
+ fa.setFile(getName() + ".log");
+ fa.setAppend(false);
+ fa.setImmediateFlush(immediateFlush);
+ fa.setBufferedIO(buffered);
+ fa.setContext(context);
+ fa.start();
+
+ }
+
+ public static void main(String[] argv) throws Exception {
+ if (argv.length != 4) {
+ usage("Wrong number of arguments.");
+ }
+
+ l = Integer.parseInt(argv[0]);
+ numThreads = Integer.parseInt(argv[1]);
+ scarceCPU = "true".equalsIgnoreCase(argv[2]);
+ longMessage = "long".equalsIgnoreCase(argv[3]);
+
+ // ----------------------------------------------------
+ // first test with unbuffered IO and immediate flushing
+ perfCase(false, true, l);
+
+ // ----------------------------------------------------
+ // Second test with unbuffered IO and no immediate flushing
+ perfCase(false, false, l);
+
+ // ----------------------------------------------------
+ // Third test with buffered IO and no immediate flushing
+ perfCase(true, false, l);
+
+ // There is no fourth test as buffered IO and immediate flushing
+ // do not make sense.
+ }
+
+ static void usage(String msg) {
+ System.err.println(msg);
+ System.err.println("Usage: java " + IO.class.getName() +
+ " runLength numThreads scarceCPU (short|long)\n" +
+ " runLength (integer) the number of logs to generate perthread\n" +
+ " numThreads (integer) the number of threads.\n" +
+ " scarceCPU (boolean) if true an additional CPU intensive thread is created\n" +
+ " (short|long) length of log messages.");
+ System.exit(1);
+ }
+
+ static void perfCase(boolean buffered, boolean immediateFlush, long len)
+ throws Exception {
+ IO[] threads = new IO[numThreads];
+ Counter counterThread = null;
+
+ if (scarceCPU) {
+ counterThread = new Counter();
+ counterThread.start();
+ }
+
+ // First create the threads
+ for (int i = 0; i < numThreads; i++) {
+ threads[i] = new IO(buffered, immediateFlush, len);
+ }
+
+ // then start them
+ for (int i = 0; i < numThreads; i++) {
+ threads[i].start();
+ }
+
+ // wait for them to stop, compute the average throughputs
+ double sum = 0;
+
+ for (int i = 0; i < numThreads; i++) {
+ threads[i].join();
+ sum += threads[i].throughput;
+ }
+
+ if (scarceCPU) {
+ // setting the interrupted field will cause counterThread to stop
+ counterThread.interrupted = true;
+ counterThread.join();
+ }
+
+ System.out.println("On average throughput of " + (sum / numThreads) +
+ " logs per millisecond.");
+ System.out.println("------------------------------------------------");
+ }
+
+ public void run() {
+ String msg = msgShort;
+
+ if (longMessage) {
+ msg = msgLong;
+ }
+
+ long before = System.currentTimeMillis();
+
+ for (int i = 0; i < len; i++) {
+ logger.debug(msg);
+ }
+
+ throughput = (len * 1.0) / (System.currentTimeMillis() - before);
+ System.out.println(getName() + ", buffered: " + buffered +
+ ", immediateFlush: " + immediateFlush + ", throughput: " + throughput +
+ " logs per millisecond.");
+ }
+}
+
+
+class Counter extends Thread {
+ public boolean interrupted = false;
+ public double counter = 0;
+
+ public void run() {
+ long before = System.currentTimeMillis();
+
+ while (!interrupted) {
+ counter += 0.001;
+ }
+
+ double tput = (counter * 1.0) / (System.currentTimeMillis() - before);
+ System.out.println("Counter thread " + getName() +
+ " incremented counter by " + tput + " per millisecond.");
+ }
+}
Added: logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml Thu Nov 2 20:36:44 2006
@@ -0,0 +1,471 @@
+<document>
+ <!--
+
+ Warning: do not use any auto-format function on this file.
+ Since "source" divs use pre as white-space, it affects the
+ look of the code parts in this document.
+
+ -->
+
+
+ <body>
+ <h2>Chapter 4: Appenders</h2>
+ <div class="author">
+ Authors: Ceki Gülcü, Sébastien Pennec
+ </div>
+
+
+ <table>
+ <tr>
+ <td valign="top" align="top">
+ <a rel="license"
+ href="http://creativecommons.org/licenses/by-nc-sa/2.5/">
+ <img alt="Creative Commons License"
+ style="border-width: 0"
+ src="http://creativecommons.org/images/public/somerights20.png" />
+ </a>
+ </td>
+ <td>
+ <p>Copyright © 2000-2006, QOS.ch</p>
+
+ <p>
+ <!--Creative Commons License-->
+ This work is licensed under a
+ <a rel="license"
+ href="http://creativecommons.org/licenses/by-nc-sa/2.5/">
+ Creative Commons
+ Attribution-NonCommercial-ShareAlike 2.5
+ License
+ </a>
+ .
+ <!--/Creative Commons License-->
+ </p>
+ </td>
+ </tr>
+ </table>
+
+ <h2>What is an Appender</h2>
+
+ <p>
+ Logback delegates the task of writing a logging event to appenders.
+ Appenders must imple-ment the <code>ch.qos.logback.core.Appender</code> interface.
+ The salient methods of this interface are summarized below:
+ </p>
+ <div class="source"><pre>package ch.qos.logback.core;
+
+import ch.qos.logback.core.spi.ContextAware;
+import ch.qos.logback.core.spi.FilterAttachable;
+import ch.qos.logback.core.spi.LifeCycle;
+
+
+public interface Appender extends LifeCycle, ContextAware, FilterAttachable {
+
+ public String getName();
+ <b>void doAppend(Object event);</b>
+ public void setLayout(Layout layout);
+ public Layout getLayout();
+ public void setName(String name);
+
+}</pre></div>
+
+ <p>
+ Most of the methods in the Appender interface are made of setter
+ and getter methods. A notable exception is the <code>doAppend()</code>
+ method taking an Object instance as its only parameter.
+ This method is perhaps the most important in the logback framework.
+ It is responsible for outputting the logging events in a suitable format
+ to the appropriate output device. Appenders are named entities.
+ This ensures that they can be referenced by name, a quality confirmed
+ to be especially significant in configuration scripts.
+ An appender can contain multiple filters, thus the <code>Appender</code>
+ interface extending the <code>FilterAttachable</code> interface.
+ Filters are discussed in detail in a subsequent chapter.
+ </p>
+
+ <p>
+ Appenders are ultimately responsible for outputting logging events.
+ However, they may delegate the actual formatting of the event to a
+ <code>Layout</code> object.
+ Each layout is associated with one and only one appender, referred to
+ as the containing appender. Some appenders have a built-in or fixed
+ event format, such that they do not require a layout. For example, the
+ <code>SocketAppender</code> simply serialize logging events before
+ transmitting them over the wire.
+ </p>
+
+ <h2>AppenderBase</h2>
+
+ <p>
+ The <code>ch.qos.logback.core.AppenderSkeleton</code> class is an abstract
+ class implementing the <code>Appender</code> interface.
+ It provides basic functionality shared by all appenders,
+ such as methods for getting or setting their name, their started status,
+ their layout and their filters.
+ It is the super-class of all appenders shipped with logback.
+ Although an abstract class, AppenderBase actually implements the
+ <code>doAppend()</code> method in the <code>Append</code> interface.
+ Perhaps the clearest way to discuss AppenderBase class is by
+ presenting a bit of its actual source code.
+ <code>AppenderBase</code>'s complete source code is also
+ <a href="../xref/ch/qos/logback/core/AppenderBase.html">
+ available for viewing</a>.
+ </p>
+
+<div class="source"><pre>public synchronized void doAppend(Object eventObject) {
+
+ // prevent re-entry.
+ if (guard) {
+ return;
+ }
+
+ try {
+ guard = true;
+
+ if (!this.started) {
+ if (statusRepeatCount++ < ALLOWED_REPEATS) {
+ addStatus(new WarnStatus(
+ "Attempted to append to non started appender [" + name + "].",this));
+ }
+ return;
+ }
+
+ if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
+ return;
+ }
+
+ // ok, we now invoke derived class' implementation of append
+ this.append(eventObject);
+
+ } finally {
+ guard = false;
+ }
+}</pre></div>
+
+ <p>
+ This implementation of the <code>doAppend()</code> method is synchronized.
+ It follows that logging to the same appender from different
+ threads is safe. While a thread, say <em>T</em>, is executing the <code>doAppend()</code>
+ method, subsequent calls by other threads are queued until <em>T</em>
+ leaves the <code>doAppend()</code> method, ensuring
+ <em>T</em>'s exclusive access to the appender.
+ </p>
+
+ <p>
+ EXPLAIN GUARD
+ </p>
+
+ <p>
+ The first statement of the <code>doAppend()</code> method, once the <code>try</code> block
+ is reached is to check whether the <code>started</code> field is true.
+ If it is not, <code>doAppend()</code> will send a warning message and return.
+ In other words, once stopped, it is impossible to write to a closed appender.
+ <code>Appender</code> object implement the <code>LifeCycle</code> interface,
+ which implies that they implement <code>start()</code>, <code>stop()</code>
+ and <code>isStarted()</code> methods. After setting all the options of an appender,
+ Joran, logback's configuration framework, calls this method to signal the appender
+ to bind or activate its options.
+ Indeed, depending on the appender, certain options cannot be activated because
+ of interferences with other options, or appenders can even not start at all if
+ some options are missing.
+ For example, since file creation depends on truncation mode,
+ <code>FileAppender</code> cannot act on the value of its <code>File</code> option
+ until the value of the Append option is also known for certain.
+ Sub-classes of <code>AppenderBase</code> are required to set the boolean variable
+ <code>started</code> to false when their <code>stop()</code> method is invoked.
+ </p>
+
+ <p>
+ If a warning message is sent due to incorrect calls to the <code>doAppend()</code>
+ method, logback's powerful <code>Status</code> error reporting system is used. In case
+ several incorrect calls on <code>doAppend()</code> are issued, <code>AppenderBase</code>
+ does not send an unlimited number of warnings. Once a certain limit is reached, the
+ <code>AppenderBase</code> instance stops its warnings.
+ </p>
+
+ <p>
+ The next <code>if</code> statement checks the result
+ of the attached <code>Filter</code> objects.
+ Depending on the decision made by the filters
+ in the filter chain, events can be denied or alternatively accepted.
+ In the absence of a decision by the filter chain, events are accepted by default.
+ </p>
+
+ <p>
+ Lastly, the <code>doAppend()</code> method invoke the derived classes' implementation
+ of the <code>append()</code> method, which does the actual work of appending the
+ event to the appropriate device.
+ </p>
+
+ <p>DO WE ADD A UML DIAGRAM?? YES!!</p>
+
+ <p>In appenders, the term option or property is reserved for named attributes
+ that are dynamically inferred using JavaBeans introspection. </p>
+
+ <h2>Logback Core</h2>
+
+ <h3>WriterAppender</h3>
+
+ <p>
+ <code>WriterAppender</code> appends events to a <code>java.io.Writer</code>.
+ This class provides basic services that other appenders build upon.
+ Users do not usually instantiate <code>WriterAppender</code> objects directly.
+ Since <code>java.io.Writer</code> type cannot be mapped to a string, there is no
+ way to specify the target <code>Writer</code> object in a configuration script.
+ Simply put, you cannot configure a <code>WriterAppender</code> from a script.
+ However, this does not mean that <code>WriterAppender</code> lacks configurable options.
+ These options are described next.
+ </p>
+
+ <table>
+ <tr>
+ <th>Option Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><b><span class="option">Encoding</span></b></td>
+ <td><code>String</code></td>
+ <td>
+ The encoding specifies the method of conversion between 16-bit Unicode
+ characters into raw 8-bit bytes. This appender will use the local platform's
+ default encoding unless you specify otherwise using the
+ <span class="option">Encoding</span> option.
+ According to the <code>java.lang</code> package documentation, acceptable values
+ are dependent on the VM implementation although all implementations are
+ required to support at least the following encodings:
+ <em>US-ASCII</em>, <em>ISO-8859-1</em>, <em>UTF-8</em>, <em>UTF-16BE</em>,
+ <em>UTF-16LE</em> and <em>UTF-16</em>.
+ By default, the <span class="option">Encoding</span> option is null such
+ that the platform's default encoding is used.
+ </td>
+ </tr>
+ <tr>
+ <td><b><span class="option">ImmediateFlush</span></b></td>
+ <td><code>boolean</code></td>
+ <td>
+ If set to true, each write of a logging event is followed by a flush operation
+ on the underlying <code>Writer</code> object. Conversely, if the option is set to false,
+ each write will not be followed by a flush.
+ In general, skipping the flush operation improves logging throughput by roughly 15%.
+ The downside is that if the application exits abruptly, the unwritten characters
+ buffered inside the <code>Writer</code> might be lost.
+ This can be particularly troublesome as those unwritten characters may contain
+ crucial information needed in identifying the reasons behind a crash.
+ By default, the <span class="option">ImmediateFlush</span> option is set to true.
+ </td>
+ </tr>
+ </table>
+
+ <p>
+ In general, if you disable immediate flushing, then make sure to flush
+ any output streams when your application exits. Otherwise, log messages
+ will be lost as illustrated by the next example.
+ </p>
+
+ <em>Example 4.1: Exiting an application without flushing (logback-examples/src/main/java/chapter4/
+ <a href="../xref/chapter4/ExitWoes.html">ExitWoes.java</a>)</em>
+<div class="source"><pre>package chapter4;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.core.WriterAppender;
+import ch.qos.logback.core.layout.DummyLayout;
+
+public class ExitWoes {
+
+ public static void main(String[] args) throws Exception {
+ LoggerContext lc = new LoggerContext();
+ WriterAppender writerAppender = new WriterAppender();
+ writerAppender.setContext(lc);
+ writerAppender.setLayout(new DummyLayout());
+
+ OutputStream os = new FileOutputStream("exitWoes1.log");
+ writerAppender.setWriter(new OutputStreamWriter(os));
+ writerAppender.setImmediateFlush(false);
+ writerAppender.start();
+
+ Logger logger = LoggerFactory.getLogger(ExitWoes1.class);
+
+ logger.debug("Hello world.");
+ }
+}</pre></div>
+
+ <p>
+ This example creates a <code>WriterAppender</code> that uses an
+ <code>OutputStreamWriter</code>
+ wrapping a <code>FileOutputStream</code> as its underlying <code>Writer</code> object,
+ with immediate flushing disabled. It then proceeds to log a single debug message.
+ According to <code>OutputStreamWriter</code> javadocs, each invocation of a
+ <code>write()</code>
+ method causes the encoding converter to be invoked on the given character(s).
+ The resulting bytes are accumulated in a buffer before being written
+ to the underlying output stream. As astonishing as this may seem,
+ running <code>ExitWoes1</code> will not produce any output in the file
+ <em>exitWoes1.log</em>
+ because the Java VM does not flush output streams when it exits.
+ Calling the <code>shutdown()</code> method of a <b>XXXXXX</b> ensures that all
+ appenders in the hierarchy are closed and their buffers are flushed.
+ For most applications this is as simple as including the following statement
+ before exiting the application.
+ </p>
+ <p>WHAT TO DO IN LB ???</p>
+
+ <p>
+ The <code>WriterAppender</code> is the super class of four other appenders,
+ namely <code>ConsoleAppender</code>, <code>FileAppender</code> which in turn is
+ the super class of <code>RollingFileAppender</code>.
+ </p>
+ <p><b>include UML??</b>
+ Figure 4 2 illustrates the class diagram for WriterAppender and its subclasses
+ </p>
+
+ <h3>ConsoleAppender</h3>
+
+ <p>
+ The <code>ConsoleAppender</code>, as the name indicates, appends on the console,
+ or more precisely on <em>System.out</em> or <em>System.err</em>, the former
+ being the default target. <code>ConsoleAppender</code> formats events with
+ a layout specified by the user. Both <em>System.out</em> and <em>System.err</em>
+ are <code>java.io.PrintStream</code> objects.
+ Consequently, they are wrapped inside an <code>OutputStreamWriter</code>
+ which buffers I/O operations but not character conversions.
+ </p>
+
+ <table>
+ <tr>
+ <th>Option Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><b><span class="option">Encoding</span></b></td>
+ <td><code>String</code></td>
+ <td>See <code>WriterAppender</code> options.</td>
+ </tr>
+ <tr>
+ <td><b><span class="option">ImmediateFlush</span></b></td>
+ <td><code>boolean</code></td>
+ <td>See <code>WriterAppender</code> options.</td>
+ </tr>
+ <tr>
+ <td><b><span class="option">Target</span></b></td>
+ <td><code>String</code></td>
+ <td>
+ One of the String values <em>System.out</em> or
+ <em>System.err</em>. The default target is <em>System.out</em>.
+ </td>
+ </tr>
+ </table>
+
+ <h3>FileAppendery</h3>
+
+ <p>
+ The <code>FileAppender</code>, a subclass of <code>WriterAppender</code>,
+ appends log events into a file. The file to write to is specified by
+ the <span class="option">File</span> option.
+ If the file already exists, it is either appended to, or truncated
+ depending on the value of the <span class="option">Append</span> option.
+ It uses a <code>FileOutputStream</code> which is wrapped by an <code>OutputStreamWriter</code>.
+ Note that <code>OutputStreamWriter</code> buffers I/O operations
+ but not character conversions. To optimize character conversions one
+ can set the <span class="option">BufferedIO</span> option to true
+ which effectively wraps the <code>OutputStreamWriter</code> with
+ a <code>BufferedWriter</code>. Options for <code>FileAppender</code> are summarized below.
+ </p>
+
+ <table>
+ <tr>
+ <th>Option Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><b><span class="option">Append</span></b></td>
+ <td><code>boolean</code></td>
+ <td>If true, events are appended at the end of an existing file.
+ Otherwise, if <span class="option">Append</span> is false, any existing
+ file is truncated. The <span class="option">Append</span> option is set to true by default.</td>
+ </tr>
+ <tr>
+ <td><b><span class="option">Encoding</span></b></td>
+ <td><code>String</code></td>
+ <td>See <code>WriterAppender</code> options.</td>
+ </tr>
+ <tr>
+ <td><b><span class="option">BufferedIO</span></b></td>
+ <td><code>boolean</code></td>
+ <td>
+ The <span class="option">BufferedIO</span> option is set to false by default.
+ If set to true, the underlying <code>OutputStreamWriter</code> is wrapped
+ by a <code>BufferedWriter</code> object.
+ Setting <span class="option">BufferedIO</span> to true automatically
+ sets the <span class="option">ImmediateFlush</span> option to false.
+ The name <span class="option">BufferedIO</span> is slightly misleading because
+ buffered IO is already supported by <code>OutputStreamWriter</code>.
+ Setting <span class="option">BufferedIO</span> to true has the effect of
+ buffering I/O as well as character to raw byte conversions, saving a few
+ CPU cycles in the process.
+ </td>
+ </tr>
+ <tr>
+ <td><b><span class="option">BufferSize</span></b></td>
+ <td><code>int</code></td>
+ <td>Size of <code>BufferedWriter</code> buffer. The default value is 8192.</td>
+ </tr>
+ <tr>
+ <td><b><span class="option">File</span></b></td>
+ <td><code>int</code></td>
+ <td>
+ The name of the file to write to. If the file does not exist, it is created. <br />
+ On the MS Windows platform users frequently forget to escape back slashes.
+ For example, the value <em>c:\temp\test.log</em> is not likely to be interpreted
+ properly as <em>'\t'</em> is an escape sequence interpreted as a single
+ tab character <em>(\u0009)</em>.
+ Correct values can be specified as <em>c:/temp/test.log</em> or
+ alternatively as <em>c:\\temp\\test.log</em>.
+ The <span class="option">File</span> option has no default value.
+ </td>
+ </tr>
+ </table>
+
+ <p>
+ By default, <code>FileAppender</code> performs a flush operation for
+ each event, ensuring that events are immediately written to disk.
+ Setting the <span class="option">ImmediateFlush</span> option to false can drastically reduce
+ I/O activity by letting <code>OutputStreamWriter</code> buffer bytes
+ before writing them on disk. For short messages, we have observed 2 or 3
+ fold increases in logging throughput, i.e. the number of logs output
+ per unit of time. For longer messages, the throughput gains are somewhat
+ less dramatic, and range between 1.4 and 2 fold. Enabling the
+ <span class="option">BufferedIO</span>
+ option, that is buffering character to byte conversions, increases
+ performance by an additional 10% to 40% compared to only disk
+ I/O buffering (<span class="option">ImmediateFlush</span>=false).
+ Performance varies somewhat depending on the host machine as well as JDK version.
+ Throughput measurements are based on the <code>chapter4.IO</code> application.
+ Please refer to the file <em>logback-examples/src/main/java/chapter4/IO.java</em>
+ for actual source code.
+ <a href="../xref/chapter4/IO.html">Online viewing</a>
+ of this file is also available.
+ </p>
+
+ <h2>Logback Classic</h2>
+
+ <h2>Logback Access</h2>
+
+
+
+
+
+
+
+
+
+ </body>
+</document>
Modified: logback/trunk/logback-skin/src/main/resources/css/site.css
==============================================================================
--- logback/trunk/logback-skin/src/main/resources/css/site.css (original)
+++ logback/trunk/logback-skin/src/main/resources/css/site.css Thu Nov 2 20:36:44 2006
@@ -360,4 +360,9 @@
.greenBold {
color: green;
font-weight: bold;
+}
+
+.option {
+ border: 1px solid black;
+ font-family: Arial, sans-serif;
}
\ No newline at end of file
1
0

svn commit: r857 - logback/trunk/logback-site/src/site/xdocTemplates
by noreply.ceki@qos.ch 02 Nov '06
by noreply.ceki@qos.ch 02 Nov '06
02 Nov '06
Author: ceki
Date: Thu Nov 2 20:27:55 2006
New Revision: 857
Removed:
logback/trunk/logback-site/src/site/xdocTemplates/accessLogJetty.xml
Modified:
logback/trunk/logback-site/src/site/xdocTemplates/shortIntro.xml
Log:
ongoing work on short intro
Modified: logback/trunk/logback-site/src/site/xdocTemplates/shortIntro.xml
==============================================================================
--- logback/trunk/logback-site/src/site/xdocTemplates/shortIntro.xml (original)
+++ logback/trunk/logback-site/src/site/xdocTemplates/shortIntro.xml Thu Nov 2 20:27:55 2006
@@ -51,15 +51,18 @@
Logback is intended as a successor to the popular log4j project.
It was designed by Ceki Gülcü, the founder of the
log4j project. It builds upon a decade long experience gained in
- designing industrial-strength logging systems. The resulting product,
- logback is faster with a smaller footprint than all
+ designing industrial-strength logging systems. The resulting
+ product, logback is faster with a smaller footprint than all
existing logging systems, sometimes by a wide margin. Logback
also offers unique and rather useful features such as Markers,
parameterized logging statements, conditional stack tracing and
- powerful event filtering, to cite a few. For its own error
- reporting, logback relies on
- <code>Status</code>
- objects which you may wish to use in contexts other than logging.
+ powerful event filtering. These are only few examples of useful
+ features logback has to offer. For its own error reporting,
+ logback relies on <code>Status</code> objects, which greatly
+ facilitate troubleshooting. You may wish to rely on Status
+ objects in contexts other than logging. Logback-core bundles
+ Joran, a powerful and generic configutation system, which can be
+ put to use in your own projects for great effect.
</p>
<p>
@@ -76,29 +79,52 @@
</p>
<p>
- The Core module lays the groundwork for the other two modules.
- The Classic module extends Core. Classic can be assimilated to
- an improved version of log4j. Logback Classic natively
- implements the
- <a href="http://www.slf4j.org">SLF4J API</a>
- so that you can readily switch back and forth between logback
- and other logging systems such as log4j or JDK14 Logging. The
- Access module integrates with Servlet containers to provide
- HTTP-access log functionality. The Access module will be covered
- in a separate document.
+ The <em>core</em> module lays the groundwork for the other two
+ modules. The <em>classic</em> module extends <em>core</em>. The
+ classic module can be assimilated to a significantly improved
+ version of log4j. Logback-classic natively implements the <a
+ href="http://www.slf4j.org">SLF4J API</a> so that you can
+ readily switch back and forth between logback and other logging
+ systems such as log4j or JDK14 Logging. The third module called
+ <em>access</em> integrates with Servlet containers to provide
+ HTTP-access log functionality. The access module will be covered
+ in a <a href="access.html">separate document</a>.
</p>
<p>
- In this document, we will use the term logback to refer to the
+ In this document, we will write "logback" to refer to the
logback classic module.
</p>
<h2>First Baby Step</h2>
- <p>
- After you have added the jar files
- <em>logback-core.jar</em>, <em>logback-classic.jar</em> and their dependencies
- to your classpath, you can begin experimenting with logback.
+ <p>Logback-classic module requires the presence
+ <em>slf4j-api.jar</em>, <em>logback-core.jar</em> in addition to
+ <em>logback-classic.jar</em> on the classpath.
+ </p>
+
+ <p>in order to falitate running the the examples in this document,
+ we have placed the required jar files in the
+ <em>logback-examples/lib</em> directory. Assuming your current
+ directory is $LOGBACK_HOME/logback-examples, where $LOGBACK_HOME
+ is the directory you've installed logback, you can start launch
+ the first example application, chapter1.HelloWord1 with the
+ following command:
</p>
+ <div class="source"><pre>
+ java -cp lib/slf4j-api-1.1.0-beta0.jar;lib/logback-core-${version}.jar;lib/logback-classic-${version}.jar
+ </pre></div>
+
+
+<h1>FIXME</h1>
+
+ <p>Assuming the After you
+ have added the jar files <em>slf4j-api.jar</em>,
+ <em>logback-core.jar</em>, <em>logback-classic.jar</em> and their
+ dependencies to your classpath, you can begin experimenting with
+ logback. To
+ </p>
+
+ <p>java -cp lib/logback-core-${version}.jar</p>
<em>Example 1.1: Basic template for logging (logback-examples/src/main/java/chapter1/HelloWorld1.java)</em>
<div class="source"><pre>package chapter1;
1
0

svn commit: r856 - logback/trunk/logback-site/src/site/xdocTemplates
by noreply.ceki@qos.ch 02 Nov '06
by noreply.ceki@qos.ch 02 Nov '06
02 Nov '06
Author: ceki
Date: Thu Nov 2 20:27:33 2006
New Revision: 856
Added:
logback/trunk/logback-site/src/site/xdocTemplates/access.xml
- copied unchanged from r809, /logback/trunk/logback-site/src/site/xdocTemplates/accessLogJetty.xml
Log:
renaming files
1
0

[Bug 27] New: Joran doesn't configure string lists correctly.
by bugzilla-daemon@pixie.qos.ch 02 Nov '06
by bugzilla-daemon@pixie.qos.ch 02 Nov '06
02 Nov '06
http://bugzilla.qos.ch/show_bug.cgi?id=27
Summary: Joran doesn't configure string lists correctly.
Product: logback-core
Version: unspecified
Platform: All
OS/Version: All
Status: NEW
Severity: major
Priority: P1
Component: Joran
AssignedTo: logback-dev(a)qos.ch
ReportedBy: noreply.sebastien(a)qos.ch
Using the following configuration file:
<configuration>
<turboFilter class="ch.qos.logback.classic.turbo.DebugUsersTurboFilter">
<user>seb</user>
<user>ceki</user>
</turboFilter>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d %level - %m%n</Pattern>
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>
(named turbo2.xml, in classic/test/input/joran)
Joran sees the two <user> elements, knows that their "containmentType" is
COLLECTION but doesn't call the addUser method.
Instead, it checks to see if a class attribute exists in the <user> elements,
and since no such attribute is given, it reports an error such as:
|-ERROR in ch.qos.logback.core.joran.action.NestedComponentIA - No class name
attribute in <user>
I guess that Joran has to learn that collection containmentType doesn't
necessarily mean "component that requires a class attribute". Here, the value
between the <user> elements is a String. I guess that inspecting the addUser
method and discovering that the parameter type is a String would help.
--
Configure bugmail: http://bugzilla.qos.ch/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
1
2

svn commit: r855 - in logback/trunk/logback-core/src: main/java/ch/qos/logback/core/joran/action main/java/ch/qos/logback/core/util test/input/joran test/java/ch/qos/logback/core/joran test/java/ch/qos/logback/core/joran/ia
by noreply.ceki@qos.ch 02 Nov '06
by noreply.ceki@qos.ch 02 Nov '06
02 Nov '06
Author: ceki
Date: Thu Nov 2 20:06:37 2006
New Revision: 855
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java
logback/trunk/logback-core/src/test/input/joran/simplePropertyIA1.xml
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/Fruit.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContextAction.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/SimplePropertyIATest.java
Log:
Fixed bug #27.
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java Thu Nov 2 20:06:37 2006
@@ -57,8 +57,6 @@
ContainmentType containmentType = parentBean.canContainComponent(nestedElementTagName);
- System.out.println("==="+containmentType);
-
switch (containmentType) {
case NOT_FOUND:
case AS_SINGLE_COMPONENT:
@@ -70,7 +68,7 @@
ImplicitActionData ad = new ImplicitActionData(parentBean, containmentType);
ad.propertyName = nestedElementTagName;
actionDataStack.push(ad);
- //System.out.println("in NestedSimplePropertyIA deemed applicable <" + pattern + ">");
+ addInfo("NestedSimplePropertyIA deemed applicable <" + pattern + ">");
return true;
default:
addError("PropertySetter.canContainComponent returned " + containmentType);
@@ -89,9 +87,8 @@
//System.out.println("body "+body+", finalBody="+finalBody);
// get the action data object pushed in isApplicable() method call
ImplicitActionData actionData = (ImplicitActionData) actionDataStack.peek();
-
switch (actionData.containmentType) {
- case AS_SINGLE_COMPONENT:
+ case AS_SINGLE_PROPERTY:
actionData.parentBean.setProperty(actionData.propertyName, finalBody);
break;
case AS_PROPERTY_COLLECTION:
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java Thu Nov 2 20:06:37 2006
@@ -113,8 +113,7 @@
name = Introspector.decapitalize(name);
PropertyDescriptor prop = getPropertyDescriptor(name);
-
- // LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType());
+
if (prop == null) {
addWarn("No such property [" + name + "] in " + objClass.getName() + ".");
} else {
@@ -287,8 +286,8 @@
}
name = capitalizeFirstLetter(name);
-
Method adderMethod = getMethod("add" + name);
+
if (adderMethod == null) {
addError("No adder for property [" + name + "].");
return;
@@ -308,12 +307,12 @@
return;
}
+
if (arg == null) {
addError("Conversion to type [" + paramTypes[0] + "] failed.");
} else {
-
try {
- adderMethod.invoke(obj, new Object[] { arg });
+ adderMethod.invoke(obj, arg);
} catch (Exception ex) {
addError("Failed to invoke adder for " + name, ex);
}
Modified: logback/trunk/logback-core/src/test/input/joran/simplePropertyIA1.xml
==============================================================================
--- logback/trunk/logback-core/src/test/input/joran/simplePropertyIA1.xml (original)
+++ logback/trunk/logback-core/src/test/input/joran/simplePropertyIA1.xml Thu Nov 2 20:06:37 2006
@@ -4,5 +4,6 @@
<fruit class="ch.qos.logback.core.joran.ia.Fruit">
<name>blue</name>
<text>hello</text>
+ <text>world</text>
</fruit>
</context>
\ No newline at end of file
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java Thu Nov 2 20:06:37 2006
@@ -34,7 +34,7 @@
interpreter.addImplicitAction(nestedIA);
NestedSimplePropertyIA nestedSimpleIA = new NestedSimplePropertyIA();
- nestedIA.setContext(context);
+ nestedSimpleIA.setContext(context);
interpreter.addImplicitAction(nestedSimpleIA);
}
@@ -42,7 +42,6 @@
protected void addInstanceRules(RuleStore rs) {
for(Pattern pattern : rulesMap.keySet()) {
Action action = rulesMap.get(pattern);
- System.out.println("Adding "+pattern +" "+action);
rs.addRule(pattern, action);
}
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/Fruit.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/Fruit.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/Fruit.java Thu Nov 2 20:06:37 2006
@@ -9,11 +9,10 @@
List<String> textList = new ArrayList<String>();
public Fruit() {
- System.out.println("Fruit constructor called");
}
- public void setName(String name) {
- this.name = name;
+ public void setName(String n) {
+ this.name = n;
}
public String getName() {
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContextAction.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContextAction.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContextAction.java Thu Nov 2 20:06:37 2006
@@ -25,7 +25,6 @@
public void begin(InterpretationContext ec, String name, Attributes attributes)
throws ActionException {
-
inError = false;
try {
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/SimplePropertyIATest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/SimplePropertyIATest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/SimplePropertyIATest.java Thu Nov 2 20:06:37 2006
@@ -44,7 +44,9 @@
Fruit f0 = fList.get(0);
assertEquals("blue", f0.getName());
- assertEquals(1, f0.textList.size());
+ assertEquals(2, f0.textList.size());
+ assertEquals("hello", f0.textList.get(0));
+ assertEquals("world", f0.textList.get(1));
} catch (Exception je) {
StatusPrinter.print(fruitContext);
throw je;
1
0

svn commit: r854 - logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi
by noreply.seb@qos.ch 02 Nov '06
by noreply.seb@qos.ch 02 Nov '06
02 Nov '06
Author: seb
Date: Thu Nov 2 19:19:46 2006
New Revision: 854
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java
Log:
import optimization
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java Thu Nov 2 19:19:46 2006
@@ -1,6 +1,5 @@
package ch.qos.logback.core.spi;
-import ch.qos.logback.core.filter.Filter;
/**
*
1
0
Author: seb
Date: Thu Nov 2 19:19:33 2006
New Revision: 853
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java
- copied, changed from r852, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/FilterReply.java
Removed:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/FilterReply.java
Modified:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachable.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachableImpl.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DebugUsersTurboFilter.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/TurboFilter.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/NOPTurboFilter.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/AbstractEvalutatorFilter.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/EvaluatorFilter.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/Filter.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComponentIA.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachable.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java
Log:
moved FilterReply to ch.qos.logback.core.spi.
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java Thu Nov 2 19:19:33 2006
@@ -19,11 +19,11 @@
import ch.qos.logback.core.Context;
import ch.qos.logback.core.CoreGlobal;
import ch.qos.logback.core.filter.Filter;
-import ch.qos.logback.core.filter.FilterReply;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.spi.AppenderAttachable;
import ch.qos.logback.core.spi.AppenderAttachableImpl;
import ch.qos.logback.core.spi.FilterAttachableImpl;
+import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.ErrorStatus;
import ch.qos.logback.core.status.StatusManager;
import ch.qos.logback.core.util.StatusPrinter;
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java Thu Nov 2 19:19:33 2006
@@ -21,9 +21,9 @@
import ch.qos.logback.classic.spi.LoggerRemoteView;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.filter.FilterReply;
import ch.qos.logback.core.spi.AppenderAttachable;
import ch.qos.logback.core.spi.AppenderAttachableImpl;
+import ch.qos.logback.core.spi.FilterReply;
public final class Logger implements org.slf4j.Logger, AppenderAttachable,
Serializable {
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java Thu Nov 2 19:19:33 2006
@@ -22,7 +22,7 @@
import ch.qos.logback.classic.turbo.TurboFilter;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.CoreGlobal;
-import ch.qos.logback.core.filter.FilterReply;
+import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.ErrorStatus;
/**
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachable.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachable.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachable.java Thu Nov 2 19:19:33 2006
@@ -5,7 +5,7 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.turbo.TurboFilter;
-import ch.qos.logback.core.filter.FilterReply;
+import ch.qos.logback.core.spi.FilterReply;
/**
* Interface for attaching ClassicFilter instances to objects.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachableImpl.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachableImpl.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterAttachableImpl.java Thu Nov 2 19:19:33 2006
@@ -14,7 +14,7 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.turbo.TurboFilter;
-import ch.qos.logback.core.filter.FilterReply;
+import ch.qos.logback.core.spi.FilterReply;
/**
* Implementation of ClassicFilterAttachable.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DebugUsersTurboFilter.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DebugUsersTurboFilter.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DebugUsersTurboFilter.java Thu Nov 2 19:19:33 2006
@@ -9,7 +9,7 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.MDC;
-import ch.qos.logback.core.filter.FilterReply;
+import ch.qos.logback.core.spi.FilterReply;
/**
* This class allows output of debug level events to a certain list of users.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/TurboFilter.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/TurboFilter.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/TurboFilter.java Thu Nov 2 19:19:33 2006
@@ -5,8 +5,8 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.core.filter.Filter;
-import ch.qos.logback.core.filter.FilterReply;
import ch.qos.logback.core.spi.ContextAwareBase;
+import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.spi.LifeCycle;
/**
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/NOPTurboFilter.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/NOPTurboFilter.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/NOPTurboFilter.java Thu Nov 2 19:19:33 2006
@@ -4,7 +4,7 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
-import ch.qos.logback.core.filter.FilterReply;
+import ch.qos.logback.core.spi.FilterReply;
public class NOPTurboFilter extends TurboFilter {
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java Thu Nov 2 19:19:33 2006
@@ -10,10 +10,10 @@
package ch.qos.logback.core;
import ch.qos.logback.core.filter.Filter;
-import ch.qos.logback.core.filter.FilterReply;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.spi.FilterAttachableImpl;
+import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.WarnStatus;
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/AbstractEvalutatorFilter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/AbstractEvalutatorFilter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/AbstractEvalutatorFilter.java Thu Nov 2 19:19:33 2006
@@ -1,5 +1,7 @@
package ch.qos.logback.core.filter;
+import ch.qos.logback.core.spi.FilterReply;
+
/**
* <p>
* This abstract class is meant to be a base for specific evaluator filters.
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/EvaluatorFilter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/EvaluatorFilter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/EvaluatorFilter.java Thu Nov 2 19:19:33 2006
@@ -2,6 +2,7 @@
import ch.qos.logback.core.boolex.EvaluationException;
import ch.qos.logback.core.boolex.EventEvaluator;
+import ch.qos.logback.core.spi.FilterReply;
public class EvaluatorFilter extends AbstractEvalutatorFilter {
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/Filter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/Filter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/Filter.java Thu Nov 2 19:19:33 2006
@@ -1,6 +1,7 @@
package ch.qos.logback.core.filter;
import ch.qos.logback.core.spi.ContextAwareBase;
+import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.spi.LifeCycle;
/**
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComponentIA.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComponentIA.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComponentIA.java Thu Nov 2 19:19:33 2006
@@ -10,6 +10,8 @@
package ch.qos.logback.core.joran.action;
+import java.util.Stack;
+
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.spi.InterpretationContext;
@@ -21,8 +23,6 @@
import ch.qos.logback.core.util.OptionHelper;
import ch.qos.logback.core.util.PropertySetter;
-import java.util.Stack;
-
/**
* This action is responsible for tying together a parent object with a child
* element for which there is no explicit rule.
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachable.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachable.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachable.java Thu Nov 2 19:19:33 2006
@@ -10,7 +10,6 @@
package ch.qos.logback.core.spi;
import ch.qos.logback.core.filter.Filter;
-import ch.qos.logback.core.filter.FilterReply;
/**
* Interface for attaching filters to objects.
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java Thu Nov 2 19:19:33 2006
@@ -10,7 +10,6 @@
package ch.qos.logback.core.spi;
import ch.qos.logback.core.filter.Filter;
-import ch.qos.logback.core.filter.FilterReply;
/**
* Implementation of FilterAttachable.
Copied: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java (from r852, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/FilterReply.java)
==============================================================================
--- /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/filter/FilterReply.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/FilterReply.java Thu Nov 2 19:19:33 2006
@@ -1,4 +1,6 @@
-package ch.qos.logback.core.filter;
+package ch.qos.logback.core.spi;
+
+import ch.qos.logback.core.filter.Filter;
/**
*
1
0
Author: ceki
Date: Thu Nov 2 19:11:54 2006
New Revision: 852
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/ContainmentType.java
logback/trunk/logback-core/src/test/input/joran/simplePropertyIA1.xml
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java
- copied, changed from r829, /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/SimpleConfigurator.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/Fruit.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContext.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContextAction.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/PackageTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/SimplePropertyIATest.java
Removed:
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/SimpleConfigurator.java
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ImplicitActionData.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComponentIA.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/util/PropertySetterTest.java
Log:
- added capability of setting collections of simple properties in PropertySetter and Joran
- small bug fix in Pattern class (a trailing / in the pattern string would cause the addition of an extra
component with an empty string)
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ImplicitActionData.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ImplicitActionData.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/ImplicitActionData.java Thu Nov 2 19:11:54 2006
@@ -1,15 +1,16 @@
package ch.qos.logback.core.joran.action;
+import ch.qos.logback.core.util.ContainmentType;
import ch.qos.logback.core.util.PropertySetter;
public class ImplicitActionData {
PropertySetter parentBean;
String propertyName;
Object nestedComponent;
- int containmentType;
+ ContainmentType containmentType;
boolean inError;
- ImplicitActionData(PropertySetter parentBean, int containmentType) {
+ ImplicitActionData(PropertySetter parentBean, ContainmentType containmentType) {
this.parentBean = parentBean;
this.containmentType = containmentType;
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComponentIA.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComponentIA.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComponentIA.java Thu Nov 2 19:11:54 2006
@@ -10,30 +10,27 @@
package ch.qos.logback.core.joran.action;
-
-
import org.xml.sax.Attributes;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.LifeCycle;
+import ch.qos.logback.core.util.ContainmentType;
import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.OptionHelper;
import ch.qos.logback.core.util.PropertySetter;
-
import java.util.Stack;
-
/**
- * This action is responsible for tying together a parent object with
- * a child element for which there is no explicit rule.
+ * This action is responsible for tying together a parent object with a child
+ * element for which there is no explicit rule.
*
* @author Ceki Gülcü
*/
public class NestedComponentIA extends ImplicitAction {
-
+
// actionDataStack contains ActionData instances
// We use a stack of ActionData objects in order to support nested
// elements which are handled by the same NestComponentIA instance.
@@ -43,32 +40,35 @@
// be followed by the corresponding pop.
Stack<ImplicitActionData> actionDataStack = new Stack<ImplicitActionData>();
- public boolean isApplicable(
- Pattern pattern, Attributes attributes, InterpretationContext ec) {
- //System.out.println("in NestComponentIA.isApplicable <" + pattern + ">");
+ public boolean isApplicable(Pattern pattern, Attributes attributes,
+ InterpretationContext ec) {
+ // System.out.println("in NestComponentIA.isApplicable <" + pattern + ">");
String nestedElementTagName = pattern.peekLast();
// calling ec.peekObject with an empty stack will throw an exception
- if(ec.isEmpty()) {
+ if (ec.isEmpty()) {
return false;
}
-
+
Object o = ec.peekObject();
PropertySetter parentBean = new PropertySetter(o);
parentBean.setContext(context);
-
- int containmentType = parentBean.canContainComponent(nestedElementTagName);
+
+ ContainmentType containmentType = parentBean
+ .canContainComponent(nestedElementTagName);
switch (containmentType) {
- case PropertySetter.NOT_FOUND:
- case PropertySetter.AS_PROPERTY:
+ case NOT_FOUND:
+ case AS_SINGLE_PROPERTY:
+ case AS_PROPERTY_COLLECTION:
return false;
- // we only push action data if NestComponentIA is applicable
- case PropertySetter.AS_COLLECTION:
- case PropertySetter.AS_COMPONENT:
- addInfo("is dmmed applicable for "+pattern);
- ImplicitActionData ad = new ImplicitActionData(parentBean, containmentType);
+ // we only push action data if NestComponentIA is applicable
+ case AS_COMPONENT_COLLECTION:
+ case AS_SINGLE_COMPONENT:
+ addInfo("was deemed applicable for " + pattern);
+ ImplicitActionData ad = new ImplicitActionData(parentBean,
+ containmentType);
actionDataStack.push(ad);
return true;
@@ -78,9 +78,9 @@
}
}
- public void begin(
- InterpretationContext ec, String localName, Attributes attributes) {
- //LogLog.debug("in NestComponentIA begin method");
+ public void begin(InterpretationContext ec, String localName,
+ Attributes attributes) {
+ // LogLog.debug("in NestComponentIA begin method");
// get the action data object pushed in isApplicable() method call
ImplicitActionData actionData = (ImplicitActionData) actionDataStack.peek();
@@ -98,29 +98,31 @@
}
try {
- //getLogger().debug(
- // "About to instantiate component <{}> of type [{}]", localName,
- // className);
+ // getLogger().debug(
+ // "About to instantiate component <{}> of type [{}]", localName,
+ // className);
- // FIXME: Loading classes should be governed by config file rules.
+ // FIXME: Loading classes should be governed by config file rules.
actionData.nestedComponent = Loader.loadClass(className).newInstance();
-
+
// pass along the repository
- if(actionData.nestedComponent instanceof ContextAware) {
+ if (actionData.nestedComponent instanceof ContextAware) {
((ContextAware) actionData.nestedComponent).setContext(this.context);
}
- //getLogger().debug(
- addInfo("Pushing component <"+localName+"> on top of the object stack.");
+ // getLogger().debug(
+ addInfo("Pushing component <" + localName
+ + "> on top of the object stack.");
ec.pushObject(actionData.nestedComponent);
} catch (Exception oops) {
actionData.inError = true;
- String msg = "Could not create component <" + localName + "> of type ["+className+"]";
+ String msg = "Could not create component <" + localName + "> of type ["
+ + className + "]";
addError(msg, oops);
}
}
public void end(InterpretationContext ec, String tagName) {
-
+
// pop the action data object pushed in isApplicable() method call
// we assume that each this begin
ImplicitActionData actionData = (ImplicitActionData) actionDataStack.pop();
@@ -130,47 +132,41 @@
}
PropertySetter nestedBean = new PropertySetter(actionData.nestedComponent);
-
-// FIXME set parent
- nestedBean.setComponent(
- "parent", actionData.parentBean.getObj());
-
+ nestedBean.setContext(context);
+
+ if (nestedBean.canContainComponent("parent") == ContainmentType.AS_SINGLE_COMPONENT) {
+ nestedBean.setComponent("parent", actionData.parentBean.getObj());
+ }
if (actionData.nestedComponent instanceof LifeCycle) {
((LifeCycle) actionData.nestedComponent).start();
}
-
-
Object o = ec.peekObject();
if (o != actionData.nestedComponent) {
- addError(
- "The object on the top the of the stack is not the component pushed earlier.");
+ addError("The object on the top the of the stack is not the component pushed earlier.");
} else {
- //getLogger().debug("Removing component from the object stack");
+ // getLogger().debug("Removing component from the object stack");
ec.popObject();
// Now let us attach the component
switch (actionData.containmentType) {
- case PropertySetter.AS_COMPONENT:
- //addInfo("Setting ["+tagName+"}] to parent of type ["+actionData.parentBean.getObjClass()+"]");
-
- actionData.parentBean.setComponent(
- tagName, actionData.nestedComponent);
+ case AS_SINGLE_COMPONENT:
+ // addInfo("Setting ["+tagName+"}] to parent of type
+ // ["+actionData.parentBean.getObjClass()+"]");
+
+ actionData.parentBean.setComponent(tagName, actionData.nestedComponent);
break;
- case PropertySetter.AS_COLLECTION:
- //getLogger().debug(
- //"Adding [{}] to parent of type [{}]", tagName,
- //actionData.parentBean.getObjClass());
- actionData.parentBean.addComponent(
- tagName, actionData.nestedComponent);
+ case AS_COMPONENT_COLLECTION:
+ // getLogger().debug(
+ // "Adding [{}] to parent of type [{}]", tagName,
+ // actionData.parentBean.getObjClass());
+ actionData.parentBean.addComponent(tagName, actionData.nestedComponent);
break;
}
}
}
-
}
-
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java Thu Nov 2 19:11:54 2006
@@ -18,6 +18,7 @@
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.util.ContainmentType;
import ch.qos.logback.core.util.PropertySetter;
@@ -54,15 +55,18 @@
PropertySetter parentBean = new PropertySetter(o);
parentBean.setContext(context);
- int containmentType = parentBean.canContainComponent(nestedElementTagName);
+ ContainmentType containmentType = parentBean.canContainComponent(nestedElementTagName);
+ System.out.println("==="+containmentType);
+
switch (containmentType) {
- case PropertySetter.NOT_FOUND:
- case PropertySetter.AS_COMPONENT:
- case PropertySetter.AS_COLLECTION:
+ case NOT_FOUND:
+ case AS_SINGLE_COMPONENT:
+ case AS_COMPONENT_COLLECTION:
return false;
- case PropertySetter.AS_PROPERTY:
+ case AS_SINGLE_PROPERTY:
+ case AS_PROPERTY_COLLECTION:
ImplicitActionData ad = new ImplicitActionData(parentBean, containmentType);
ad.propertyName = nestedElementTagName;
actionDataStack.push(ad);
@@ -85,8 +89,14 @@
//System.out.println("body "+body+", finalBody="+finalBody);
// get the action data object pushed in isApplicable() method call
ImplicitActionData actionData = (ImplicitActionData) actionDataStack.peek();
- actionData.parentBean.setProperty(actionData.propertyName, finalBody);
+ switch (actionData.containmentType) {
+ case AS_SINGLE_COMPONENT:
+ actionData.parentBean.setProperty(actionData.propertyName, finalBody);
+ break;
+ case AS_PROPERTY_COLLECTION:
+ actionData.parentBean.addProperty(actionData.propertyName, finalBody);
+ }
}
public void end(InterpretationContext ec, String tagName) {
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java Thu Nov 2 19:11:54 2006
@@ -43,14 +43,16 @@
int lastIndex = 0;
- //System.out.println("p is "+ p);
+ // System.out.println("p is "+ p);
while (true) {
int k = p.indexOf('/', lastIndex);
- //System.out.println("k is "+ k);
+ // System.out.println("k is "+ k);
if (k == -1) {
- components.add(p.substring(lastIndex));
-
+ String lastPart = p.substring(lastIndex);
+ if(lastPart != null && lastPart.length() > 0) {
+ components.add(p.substring(lastIndex));
+ }
break;
} else {
String c = p.substring(lastIndex, k);
@@ -213,7 +215,7 @@
int size = components.size();
String result = "";
for(int i = 0; i < size; i++) {
- result += "/" + components.get(i);
+ result += "[" + components.get(i) + "]";
}
return result;
}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/ContainmentType.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/ContainmentType.java Thu Nov 2 19:11:54 2006
@@ -0,0 +1,5 @@
+package ch.qos.logback.core.util;
+
+public enum ContainmentType {
+ NOT_FOUND, AS_SINGLE_COMPONENT, AS_SINGLE_PROPERTY, AS_PROPERTY_COLLECTION, AS_COMPONENT_COLLECTION;
+}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java Thu Nov 2 19:11:54 2006
@@ -50,10 +50,9 @@
* @author Ceki Gulcu
*/
public class PropertySetter extends ContextAwareBase {
- public static final int NOT_FOUND = 0;
- public static final int AS_COMPONENT = 1;
- public static final int AS_PROPERTY = 2;
- public static final int AS_COLLECTION = 3;
+ private static final int X_NOT_FOUND = 0;
+ private static final int X_AS_COMPONENT = 1;
+ private static final int X_AS_PROPERTY = 2;
protected Object obj;
protected Class objClass;
@@ -89,37 +88,6 @@
}
/**
- * Set the properties for the object that match the <code>prefix</code>
- * passed as parameter.
- */
- // public void setProperties(Properties properties, String prefix) {
- // int len = prefix.length();
- //
- // for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) {
- // String key = (String) e.nextElement();
- //
- // // handle only properties that start with the desired frefix.
- // if (key.startsWith(prefix)) {
- // // ignore key if it contains dots after the prefix
- // if (key.indexOf('.', len + 1) > 0) {
- // // System.err.println("----------Ignoring---["+key
- // // +"], prefix=["+prefix+"].");
- // continue;
- // }
- //
- // String value = OptionHelper.findAndSubst(key, properties);
- //
- // key = key.substring(len);
- //
- // if ("layout".equals(key) && obj instanceof Appender) {
- // continue;
- // }
- //
- // setProperty(key, value);
- // }
- // }
- // }
- /**
* Set a property on this PropertySetter's Object. If successful, this method
* will invoke a setter method on the underlying Object. The setter is the one
* for the specified property name and the value is determined partly from the
@@ -208,16 +176,21 @@
}
}
- public int canContainComponent(String name) {
+ public ContainmentType canContainComponent(String name) {
String cName = capitalizeFirstLetter(name);
- Method method = getMethod("add" + cName);
-
- if (method != null) {
- // getLogger().debug(
- // "Found add {} method in class {}", cName, objClass.getName());
+ Method addMethod = getMethod("add" + cName);
- return AS_COLLECTION;
+ if (addMethod != null) {
+ int type = computeContainmentTpye(addMethod);
+ switch (type) {
+ case X_NOT_FOUND:
+ return ContainmentType.NOT_FOUND;
+ case X_AS_PROPERTY:
+ return ContainmentType.AS_PROPERTY_COLLECTION;
+ case X_AS_COMPONENT:
+ return ContainmentType.AS_COMPONENT_COLLECTION;
+ }
}
String dName = Introspector.decapitalize(name);
@@ -230,25 +203,39 @@
// getLogger().debug(
// "Found setter method for property [{}] in class {}", name,
// objClass.getName());
- Class[] classArray = setterMethod.getParameterTypes();
- if (classArray.length != 1) {
- return NOT_FOUND;
- } else {
- Class clazz = classArray[0];
- Package p = clazz.getPackage();
- if (clazz.isPrimitive()) {
- return AS_PROPERTY;
- } else if ("java.lang".equals(p.getName())) {
- return AS_PROPERTY;
- } else {
- return AS_COMPONENT;
- }
+ int type = computeContainmentTpye(setterMethod);
+ // getLogger().debug(
+ // "Found add {} method in class {}", cName, objClass.getName());
+ switch (type) {
+ case X_NOT_FOUND:
+ return ContainmentType.NOT_FOUND;
+ case X_AS_PROPERTY:
+ return ContainmentType.AS_SINGLE_PROPERTY;
+ case X_AS_COMPONENT:
+ return ContainmentType.AS_SINGLE_COMPONENT;
}
}
}
// we have failed
- return NOT_FOUND;
+ return ContainmentType.NOT_FOUND;
+ }
+
+ int computeContainmentTpye(Method setterMethod) {
+ Class[] classArray = setterMethod.getParameterTypes();
+ if (classArray.length != 1) {
+ return X_NOT_FOUND;
+ } else {
+ Class clazz = classArray[0];
+ Package p = clazz.getPackage();
+ if (clazz.isPrimitive()) {
+ return X_AS_PROPERTY;
+ } else if ("java.lang".equals(p.getName())) {
+ return X_AS_PROPERTY;
+ } else {
+ return X_AS_COMPONENT;
+ }
+ }
}
public Class getObjClass() {
@@ -292,6 +279,48 @@
}
}
+ @SuppressWarnings("unchecked")
+ public void addProperty(String name, String strValue) {
+
+ if (strValue == null) {
+ return;
+ }
+
+ name = capitalizeFirstLetter(name);
+
+ Method adderMethod = getMethod("add" + name);
+ if (adderMethod == null) {
+ addError("No adder for property [" + name + "].");
+ return;
+ }
+
+ Class[] paramTypes = adderMethod.getParameterTypes();
+ if (paramTypes.length != 1) {
+ addError("#params for setter != 1");
+ return;
+
+ }
+ Object arg;
+ try {
+ arg = convertArg(strValue, paramTypes[0]);
+ } catch (Throwable t) {
+ addError("Conversion to type [" + paramTypes[0] + "] failed. ", t);
+ return;
+ }
+
+ if (arg == null) {
+ addError("Conversion to type [" + paramTypes[0] + "] failed.");
+ } else {
+
+ try {
+ adderMethod.invoke(obj, new Object[] { arg });
+ } catch (Exception ex) {
+ addError("Failed to invoke adder for " + name, ex);
+ }
+ }
+
+ }
+
public void setComponent(String name, Object childComponent) {
String dName = Introspector.decapitalize(name);
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(dName);
@@ -387,10 +416,10 @@
}
for (int i = 0; i < propertyDescriptors.length; i++) {
- //System.out.println("Comparing " + name + " against "
- // + propertyDescriptors[i].getName());
+ // System.out.println("Comparing " + name + " against "
+ // + propertyDescriptors[i].getName());
if (name.equals(propertyDescriptors[i].getName())) {
- //System.out.println("matched");
+ // System.out.println("matched");
return propertyDescriptors[i];
}
}
Added: logback/trunk/logback-core/src/test/input/joran/simplePropertyIA1.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/input/joran/simplePropertyIA1.xml Thu Nov 2 19:11:54 2006
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<context>
+ <fruit class="ch.qos.logback.core.joran.ia.Fruit">
+ <name>blue</name>
+ <text>hello</text>
+ </fruit>
+</context>
\ No newline at end of file
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllTest.java Thu Nov 2 19:11:54 2006
@@ -21,7 +21,6 @@
suite.addTest(ch.qos.logback.core.pattern.PackageTest.suite());
suite.addTest(ch.qos.logback.core.joran.PackageTest.suite());
suite.addTest(ch.qos.logback.core.appender.PackageTest.suite());
- suite.addTest(ch.qos.logback.core.rolling.helper.PackageTest.suite());
suite.addTest(ch.qos.logback.core.rolling.PackageTest.suite());
return suite;
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java Thu Nov 2 19:11:54 2006
@@ -22,6 +22,7 @@
suite.addTest(ch.qos.logback.core.joran.event.PackageTest.suite());
suite.addTest(ch.qos.logback.core.joran.spi.PackageTest.suite());
suite.addTest(ch.qos.logback.core.joran.replay.PackageTest.suite());
+ suite.addTest(ch.qos.logback.core.joran.ia.PackageTest.suite());
return suite;
}
}
Copied: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java (from r829, /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/SimpleConfigurator.java)
==============================================================================
--- /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/SimpleConfigurator.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/SimpleConfigurator.java Thu Nov 2 19:11:54 2006
@@ -7,7 +7,7 @@
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-package ch.qos.logback.core.joran.replay;
+package ch.qos.logback.core.joran;
import java.util.HashMap;
@@ -42,6 +42,7 @@
protected void addInstanceRules(RuleStore rs) {
for(Pattern pattern : rulesMap.keySet()) {
Action action = rulesMap.get(pattern);
+ System.out.println("Adding "+pattern +" "+action);
rs.addRule(pattern, action);
}
}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/Fruit.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/Fruit.java Thu Nov 2 19:11:54 2006
@@ -0,0 +1,27 @@
+package ch.qos.logback.core.joran.ia;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Fruit {
+
+ String name;
+ List<String> textList = new ArrayList<String>();
+
+ public Fruit() {
+ System.out.println("Fruit constructor called");
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void addText(String s) {
+ textList.add(s);
+ }
+
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContext.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContext.java Thu Nov 2 19:11:54 2006
@@ -0,0 +1,23 @@
+package ch.qos.logback.core.joran.ia;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.qos.logback.core.ContextBase;
+
+public class FruitContext extends ContextBase {
+
+ List<Fruit> fruitList = new ArrayList<Fruit>();
+
+ public void addFruit(Fruit fs) {
+ fruitList.add(fs);
+ }
+
+ public List<Fruit> getFruitList() {
+ return fruitList;
+ }
+
+ public void setFruitShellList(List<Fruit> fruitList) {
+ this.fruitList = fruitList;
+ }
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContextAction.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/FruitContextAction.java Thu Nov 2 19:11:54 2006
@@ -0,0 +1,62 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework for Java.
+ *
+ * Copyright (C) 2000-2006, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.joran.ia;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.ActionException;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+
+public class FruitContextAction extends Action {
+
+ private boolean inError = false;
+
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+
+
+ inError = false;
+
+ try {
+ ec.pushObject(context);
+ } catch (Exception oops) {
+ inError = true;
+ addError(
+ "Could not push context", oops);
+ throw new ActionException(ActionException.SKIP_CHILDREN, oops);
+ }
+ }
+
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ if (inError) {
+ return;
+ }
+
+ Object o = ec.peekObject();
+
+ if (o != context) {
+ addWarn(
+ "The object at the of the stack is not the context named ["
+ + context.getName() + "] pushed earlier.");
+ } else {
+ addInfo(
+ "Popping context named [" + context.getName()
+ + "] from the object stack");
+ ec.popObject();
+ }
+ }
+
+
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/PackageTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/PackageTest.java Thu Nov 2 19:11:54 2006
@@ -0,0 +1,23 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 1999-2006, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.joran.ia;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class PackageTest extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(SimplePropertyIATest.class);
+ return suite;
+ }
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/SimplePropertyIATest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/ia/SimplePropertyIATest.java Thu Nov 2 19:11:54 2006
@@ -0,0 +1,55 @@
+package ch.qos.logback.core.joran.ia;
+
+import java.util.HashMap;
+import java.util.List;
+
+import junit.framework.TestCase;
+import ch.qos.logback.core.joran.SimpleConfigurator;
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.util.Constants;
+import ch.qos.logback.core.util.StatusPrinter;
+
+public class SimplePropertyIATest extends TestCase {
+
+ FruitContext fruitContext = new FruitContext();
+
+ public SimplePropertyIATest(String arg0) {
+ super(arg0);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ fruitContext.setName("fruits");
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void test() throws Exception {
+ try {
+ HashMap<Pattern, Action> rulesMap = new HashMap<Pattern, Action>();
+ rulesMap.put(new Pattern("/context/"), new FruitContextAction());
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(rulesMap);
+
+ simpleConfigurator.setContext(fruitContext);
+
+ simpleConfigurator.doConfigure(Constants.TEST_DIR_PREFIX + "input/joran/"
+ + "simplePropertyIA1.xml");
+ StatusPrinter.print(fruitContext);
+ List<Fruit> fList = fruitContext.getFruitList();
+ assertNotNull(fList);
+ assertEquals(1, fList.size());
+
+ Fruit f0 = fList.get(0);
+ assertEquals("blue", f0.getName());
+ assertEquals(1, f0.textList.size());
+ } catch (Exception je) {
+ StatusPrinter.print(fruitContext);
+ throw je;
+ }
+ }
+
+
+}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java Thu Nov 2 19:11:54 2006
@@ -1,9 +1,13 @@
package ch.qos.logback.core.joran.replay;
+import java.util.ArrayList;
+import java.util.List;
+
public class Fruit {
String name;
-
+ List<String> textList = new ArrayList<String>();
+
public Fruit() {
System.out.println("Fruit constructor called");
}
@@ -25,4 +29,9 @@
return retValue.toString();
}
+
+ public void addText(String s) {
+ textList.add(s);
+ }
+
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java Thu Nov 2 19:11:54 2006
@@ -6,6 +6,7 @@
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import ch.qos.logback.core.joran.SimpleConfigurator;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.joran.action.NOPAction;
import ch.qos.logback.core.joran.spi.Pattern;
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java Thu Nov 2 19:11:54 2006
@@ -49,6 +49,13 @@
assertEquals("a", p.get(0));
}
+ public void testSuffix() {
+ Pattern p = new Pattern("a/");
+ assertEquals(1, p.size());
+ assertEquals("a", p.peekLast());
+ assertEquals("a", p.get(0));
+ }
+
public void test2() {
Pattern p = new Pattern("a/b");
assertEquals(2, p.size());
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java Thu Nov 2 19:11:54 2006
@@ -69,9 +69,23 @@
fail("Wrong type");
}
- // jp.parse(doc);
}
+ public void testSlashSuffix() throws Exception {
+ SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
+ Pattern pa = new Pattern("a/");
+ srs.addRule(pa, new XAction());
+
+ List r = srs.matchActions(new Pattern("a"));
+ assertNotNull(r);
+ assertEquals(1, r.size());
+
+ if (!(r.get(0) instanceof XAction)) {
+ fail("Wrong type");
+ }
+
+
+ }
public void testTail1() throws Exception {
SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
srs.addRule(new Pattern("*/b"), new XAction());
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/PackageTest.java Thu Nov 2 19:11:54 2006
@@ -11,6 +11,7 @@
suite.addTestSuite(RenamingTest.class);
suite.addTestSuite(SizeBasedRollingTest.class);
suite.addTestSuite(TimeBasedRollingTest.class);
+ suite.addTest(ch.qos.logback.core.rolling.helper.PackageTest.suite());
return suite;
}
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/util/PropertySetterTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/util/PropertySetterTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/util/PropertySetterTest.java Thu Nov 2 19:11:54 2006
@@ -1,5 +1,8 @@
package ch.qos.logback.core.util;
+import java.util.ArrayList;
+import java.util.List;
+
import ch.qos.logback.core.util.PropertySetter;
import junit.framework.TestCase;
@@ -8,16 +11,20 @@
public void testCanContainComponent() {
House house = new House();
PropertySetter setter = new PropertySetter(house);
- assertEquals(PropertySetter.AS_COMPONENT, setter.canContainComponent("door"));
+ assertEquals(ContainmentType.AS_SINGLE_COMPONENT, setter.canContainComponent("door"));
+
+ assertEquals(ContainmentType.AS_SINGLE_PROPERTY, setter.canContainComponent("count"));
+ assertEquals(ContainmentType.AS_SINGLE_PROPERTY, setter.canContainComponent("Count"));
- assertEquals(PropertySetter.AS_PROPERTY, setter.canContainComponent("count"));
- assertEquals(PropertySetter.AS_PROPERTY, setter.canContainComponent("Count"));
+ assertEquals(ContainmentType.AS_SINGLE_PROPERTY, setter.canContainComponent("name"));
+ assertEquals(ContainmentType.AS_SINGLE_PROPERTY, setter.canContainComponent("Name"));
- assertEquals(PropertySetter.AS_PROPERTY, setter.canContainComponent("name"));
- assertEquals(PropertySetter.AS_PROPERTY, setter.canContainComponent("Name"));
+ assertEquals(ContainmentType.AS_SINGLE_PROPERTY, setter.canContainComponent("open"));
+ assertEquals(ContainmentType.AS_SINGLE_PROPERTY, setter.canContainComponent("Open"));
+
+ assertEquals(ContainmentType.AS_COMPONENT_COLLECTION, setter.canContainComponent("Window"));
+ assertEquals(ContainmentType.AS_PROPERTY_COLLECTION, setter.canContainComponent("adjective"));
- assertEquals(PropertySetter.AS_PROPERTY, setter.canContainComponent("open"));
- assertEquals(PropertySetter.AS_PROPERTY, setter.canContainComponent("Open"));
}
public void testSetProperty() {
@@ -55,10 +62,6 @@
setter.setProperty("camelCase", "gh");
assertEquals("gh", house.getCamelCase());
-
- setter.setProperty("OnMatch", "raven");
- assertEquals("raven", house.getOnMatch());
-
}
public void testSetComponent() {
@@ -68,6 +71,31 @@
setter.setComponent("door", door);
assertEquals(door, house.getDoor());
}
+
+ public void testPropertyCollection() {
+ House house = new House();
+ PropertySetter setter = new PropertySetter(house);
+ setter.addProperty("adjective", "nice");
+ setter.addProperty("adjective", "big");
+ assertEquals(2, house.adjectiveList.size());
+ assertEquals("nice", house.adjectiveList.get(0));
+ assertEquals("big", house.adjectiveList.get(1));
+ }
+
+ public void testComponentCollection() {
+ House house = new House();
+ PropertySetter setter = new PropertySetter(house);
+ Window w1 = new Window();
+ w1.handle=10;
+ Window w2 = new Window();
+ w2.handle=20;
+
+ setter.addComponent("window", w1);
+ setter.addComponent("window", w2);
+ assertEquals(2, house.windowList.size());
+ assertEquals(10, house.windowList.get(0).handle);
+ assertEquals(20, house.windowList.get(1).handle);
+ }
public void testSetComponentWithCamelCaseName() {
House house = new House();
@@ -80,22 +108,16 @@
}
class House {
- Door door;
+ Door mainDoor;
int count;
boolean open;
String name;
String camelCase;
- String onMatch;
SwimmingPool pool;
- public String getOnMatch() {
- return onMatch;
- }
-
- public void setOnMatch(String onMatch) {
- this.onMatch = onMatch;
- }
-
+ List<String> adjectiveList = new ArrayList<String>();
+ List<Window> windowList = new ArrayList<Window>();
+
public String getCamelCase() {
return camelCase;
}
@@ -113,11 +135,11 @@
}
public Door getDoor() {
- return door;
+ return mainDoor;
}
public void setDoor(Door door) {
- this.door = door;
+ this.mainDoor = door;
}
public String getName() {
@@ -143,12 +165,25 @@
public SwimmingPool getSwimmingPool() {
return pool;
}
+
+ public void addWindow(Window w) {
+ windowList.add(w);
+ }
+
+
+ public void addAdjective(String s) {
+ adjectiveList.add(s);
+ }
}
class Door {
int handle;
}
+class Window {
+ int handle;
+}
+
class SwimmingPool {
int length;
int width;
1
0