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