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

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
participants (1)
-
noreply.ceki@qos.ch