[logback-dev] svn commit: r2079 - in logback/trunk: logback-classic/src/main/java/ch/qos/logback/classic/hoard logback-classic/src/main/java/ch/qos/logback/classic/joran logback-classic/src/main/java/ch/qos/logback/classic/spi logback-classic/src/test/input/joran/hoard logback-classic/src/test/java/ch/qos/logback/classic/hoard logback-core/src/main/java/ch/qos/logback/core logback-core/src/main/java/ch/qos/logback/core/db logback-core/src/main/java/ch/qos/logback/core/joran logback-core/src/main/java/ch/qos/logback/core/joran/action logback-core/src/main/java/ch/qos/logback/core/joran/spi logback-core/src/main/java/ch/qos/logback/core/spi logback-core/src/main/java/ch/qos/logback/core/util logback-core/src/test/java/ch/qos/logback/core/joran/action
noreply.ceki at qos.ch
noreply.ceki at qos.ch
Fri Dec 12 22:05:20 CET 2008
Author: ceki
Date: Fri Dec 12 22:05:20 2008
New Revision: 2079
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderFactory.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardAction.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingAppender.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingJoranConfigurator.java
logback/trunk/logback-classic/src/test/input/joran/hoard/
logback/trunk/logback-classic/src/test/input/joran/hoard/hoard0.xml
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/HoardingAppenderTest.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyContainer.java
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/spi/LoggerContextAwareBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/Context.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/BindDataSourceToJNDIAction.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/GenericConfigurator.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.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/InterpretationContext.java
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/util/OptionHelper.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/PropertyActionTest.java
Log:
- Initial commit of HoardingAppender
HoardingAppender contains other appenders which it can build
dynamically depending on MDC values. The built appender is specified
as part of a configuration file. Here is an example.
<configuration debug="true">
<appender name="HOARD" class="ch.qos.logback.classic.hoard.HoardingAppender">
<mdcKey>userid</mdcKey>
<hoard>
<!-- you can put any appender here -->
<appender name="file-${userid}" class="ch.qos.logback.core.FileAppender">
<File>${userid}.log</File>
<Append>true</Append>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d [%thread] %level %logger{35} - %msg%n</Pattern>
</layout>
</appender>
</hoard>
</appender>
<root level="DEBUG">
<appender-ref ref="HOARD" />
</root>
</configuration>
A new file appender will be built each according to the MDC value
associated with the key "userid" when a logging event occurs. The
above configuration file will ventilate logging into log files named
after the userid.
- Added PropertyContainer interface
- Context interface now extends PropertyContainer
- InterpretationContext implements PropertyContainer
It now has a field called propertiesMap which has precedence
over values placed in the context
- InterpretationContext.getSubstitutionProperty was renamed as
getProperty
- It is now possible to initialize a joran Interpreter with an initial
(not empty) pattern
This is still very much ongoing work.
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderFactory.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderFactory.java Fri Dec 12 22:05:20 2008
@@ -0,0 +1,49 @@
+package ch.qos.logback.classic.hoard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.joran.event.SaxEvent;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.util.StatusPrinter;
+
+public class AppenderFactory {
+
+ final List<SaxEvent> eventList;
+ Context context;
+
+ AppenderFactory(Context context, List<SaxEvent> eventList) {
+ this.context = context;
+ this.eventList = new ArrayList<SaxEvent>(eventList);
+ removeHoardElement();
+
+ }
+
+ void removeHoardElement() {
+ eventList.remove(0);
+ eventList.remove(eventList.size() - 1);
+ System.out.println(eventList);
+ }
+
+ Appender<LoggingEvent> buildAppender(Context context, String mdcKey,
+ String mdcValue) throws JoranException {
+ //HoardingContext hoardingContext = new HoardingContext(context, mdcKey,
+ // mdcValue);
+ HoardingJoranConfigurator hjc = new HoardingJoranConfigurator(mdcKey, mdcValue);
+ hjc.setContext(context);
+
+ hjc.doConfigure(eventList);
+
+ StatusPrinter.print(context);
+
+ return hjc.getAppender();
+ }
+
+ public List<SaxEvent> getEventList() {
+ return eventList;
+ }
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardAction.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardAction.java Fri Dec 12 22:05:20 2008
@@ -0,0 +1,47 @@
+package ch.qos.logback.classic.hoard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.event.InPlayListener;
+import ch.qos.logback.core.joran.event.SaxEvent;
+import ch.qos.logback.core.joran.spi.ActionException;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+
+public class HoardAction extends Action implements InPlayListener {
+ List<SaxEvent> seList;
+
+ @Override
+ public void begin(InterpretationContext ec, String name, Attributes attributes)
+ throws ActionException {
+ seList = new ArrayList<SaxEvent>();
+ ec.addInPlayListener(this);
+ }
+
+ @Override
+ public void end(InterpretationContext ec, String name) throws ActionException {
+ ec.removeInPlayListener(this);
+ Object o = ec.peekObject();
+ if (o instanceof HoardingAppender) {
+ HoardingAppender ha = (HoardingAppender) o;
+ AppenderFactory appenderFactory = new AppenderFactory(context, seList);
+ ha.setAppenderFactory(appenderFactory);
+ }
+ }
+
+ public void inPlay(SaxEvent event) {
+ seList.add(event);
+ System.out.println(event);
+ }
+
+ public List<SaxEvent> getSeList() {
+ return seList;
+ }
+
+
+
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingAppender.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingAppender.java Fri Dec 12 22:05:20 2008
@@ -0,0 +1,59 @@
+package ch.qos.logback.classic.hoard;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.slf4j.MDC;
+
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.UnsynchronizedAppenderBase;
+import ch.qos.logback.core.joran.spi.JoranException;
+
+public class HoardingAppender extends UnsynchronizedAppenderBase<LoggingEvent> {
+
+ static String DEFAULT = "default";
+
+ Map<String, Appender<LoggingEvent>> appenderMap = new Hashtable<String, Appender<LoggingEvent>>();
+
+ String mdcKey;
+
+ AppenderFactory appenderFactory;
+
+ void setAppenderFactory(AppenderFactory appenderFactory) {
+ this.appenderFactory = appenderFactory;
+ }
+
+
+
+ @Override
+ protected void append(LoggingEvent loggingEvent) {
+ String mdcValue = MDC.get(mdcKey);
+
+ if (mdcValue == null) {
+ mdcValue = DEFAULT;
+ }
+
+ Appender<LoggingEvent> appender = appenderMap.get(mdcValue);
+
+ if (appender == null) {
+ try {
+ appender = appenderFactory.buildAppender(context, mdcKey, mdcValue);
+ } catch (JoranException e) {
+ addError("Failed to build appender for " + mdcKey + "=" + mdcValue, e);
+ return;
+ }
+ }
+ appender.doAppend(loggingEvent);
+ }
+
+ public String getMdcKey() {
+ return mdcKey;
+ }
+
+ public void setMdcKey(String mdcKey) {
+ this.mdcKey = mdcKey;
+ }
+
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingJoranConfigurator.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingJoranConfigurator.java Fri Dec 12 22:05:20 2008
@@ -0,0 +1,64 @@
+package ch.qos.logback.classic.hoard;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.joran.GenericConfigurator;
+import ch.qos.logback.core.joran.action.ActionConst;
+import ch.qos.logback.core.joran.action.AppenderAction;
+import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
+import ch.qos.logback.core.joran.action.NestedComplexPropertyIA;
+import ch.qos.logback.core.joran.spi.Interpreter;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.joran.spi.RuleStore;
+
+public class HoardingJoranConfigurator extends GenericConfigurator {
+
+ String key;
+ String value;
+
+ HoardingJoranConfigurator(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+ @Override
+ protected Pattern initialPattern() {
+ return new Pattern("configuration");
+ }
+
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ NestedComplexPropertyIA nestedComplexIA = new NestedComplexPropertyIA();
+ nestedComplexIA.setContext(context);
+ interpreter.addImplicitAction(nestedComplexIA);
+
+ NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA();
+ nestedSimpleIA.setContext(context);
+ interpreter.addImplicitAction(nestedSimpleIA);
+ }
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ rs.addRule(new Pattern("configuration/appender"), new AppenderAction());
+ }
+
+ @Override
+ protected void buildInterpreter() {
+ super.buildInterpreter();
+ Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
+ omap.put(ActionConst.APPENDER_BAG, new HashMap());
+ omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap());
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put(key, value);
+ interpreter.setInterpretationContextPropertiesMap(propertiesMap);
+ }
+
+ public Appender getAppender() {
+ Map<String, Object> omap = interpreter.getInterpretationContext().getObjectMap();
+ HashMap map = (HashMap) omap.get(ActionConst.APPENDER_BAG);
+ Collection values = map.values();
+ return (Appender) values.iterator().next();
+ }
+}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java Fri Dec 12 22:05:20 2008
@@ -10,6 +10,7 @@
package ch.qos.logback.classic.joran;
+import ch.qos.logback.classic.hoard.HoardAction;
import ch.qos.logback.classic.joran.action.ConfigurationAction;
import ch.qos.logback.classic.joran.action.ConsolePluginAction;
import ch.qos.logback.classic.joran.action.ContextNameAction;
@@ -25,6 +26,7 @@
import ch.qos.logback.core.joran.action.AppenderRefAction;
import ch.qos.logback.core.joran.action.IncludeAction;
import ch.qos.logback.core.joran.action.MatcherAction;
+import ch.qos.logback.core.joran.action.NOPAction;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.joran.spi.RuleStore;
@@ -51,6 +53,10 @@
rs.addRule(new Pattern("*/evaluator/matcher"),
new MatcherAction());
+ rs.addRule(new Pattern("configuration/appender/hoard"), new HoardAction());
+ rs.addRule(new Pattern("configuration/appender/hoard/*"), new NOPAction());
+
+
rs.addRule(new Pattern("configuration/logger"), new LoggerAction());
rs.addRule(new Pattern("configuration/logger/level"), new LevelAction());
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAwareBase.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAwareBase.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggerContextAwareBase.java Fri Dec 12 22:05:20 2008
@@ -1,11 +1,11 @@
/**
- * LOGBack: the reliable, fast and flexible logging library for Java.
- *
- * 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.
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.spi;
Added: logback/trunk/logback-classic/src/test/input/joran/hoard/hoard0.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/hoard/hoard0.xml Fri Dec 12 22:05:20 2008
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration debug="true">
+
+ <appender name="HOARD"
+ class="ch.qos.logback.classic.hoard.HoardingAppender">
+
+ <mdcKey>userid</mdcKey>
+
+
+ <hoard>
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <File>${userid}.log</File>
+ <Append>true</Append>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%d [%thread] %level %logger{35} - %msg%n</Pattern>
+ </layout>
+ </appender>
+ </hoard>
+
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="HOARD" />
+ </root>
+
+</configuration>
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/HoardingAppenderTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/HoardingAppenderTest.java Fri Dec 12 22:05:20 2008
@@ -0,0 +1,44 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.hoard;
+
+import org.junit.Test;
+
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.classic.util.TeztConstants;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.util.StatusPrinter;
+
+public class HoardingAppenderTest {
+
+ static String PREFIX = TeztConstants.TEST_DIR_PREFIX + "input/joran/hoard/";
+
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass().getName());
+ Logger root = loggerContext.getLogger(LoggerContext.ROOT_NAME);
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
+
+
+ @Test
+ public void testLevel() throws JoranException {
+ configure(PREFIX + "hoard0.xml");
+ logger.debug("ss");
+ //StatusPrinter.print(loggerContext);
+
+ }
+
+}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/Context.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/Context.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/Context.java Fri Dec 12 22:05:20 2008
@@ -9,10 +9,11 @@
*/
package ch.qos.logback.core;
+import ch.qos.logback.core.spi.PropertyContainer;
import ch.qos.logback.core.status.StatusManager;
-public interface Context {
+public interface Context extends PropertyContainer {
StatusManager getStatusManager();
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/BindDataSourceToJNDIAction.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/BindDataSourceToJNDIAction.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/db/BindDataSourceToJNDIAction.java Fri Dec 12 22:05:20 2008
@@ -40,7 +40,7 @@
*/
public void begin(
InterpretationContext ec, String localName, Attributes attributes) {
- String dsClassName = ec.getSubstitutionProperty(DATA_SOURCE_CLASS);
+ String dsClassName = ec.getProperty(DATA_SOURCE_CLASS);
if (OptionHelper.isEmpty(dsClassName)) {
addWarn("dsClassName is a required parameter");
@@ -49,9 +49,9 @@
return;
}
- String urlStr = ec.getSubstitutionProperty(URL);
- String userStr = ec.getSubstitutionProperty(USER);
- String passwordStr = ec.getSubstitutionProperty(PASSWORD);
+ String urlStr = ec.getProperty(URL);
+ String userStr = ec.getProperty(USER);
+ String passwordStr = ec.getProperty(PASSWORD);
try {
DataSource ds =
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 Fri Dec 12 22:05:20 2008
@@ -24,6 +24,7 @@
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.joran.spi.Interpreter;
import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.joran.spi.RuleStore;
import ch.qos.logback.core.joran.spi.SimpleRuleStore;
import ch.qos.logback.core.spi.ContextAwareBase;
@@ -78,10 +79,14 @@
abstract protected void addImplicitRules(Interpreter interpreter);
+ protected Pattern initialPattern() {
+ return new Pattern();
+ }
+
protected void buildInterpreter() {
RuleStore rs = new SimpleRuleStore(context);
addInstanceRules(rs);
- this.interpreter = new Interpreter(context, rs);
+ this.interpreter = new Interpreter(context, rs, initialPattern());
InterpretationContext ec = interpreter.getInterpretationContext();
ec.setContext(context);
addImplicitRules(interpreter);
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java Fri Dec 12 22:05:20 2008
@@ -64,7 +64,7 @@
// remove the <included> tag from the beginning and </included> from the end
trimHeadAndTail(recorder);
- ec.getJoranInterpreter().addEvents(recorder.saxEventList);
+ ec.getJoranInterpreter().addEventsDynamically(recorder.saxEventList);
}
private boolean checkAttributes(Attributes attributes) {
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 Fri Dec 12 22:05:20 2008
@@ -51,7 +51,7 @@
}
}
- public void addEvents(List<SaxEvent> eventList) {
+ public void addEventsDynamically(List<SaxEvent> eventList) {
this.eventList.addAll(currentIndex+2, eventList);
}
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/InterpretationContext.java Fri Dec 12 22:05:20 2008
@@ -24,30 +24,38 @@
import ch.qos.logback.core.joran.event.InPlayListener;
import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.spi.ContextAwareBase;
+import ch.qos.logback.core.spi.PropertyContainer;
import ch.qos.logback.core.util.OptionHelper;
-
/**
*
* An InterpretationContext contains the contextual state of a Joran parsing
- * session. {@link Action} objects depend on this context to exchange
- * and store information.
+ * session. {@link Action} objects depend on this context to exchange and store
+ * information.
*
* @author Ceki Gülcü
*/
-public class InterpretationContext extends ContextAwareBase {
+public class InterpretationContext extends ContextAwareBase implements
+ PropertyContainer {
Stack<Object> objectStack;
Map<String, Object> objectMap;
+ Map<String, String> propertiesMap;
+
Interpreter joranInterpreter;
final List<InPlayListener> listenerList = new ArrayList<InPlayListener>();
-
+
public InterpretationContext(Context context, Interpreter joranInterpreter) {
this.context = context;
this.joranInterpreter = joranInterpreter;
- objectStack = new Stack<Object> ();
+ objectStack = new Stack<Object>();
objectMap = new HashMap<String, Object>(5);
+ propertiesMap = new HashMap<String, String>(5);
}
-
+
+ void setPropertiesMap(Map<String, String> propertiesMap) {
+ this.propertiesMap = propertiesMap;
+ }
+
String updateLocationInfo(String msg) {
Locator locator = joranInterpreter.getLocator();
@@ -57,7 +65,7 @@
return msg;
}
}
-
+
public Locator getLocator() {
return joranInterpreter.getLocator();
}
@@ -135,31 +143,40 @@
}
}
- public String getSubstitutionProperty(String key) {
- return context.getProperty(key);
+ /**
+ * If a key is found in propertiesMap then return it. Otherwise, delegate to
+ * the context.
+ */
+ public String getProperty(String key) {
+ String v = propertiesMap.get(key);
+ if (v != null) {
+ return v;
+ } else {
+ return context.getProperty(key);
+ }
}
public String subst(String value) {
if (value == null) {
return null;
}
- return OptionHelper.substVars(value, context);
+ return OptionHelper.substVars(value, this);
}
-
+
public void addInPlayListener(InPlayListener ipl) {
- if(listenerList.contains(ipl)) {
- addWarn("InPlayListener "+ipl+" has been already registered");
+ if (listenerList.contains(ipl)) {
+ addWarn("InPlayListener " + ipl + " has been already registered");
} else {
listenerList.add(ipl);
}
}
-
+
public boolean removeInPlayListener(InPlayListener ipl) {
return listenerList.remove(ipl);
}
-
+
void fireInPlay(SaxEvent event) {
- for(InPlayListener ipl: listenerList) {
+ for (InPlayListener ipl : listenerList) {
ipl.inPlay(event);
}
}
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 Fri Dec 12 22:05:20 2008
@@ -12,6 +12,7 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Stack;
import java.util.Vector;
@@ -64,7 +65,7 @@
private static List EMPTY_LIST = new Vector(0);
final private RuleStore ruleStore;
- final private InterpretationContext ec;
+ final private InterpretationContext interpretationContext;
final private ArrayList<ImplicitAction> implicitActions;
final private CAI_WithLocatorSupport cai;
Pattern pattern;
@@ -87,18 +88,20 @@
*/
Pattern skip = null;
- public Interpreter(Context context, RuleStore rs) {
+ public Interpreter(Context context, RuleStore rs, Pattern initialPattern) {
this.cai = new CAI_WithLocatorSupport(this);
this.cai.setContext(context);
ruleStore = rs;
- ec = new InterpretationContext(context, this);
+ interpretationContext = new InterpretationContext(context, this);
implicitActions = new ArrayList<ImplicitAction>(3);
- pattern = new Pattern();
+ this.pattern = initialPattern;
actionListStack = new Stack<List>();
player = new EventPlayer(this);
}
-
+ public void setInterpretationContextPropertiesMap(Map<String, String> propertiesMap) {
+ interpretationContext.setPropertiesMap(propertiesMap);
+ }
/**
* @deprecated replaced by {@link #getInterpretationContext()}
*/
@@ -107,7 +110,7 @@
}
public InterpretationContext getInterpretationContext() {
- return ec;
+ return interpretationContext;
}
public void startDocument() {
@@ -241,7 +244,7 @@
// logger.debug("set of applicable patterns: " + applicableActionList);
if (applicableActionList == null) {
- applicableActionList = lookupImplicitAction(pattern, attributes, ec);
+ applicableActionList = lookupImplicitAction(pattern, attributes, interpretationContext);
}
return applicableActionList;
@@ -259,7 +262,7 @@
// now let us invoke the action. We catch and report any eventual
// exceptions
try {
- action.begin(ec, tagName, atts);
+ action.begin(interpretationContext, tagName, atts);
} catch (ActionException e) {
skip = (Pattern) pattern.clone();
cai.addError("ActionException in Action for tag [" + tagName + "]", e);
@@ -279,7 +282,7 @@
while (i.hasNext()) {
Action action = (Action) i.next();
try {
- action.body(ec, body);
+ action.body(interpretationContext, body);
} catch (ActionException ae) {
cai
.addError("Exception in end() methd for action [" + action + "]",
@@ -301,7 +304,7 @@
// now let us invoke the end method of the action. We catch and report
// any eventual exceptions
try {
- action.end(ec, tagName);
+ action.end(interpretationContext, tagName);
} catch (ActionException ae) {
// at this point endAction, there is no point in skipping children as
// they have been already processed
@@ -321,9 +324,9 @@
player.play(eventList);
}
- public void addEvents(List<SaxEvent> eventList) {
+ public void addEventsDynamically(List<SaxEvent> eventList) {
if (player != null) {
- player.addEvents(eventList);
+ player.addEventsDynamically(eventList);
}
}
}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyContainer.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/spi/PropertyContainer.java Fri Dec 12 22:05:20 2008
@@ -0,0 +1,6 @@
+package ch.qos.logback.core.spi;
+
+public interface PropertyContainer {
+
+ public String getProperty(String key);
+}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java Fri Dec 12 22:05:20 2008
@@ -14,6 +14,7 @@
import ch.qos.logback.core.Context;
import ch.qos.logback.core.CoreConstants;
+import ch.qos.logback.core.spi.PropertyContainer;
/**
* @author Ceki Gulcu
@@ -125,7 +126,7 @@
* @throws IllegalArgumentException
* if <code>val</code> is malformed.
*/
- public static String substVars(String val, Context context) {
+ public static String substVars(String val, PropertyContainer pc) {
StringBuffer sbuf = new StringBuffer();
@@ -167,7 +168,7 @@
String replacement = null;
// first try the props passed as parameter
- replacement = context.getProperty(key);
+ replacement = pc.getProperty(key);
// then try in System properties
if (replacement == null) {
@@ -186,7 +187,7 @@
// where the properties are
// x1=p1
// x2=${x1}
- String recursiveReplacement = substVars(replacement, context);
+ String recursiveReplacement = substVars(replacement, pc);
sbuf.append(recursiveReplacement);
} else {
// if we could not find a replacement, then signal the error
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/PropertyActionTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/PropertyActionTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/PropertyActionTest.java Fri Dec 12 22:05:20 2008
@@ -43,7 +43,7 @@
atts.setValue("name", "v1");
atts.setValue("value", "work");
spAction.begin(ec, null, atts);
- assertEquals("work", ec.getSubstitutionProperty("v1"));
+ assertEquals("work", ec.getProperty("v1"));
}
@Test
@@ -52,7 +52,7 @@
atts.setValue("name", "v1");
atts.setValue("value", "${w}k");
spAction.begin(ec, null, atts);
- assertEquals("work", ec.getSubstitutionProperty("v1"));
+ assertEquals("work", ec.getProperty("v1"));
}
@Test
@@ -93,24 +93,24 @@
context.putProperty("STEM", Constants.TEST_DIR_PREFIX + "input/joran");
atts.setValue("file", "${STEM}/propertyActionTest.properties");
spAction.begin(ec, null, atts);
- assertEquals("tata", ec.getSubstitutionProperty("v1"));
- assertEquals("toto", ec.getSubstitutionProperty("v2"));
+ assertEquals("tata", ec.getProperty("v1"));
+ assertEquals("toto", ec.getProperty("v2"));
}
@Test
public void testLoadFile() {
atts.setValue("file", Constants.TEST_DIR_PREFIX + "input/joran/propertyActionTest.properties");
spAction.begin(ec, null, atts);
- assertEquals("tata", ec.getSubstitutionProperty("v1"));
- assertEquals("toto", ec.getSubstitutionProperty("v2"));
+ assertEquals("tata", ec.getProperty("v1"));
+ assertEquals("toto", ec.getProperty("v2"));
}
@Test
public void testLoadResource() {
atts.setValue("resource", "asResource/joran/propertyActionTest.properties");
spAction.begin(ec, null, atts);
- assertEquals("tata", ec.getSubstitutionProperty("r1"));
- assertEquals("toto", ec.getSubstitutionProperty("r2"));
+ assertEquals("tata", ec.getProperty("r1"));
+ assertEquals("toto", ec.getProperty("r2"));
}
@Test
@@ -118,8 +118,8 @@
context.putProperty("STEM", "asResource/joran");
atts.setValue("resource", "${STEM}/propertyActionTest.properties");
spAction.begin(ec, null, atts);
- assertEquals("tata", ec.getSubstitutionProperty("r1"));
- assertEquals("toto", ec.getSubstitutionProperty("r2"));
+ assertEquals("tata", ec.getProperty("r1"));
+ assertEquals("toto", ec.getProperty("r2"));
}
@Test
More information about the logback-dev
mailing list