[logback-dev] svn commit: r1427 - in logback/trunk: logback-classic/src/main/java/ch/qos/logback/classic/joran logback-classic/src/main/java/ch/qos/logback/classic/joran/action logback-classic/src/test/input/joran logback-classic/src/test/java/ch/qos/logback/classic/joran logback-core/src/main/java/ch/qos/logback/core/joran logback-core/src/main/java/ch/qos/logback/core/joran/spi
noreply.seb at qos.ch
noreply.seb at qos.ch
Wed Mar 14 20:44:42 CET 2007
Author: seb
Date: Wed Mar 14 20:44:42 2007
New Revision: 1427
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoadConfigurationFileAction.java
logback/trunk/logback-classic/src/test/input/joran/invalidConfig.xml
logback/trunk/logback-classic/src/test/input/joran/invalidRedirect.xml
logback/trunk/logback-classic/src/test/input/joran/redirectConfig.xml
logback/trunk/logback-classic/src/test/input/joran/redirectToInvalid.xml
logback/trunk/logback-classic/src/test/input/joran/redirectWithSubst.xml
logback/trunk/logback-classic/src/test/input/joran/simpleConfig.xml
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/LoadConfigurationFileTest.java
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
Log:
Added include functionality to Joran.
The <include> pattern used in a <configuration> pattern can have a "path" attribute with the path to a file that will be parsed and executed to configure logback.
This attribute can be set with a property.
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java Wed Mar 14 20:44:42 2007
@@ -15,6 +15,7 @@
import ch.qos.logback.classic.joran.action.JMXConfiguratorAction;
import ch.qos.logback.classic.joran.action.LayoutAction;
import ch.qos.logback.classic.joran.action.LevelAction;
+import ch.qos.logback.classic.joran.action.LoadConfigurationFileAction;
import ch.qos.logback.classic.joran.action.LoggerAction;
import ch.qos.logback.classic.joran.action.RootLoggerAction;
import ch.qos.logback.core.joran.JoranConfiguratorBase;
@@ -58,6 +59,7 @@
new LayoutAction());
rs.addRule(new Pattern("configuration/jmxConfigurator"), new JMXConfiguratorAction());
+ rs.addRule(new Pattern("configuration/include"), new LoadConfigurationFileAction());
}
}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoadConfigurationFileAction.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/LoadConfigurationFileAction.java Wed Mar 14 20:44:42 2007
@@ -0,0 +1,88 @@
+/**
+ * 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 ch.qos.logback.classic.joran.action;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.event.SaxEvent;
+import ch.qos.logback.core.joran.event.SaxEventRecorder;
+import ch.qos.logback.core.joran.spi.ActionException;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.joran.spi.JoranException;
+
+public class LoadConfigurationFileAction extends Action {
+
+ private static final String INCLUDED_TAG = "included";
+ private static final String PATH_ATTR = "path";
+ private SaxEventRecorder recorder;
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+
+ String attribute = attributes.getValue(PATH_ATTR);
+ if (attribute == null) {
+ addError("Path to configuration file to include is not set.");
+ return;
+ }
+
+ String pathToFile;
+
+ if (attribute.startsWith("$")) {
+ pathToFile = ec.subst(attribute);
+ } else {
+ pathToFile = attribute;
+ }
+
+ try {
+ InputStream in = new FileInputStream(pathToFile);
+ parseAndRecord(in);
+ in.close();
+ } catch (IOException ioe) {
+ String errMsg = "File [" + pathToFile + "] does not exist.";
+ addError(errMsg, ioe);
+ } catch (JoranException e) {
+ addError("Error while parsing file " + pathToFile + e);
+ }
+
+ if (recorder.saxEventList.size() == 0) {
+ return;
+ }
+
+ SaxEvent first = recorder.saxEventList.get(0);
+ if (first != null && first.qName.equalsIgnoreCase(INCLUDED_TAG)) {
+ recorder.saxEventList.remove(0);
+ }
+
+ SaxEvent last = recorder.saxEventList.get(recorder.saxEventList.size()-1);
+ if (last != null && last.qName.equalsIgnoreCase(INCLUDED_TAG)) {
+ recorder.saxEventList.remove(recorder.saxEventList.size()-1);
+ }
+
+ ec.getJoranInterpreter().addEvents(recorder.saxEventList);
+ }
+
+ private void parseAndRecord(InputStream inputSource) throws JoranException {
+ recorder = new SaxEventRecorder();
+ recorder.setContext(context);
+ recorder.recordEvents(inputSource);
+ }
+
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ // do nothing
+ }
+
+}
Added: logback/trunk/logback-classic/src/test/input/joran/invalidConfig.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/invalidConfig.xml Wed Mar 14 20:44:42 2007
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE included>
+
+<included>
+ <!-- This file is invalid on purpose. Do not correct it. -->
+
+ <appender name="redirectConsole"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <param name="Pattern" value="%d - %m%n" />
+ </layout>
+
+
+ <root>
+ <level value="DEBUG" />
+ <appender-ref ref="redirectConsole" />
+ </root>
+
+</included>
\ No newline at end of file
Added: logback/trunk/logback-classic/src/test/input/joran/invalidRedirect.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/invalidRedirect.xml Wed Mar 14 20:44:42 2007
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration>
+
+ <include path="toto" />
+
+</configuration>
Added: logback/trunk/logback-classic/src/test/input/joran/redirectConfig.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/redirectConfig.xml Wed Mar 14 20:44:42 2007
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration>
+
+ <include path="src/test/input/joran/simpleConfig.xml" />
+
+</configuration>
Added: logback/trunk/logback-classic/src/test/input/joran/redirectToInvalid.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/redirectToInvalid.xml Wed Mar 14 20:44:42 2007
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration>
+
+ <include path="src/test/input/joran/invalidConfig.xml" />
+
+</configuration>
Added: logback/trunk/logback-classic/src/test/input/joran/redirectWithSubst.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/redirectWithSubst.xml Wed Mar 14 20:44:42 2007
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration>
+ <substitutionProperty name="path.to.file"
+ value="src/test/input/joran/simpleConfig.xml" />
+
+ <include path="${path.to.file}" />
+
+</configuration>
Added: logback/trunk/logback-classic/src/test/input/joran/simpleConfig.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/simpleConfig.xml Wed Mar 14 20:44:42 2007
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE included>
+
+<included>
+
+ <appender name="redirectConsole"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <param name="Pattern" value="%d - %m%n" />
+ </layout>
+ </appender>
+
+ <root>
+ <level value="DEBUG" />
+ <appender-ref ref="redirectConsole" />
+ </root>
+
+</included>
\ No newline at end of file
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/LoadConfigurationFileTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/LoadConfigurationFileTest.java Wed Mar 14 20:44:42 2007
@@ -0,0 +1,85 @@
+package ch.qos.logback.classic.joran;
+
+import junit.framework.TestCase;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.joran.action.LoadConfigurationFileAction;
+import ch.qos.logback.classic.util.Constants;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.ConsoleAppender;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.status.Status;
+
+public class LoadConfigurationFileTest extends TestCase {
+
+ LoggerContext context;
+ LoadConfigurationFileAction action;
+
+ String filePath = Constants.TEST_DIR_PREFIX
+ + "input/joran/redirectConfig.xml";
+ String invalidRedirect = Constants.TEST_DIR_PREFIX
+ + "input/joran/invalidRedirect.xml";
+ String filePathWithSubst = Constants.TEST_DIR_PREFIX
+ + "input/joran/redirectWithSubst.xml";
+ String redirectToInvalid = Constants.TEST_DIR_PREFIX
+ + "input/joran/redirectToInvalid.xml";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ context = new LoggerContext();
+ action = new LoadConfigurationFileAction();
+ action.setContext(context);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ action = null;
+ context = null;
+ }
+
+ public void testLoadFileOK() throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ jc.doConfigure(filePath);
+
+ verifyConfig();
+ }
+
+ public void testNoFileFound() throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ jc.doConfigure(invalidRedirect);
+
+ assertEquals(3, context.getStatusManager().getCount());
+ assertEquals(Status.ERROR, context.getStatusManager().getLevel());
+ }
+
+ public void testWithCorruptFile() throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ jc.doConfigure(redirectToInvalid);
+
+ assertEquals(10, context.getStatusManager().getCount());
+ assertEquals(Status.ERROR, context.getStatusManager().getLevel());
+ }
+
+ public void testWithSubst() throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(context);
+ jc.doConfigure(filePathWithSubst);
+
+ verifyConfig();
+ }
+
+ private void verifyConfig() {
+ Logger logger = context.getLogger(LoggerContext.ROOT_NAME);
+ Appender appender = (ConsoleAppender) logger.getAppender("redirectConsole");
+ assertNotNull(appender);
+ PatternLayout layout = (PatternLayout) appender.getLayout();
+ assertNotNull(layout);
+ assertEquals("%d - %m%n", layout.getPattern());
+ }
+}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/joran/PackageTest.java Wed Mar 14 20:44:42 2007
@@ -17,7 +17,7 @@
TestSuite suite = new TestSuite();
suite.addTestSuite(BasicJoranTest.class);
suite.addTestSuite(EvaluatorJoranTest.class);
-
+ suite.addTestSuite(LoadConfigurationFileTest.class);
return suite;
}
}
\ No newline at end of file
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java Wed Mar 14 20:44:42 2007
@@ -85,7 +85,6 @@
InterpretationContext ec = interpreter.getExecutionContext();
ec.setContext(context);
addImplicitRules(interpreter);
-
}
final public void doConfigure(final InputSource inputSource)
@@ -94,8 +93,7 @@
recorder.setContext(context);
recorder.recordEvents(inputSource);
buildInterpreter();
- EventPlayer player = new EventPlayer(interpreter);
- player.play(recorder.saxEventList);
+ interpreter.play(recorder.saxEventList);
}
public void doConfigure(final List<SaxEvent> eventList)
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/EventPlayer.java Wed Mar 14 20:44:42 2007
@@ -19,14 +19,19 @@
public class EventPlayer {
final Interpreter interpreter;
-
+ List<SaxEvent> eventList;
+ int currentIndex;
+
public EventPlayer(Interpreter interpreter) {
- this.interpreter = interpreter;
+ this.interpreter = interpreter;
}
public void play(List<SaxEvent> seList) {
-
- for(SaxEvent se : seList) {
+ eventList = seList;
+ SaxEvent se;
+ for(currentIndex = 0; currentIndex < eventList.size(); currentIndex++) {
+ se = eventList.get(currentIndex);
+
if(se instanceof StartEvent) {
interpreter.startElement((StartEvent) se);
// invoke fireInPlay after startElement processing
@@ -45,4 +50,8 @@
}
}
+
+ public void addEvents(List<SaxEvent> eventList) {
+ this.eventList.addAll(currentIndex+2, eventList);
+ }
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Interpreter.java Wed Mar 14 20:44:42 2007
@@ -23,6 +23,7 @@
import ch.qos.logback.core.joran.action.ImplicitAction;
import ch.qos.logback.core.joran.event.BodyEvent;
import ch.qos.logback.core.joran.event.EndEvent;
+import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.event.StartEvent;
import ch.qos.logback.core.spi.ContextAwareImpl;
@@ -68,6 +69,7 @@
final private ContextAwareImpl cai;
Pattern pattern;
Locator locator;
+ EventPlayer player;
/**
* The <id>actionListStack</id> contains a list of actions that are executing
@@ -93,6 +95,7 @@
implicitActions = new ArrayList<ImplicitAction>(3);
pattern = new Pattern();
actionListStack = new Stack<List>();
+ player = new EventPlayer(this);
}
public InterpretationContext getExecutionContext() {
@@ -328,4 +331,14 @@
public RuleStore getRuleStore() {
return ruleStore;
}
+
+ public void play(List<SaxEvent> eventList) {
+ player.play(eventList);
+ }
+
+ public void addEvents(List<SaxEvent> eventList) {
+ if (player != null) {
+ player.addEvents(eventList);
+ }
+ }
}
More information about the logback-dev
mailing list