svn commit: r715 - in logback/trunk/logback-core/src: main/java/ch/qos/logback/core/joran main/java/ch/qos/logback/core/joran/action main/java/ch/qos/logback/core/joran/spi main/java/ch/qos/logback/core/util test/input/joran test/java/ch/qos/logback/core test/java/ch/qos/logback/core/joran test/java/ch/qos/logback/core/joran/event test/java/ch/qos/logback/core/joran/replay test/java/ch/qos/logback/core/joran/spi test/java/ch/qos/logback/core/pattern

Author: ceki Date: Thu Oct 19 15:45:50 2006 New Revision: 715 Added: logback/trunk/logback-core/src/test/input/joran/fruit1.xml logback/trunk/logback-core/src/test/input/joran/fruit2.xml logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitAction.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitContext.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactory.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactoryAction.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShell.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShellAction.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/PackageTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/SimpleConfigurator.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/WeightytFruit.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/pattern/PackageTest.java - copied, changed from r714, /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/pattern/AllTest.java Removed: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/event/FruitConfigAction.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/pattern/AllTest.java 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/action/NestedSimplePropertyIA.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/event/InPlayFireTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java Log: - Added suffix pattern matching to SimpleRuleStore. We can now do pattern matching for a/*. - Tested Joran's newly introduced reconfigure capability. 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 Thu Oct 19 15:45:50 2006 @@ -30,7 +30,7 @@ public abstract class GenericConfigurator extends ContextAwareBase { - Interpreter interpreter; + protected Interpreter interpreter; final public void doConfigure(URL url) throws JoranException { try { @@ -98,7 +98,7 @@ player.play(recorder.saxEventList); } - final public void doConfigure(final List<SaxEvent> eventList) + public void doConfigure(final List<SaxEvent> eventList) throws JoranException { buildInterpreter(); EventPlayer player = new EventPlayer(interpreter); Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedSimplePropertyIA.java Thu Oct 19 15:45:50 2006 @@ -60,7 +60,7 @@ ImplicitActionData ad = new ImplicitActionData(parentBean, containmentType); ad.propertyName = nestedElementTagName; actionDataStack.push(ad); - + // System.out.println("NestedSimplePropertyIA deemed applicable for " +pattern); return true; default: addError("PropertySetter.canContainComponent returned " + containmentType); Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java Thu Oct 19 15:45:50 2006 @@ -98,7 +98,7 @@ * with the pattern p passed as parameter. By "tail" components we mean the * components at the end of the pattern. */ - public int tailMatch(Pattern p) { + public int getTailMatchLength(Pattern p) { if (p == null) { return 0; } @@ -129,6 +129,43 @@ return match; } + /** + * Returns the number of "prefix" components that this pattern has in common + * with the pattern p passed as parameter. By "prefix" components we mean the + * components at the beginning of the pattern. + */ + public int getPrefixMatchLength(Pattern p) { + if (p == null) { + return 0; + } + + int lSize = this.components.size(); + int rSize = p.components.size(); + + // no match possible for empty sets + if ((lSize == 0) || (rSize == 0)) { + return 0; + } + + int minLen = (lSize <= rSize) ? lSize : rSize; + int match = 0; + + for (int i = 0; i < minLen; i++) { + String l = (String) this.components.get(i); + String r = (String) p.components.get(i); + + if (l.equals(r) || "*".equals(l) || "*".equals(r)) { + match++; + } else { + break; + } + } + + return match; + } + + + @Override public boolean equals(Object o) { //System.out.println("in equals:" +this+ " vs. " + o); Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/SimpleRuleStore.java Thu Oct 19 15:45:50 2006 @@ -12,7 +12,6 @@ import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import ch.qos.logback.core.Context; @@ -67,38 +66,77 @@ } } - public List matchActions(Pattern pattern) { + // exact match has highest priority + // if no exact match, check for tail match, i.e matches of type */x/y + // tail match for */x/y has higher priority than match for */x + // if no tail match, check for prefix match, i.e. matches for x/* + // match for x/y/* has higher priority than matches for x/* + + public List matchActions(Pattern currentPattern) { //System.out.println("pattern to search for:" + pattern + ", hashcode: " + pattern.hashCode()); //System.out.println("rules:" + rules); - ArrayList a4p = (ArrayList) rules.get(pattern); + List actionList; - if (a4p != null) { - return a4p; + if ((actionList = rules.get(currentPattern)) != null) { + return actionList; + } else if ( (actionList = tailMatch(currentPattern)) != null){ + return actionList; + } else if ((actionList = prefixMatch(currentPattern)) != null) { + return actionList; } else { - Iterator patternsIterator = rules.keySet().iterator(); - int max = 0; - Pattern longestMatch = null; - - while (patternsIterator.hasNext()) { - Pattern p = (Pattern) patternsIterator.next(); - - if ((p.size() > 1) && p.get(0).equals("*")) { - int r = pattern.tailMatch(p); - - //System.out.println("tailMatch " +r); - if (r > max) { - //System.out.println("New longest match "+p); - max = r; - longestMatch = p; - } + return null; + } + } + + List tailMatch(Pattern currentPattern) { + int max = 0; + Pattern longestMatchingPattern = null; + + for (Pattern p: rules.keySet()) { + + if ((p.size() > 1) && p.get(0).equals("*")) { + int r = currentPattern.getTailMatchLength(p); + + //System.out.println("tailMatch " +r); + if (r > max) { + //System.out.println("New longest tailMatch "+p); + max = r; + longestMatchingPattern = p; } } + } - if (longestMatch != null) { - return (ArrayList) rules.get(longestMatch); - } else { - return null; + if (longestMatchingPattern != null) { + return rules.get(longestMatchingPattern); + } else { + return null; + } + } + + List prefixMatch(Pattern currentPattern) { + int max = 0; + Pattern longestMatchingPattern = null; + + for (Pattern p: rules.keySet()) { + String last = p.peekLast(); + if("*".equals(last)) { + int r = currentPattern.getPrefixMatchLength(p); + + //System.out.println("prefixMatch " +r); + if (r > max) { + //System.out.println("New longest prefixMatch "+p); + max = r; + longestMatchingPattern = p; + } } } + + if (longestMatchingPattern != null) { + //System.out.println("prefixMatch will return" +rules.get(longestMatchingPattern)); + return rules.get(longestMatchingPattern); + } else { + return null; + } } + } Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/PropertySetter.java Thu Oct 19 15:45:50 2006 @@ -17,7 +17,6 @@ // Contributors: Georg Lundesgaard package ch.qos.logback.core.util; - import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; @@ -31,46 +30,46 @@ import ch.qos.logback.core.Appender; import ch.qos.logback.core.spi.ContextAwareBase; - - /** - * General purpose Object property setter. Clients repeatedly invokes - * {@link #setProperty setProperty(name,value)} in order to invoke setters - * on the Object specified in the constructor. This class relies on the - * JavaBeans {@link Introspector} to analyze the given Object Class using - * reflection. + * General purpose Object property setter. Clients repeatedly invokes + * {@link #setProperty setProperty(name,value)} in order to invoke setters on + * the Object specified in the constructor. This class relies on the JavaBeans + * {@link Introspector} to analyze the given Object Class using reflection. * - * <p>Usage: - <pre> - PropertySetter ps = new PropertySetter(anObject); - ps.set("name", "Joe"); - ps.set("age", "32"); - ps.set("isMale", "true"); - </pre> - - * will cause the invocations anObject.setName("Joe"), anObject.setAge(32), - * and setMale(true) if such methods exist with those signatures. - * Otherwise an {@link IntrospectionException} are thrown. - - @author Anders Kristensen - @author Ceki Gulcu + * <p> + * Usage: + * + * <pre> + * PropertySetter ps = new PropertySetter(anObject); + * ps.set("name", "Joe"); + * ps.set("age", "32"); + * ps.set("isMale", "true"); + * </pre> + * + * will cause the invocations anObject.setName("Joe"), anObject.setAge(32), and + * setMale(true) if such methods exist with those signatures. Otherwise an + * {@link IntrospectionException} are thrown. + * + * @author Anders Kristensen + * @author Ceki Gulcu */ public class PropertySetter extends ContextAwareBase { public static final int NOT_FOUND = 0; public static final int AS_COMPONENT = 1; public static final int AS_PROPERTY = 2; public static final int AS_COLLECTION = 3; - + protected Object obj; protected Class objClass; protected PropertyDescriptor[] propertyDescriptors; protected MethodDescriptor[] methodDescriptors; /** - Create a new PropertySetter for the specified Object. This is done - in preparation for invoking {@link #setProperty} one or more times. - - @param obj the object for which to set properties + * Create a new PropertySetter for the specified Object. This is done in + * preparation for invoking {@link #setProperty} one or more times. + * + * @param obj + * the object for which to set properties */ public PropertySetter(Object obj) { this.obj = obj; @@ -78,8 +77,8 @@ } /** - Uses JavaBeans {@link Introspector} to computer setters of object to be - configured. + * Uses JavaBeans {@link Introspector} to computer setters of object to be + * configured. */ protected void introspect() { try { @@ -87,15 +86,14 @@ propertyDescriptors = bi.getPropertyDescriptors(); methodDescriptors = bi.getMethodDescriptors(); } catch (IntrospectionException ex) { - addError( - "Failed to introspect " + obj + ": " + ex.getMessage()); + addError("Failed to introspect " + obj + ": " + ex.getMessage()); propertyDescriptors = new PropertyDescriptor[0]; methodDescriptors = new MethodDescriptor[0]; } } /** - * Set the properties for the object that match the <code>prefix</code> + * Set the properties for the object that match the <code>prefix</code> * passed as parameter. */ public void setProperties(Properties properties, String prefix) { @@ -108,13 +106,13 @@ if (key.startsWith(prefix)) { // ignore key if it contains dots after the prefix if (key.indexOf('.', len + 1) > 0) { - //System.err.println("----------Ignoring---["+key - // +"], prefix=["+prefix+"]."); + // System.err.println("----------Ignoring---["+key + // +"], prefix=["+prefix+"]."); continue; } String value = OptionHelper.findAndSubst(key, properties); - + key = key.substring(len); if ("layout".equals(key) && obj instanceof Appender) { @@ -127,19 +125,22 @@ } /** - Set a property on this PropertySetter's Object. If successful, this - method will invoke a setter method on the underlying Object. The - setter is the one for the specified property name and the value is - determined partly from the setter argument type and partly from the - value specified in the call to this method. - - <p>If the setter expects a String no conversion is necessary. - If it expects an int, then an attempt is made to convert 'value' - to an int using new Integer(value). If the setter expects a boolean, - the conversion is by new Boolean(value). - - @param name name of the property - @param value String value of the property + * Set a property on this PropertySetter's Object. If successful, this method + * will invoke a setter method on the underlying Object. The setter is the one + * for the specified property name and the value is determined partly from the + * setter argument type and partly from the value specified in the call to + * this method. + * + * <p> + * If the setter expects a String no conversion is necessary. If it expects an + * int, then an attempt is made to convert 'value' to an int using new + * Integer(value). If the setter expects a boolean, the conversion is by new + * Boolean(value). + * + * @param name + * name of the property + * @param value + * String value of the property */ public void setProperty(String name, String value) { if (value == null) { @@ -150,35 +151,37 @@ PropertyDescriptor prop = getPropertyDescriptor(name); - //LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType()); + // LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType()); if (prop == null) { - addWarn( - "No such property [" + name + "] in " + objClass.getName() + "."); + addWarn("No such property [" + name + "] in " + objClass.getName() + "."); } else { try { setProperty(prop, name, value); } catch (PropertySetterException ex) { - addWarn( - "Failed to set property [" + name + "] to value \"" + value + "\". ", ex); + addWarn("Failed to set property [" + name + "] to value \"" + value + + "\". ", ex); } } } /** - Set the named property given a {@link PropertyDescriptor}. - - @param prop A PropertyDescriptor describing the characteristics - of the property to set. - @param name The named of the property to set. - @param value The value of the property. + * Set the named property given a {@link PropertyDescriptor}. + * + * @param prop + * A PropertyDescriptor describing the characteristics of the + * property to set. + * @param name + * The named of the property to set. + * @param value + * The value of the property. */ public void setProperty(PropertyDescriptor prop, String name, String value) - throws PropertySetterException { + throws PropertySetterException { Method setter = prop.getWriteMethod(); if (setter == null) { - throw new PropertySetterException( - "No setter for property [" + name + "]."); + throw new PropertySetterException("No setter for property [" + name + + "]."); } Class[] paramTypes = setter.getParameterTypes(); @@ -192,16 +195,16 @@ try { arg = convertArg(value, paramTypes[0]); } catch (Throwable t) { - throw new PropertySetterException( - "Conversion to type [" + paramTypes[0] + "] failed. ", t); + throw new PropertySetterException("Conversion to type [" + paramTypes[0] + + "] failed. ", t); } if (arg == null) { - throw new PropertySetterException( - "Conversion to type [" + paramTypes[0] + "] failed."); + throw new PropertySetterException("Conversion to type [" + paramTypes[0] + + "] failed."); } - //getLogger().debug("Setting property [{}] to [{}].", name, arg); + // getLogger().debug("Setting property [{}] to [{}].", name, arg); try { setter.invoke(obj, new Object[] { arg }); @@ -216,33 +219,32 @@ Method method = getMethod("add" + cName); if (method != null) { - //getLogger().debug( - // "Found add {} method in class {}", cName, objClass.getName()); + // getLogger().debug( + // "Found add {} method in class {}", cName, objClass.getName()); return AS_COLLECTION; } String dName = Introspector.decapitalize(name); - + PropertyDescriptor propertyDescriptor = getPropertyDescriptor(dName); if (propertyDescriptor != null) { Method setterMethod = propertyDescriptor.getWriteMethod(); - if (setterMethod != null) { - //getLogger().debug( - // "Found setter method for property [{}] in class {}", name, - // objClass.getName()); + // getLogger().debug( + // "Found setter method for property [{}] in class {}", name, + // objClass.getName()); Class[] classArray = setterMethod.getParameterTypes(); - if(classArray.length != 1) { + if (classArray.length != 1) { return NOT_FOUND; } else { Class clazz = classArray[0]; Package p = clazz.getPackage(); - if(clazz.isPrimitive()) { + if (clazz.isPrimitive()) { return AS_PROPERTY; - } else if("java.lang".equals(p.getName())) { + } else if ("java.lang".equals(p.getName())) { return AS_PROPERTY; } else { return AS_COMPONENT; @@ -255,8 +257,6 @@ return NOT_FOUND; } - - public Class getObjClass() { return objClass; } @@ -277,28 +277,24 @@ try { method.invoke(this.obj, new Object[] { childComponent }); } catch (Exception e) { - addError( - "Could not invoke method " + method.getName() + " in class " - + obj.getClass().getName() + " with parameter of type " - + ccc.getName(), e); + addError("Could not invoke method " + method.getName() + + " in class " + obj.getClass().getName() + + " with parameter of type " + ccc.getName(), e); } } else { - addError( - "A \"" + ccc.getName() + "\" object is not assignable to a \"" - + params[0].getName() + "\" variable."); - addError( - "The class \"" + params[0].getName() + "\" was loaded by "); - addError( - "[" + params[0].getClassLoader() + "] whereas object of type "); - addError( - "\"" + ccc.getName() + "\" was loaded by [" + ccc.getClassLoader() - + "]."); + addError("A \"" + ccc.getName() + + "\" object is not assignable to a \"" + params[0].getName() + + "\" variable."); + addError("The class \"" + params[0].getName() + "\" was loaded by "); + addError("[" + params[0].getClassLoader() + + "] whereas object of type "); + addError("\"" + ccc.getName() + "\" was loaded by [" + + ccc.getClassLoader() + "]."); } } } else { - addError( - "Could not find method [" + "add" + name + "] in class [" - + objClass.getName() + "]."); + addError("Could not find method [" + "add" + name + "] in class [" + + objClass.getName() + "]."); } } @@ -306,9 +302,8 @@ PropertyDescriptor propertyDescriptor = getPropertyDescriptor(name); if (propertyDescriptor == null) { - addWarn( - "Could not find PropertyDescriptor for [" + name + "] in " - + objClass.getName()); + addWarn("Could not find PropertyDescriptor for [" + name + "] in " + + objClass.getName()); return; } @@ -316,9 +311,8 @@ Method setter = propertyDescriptor.getWriteMethod(); if (setter == null) { - addWarn( - "Not setter method for property [" + name + "] in " - + obj.getClass().getName()); + addWarn("Not setter method for property [" + name + "] in " + + obj.getClass().getName()); return; } @@ -326,21 +320,20 @@ Class[] paramTypes = setter.getParameterTypes(); if (paramTypes.length != 1) { - addError( - "Wrong number of parameters in setter method for property [" + name - + "] in " + obj.getClass().getName()); + addError("Wrong number of parameters in setter method for property [" + + name + "] in " + obj.getClass().getName()); return; } try { setter.invoke(obj, new Object[] { childComponent }); - //getLogger().debug( - // "Set child component of type [{}] for [{}].", objClass.getName(), - // childComponent.getClass().getName()); + // getLogger().debug( + // "Set child component of type [{}] for [{}].", objClass.getName(), + // childComponent.getClass().getName()); } catch (Exception e) { - addError( - "Could not set component " + obj + " for parent component " + obj, e); + addError("Could not set component " + obj + " for parent component " + + obj, e); } } @@ -349,9 +342,8 @@ } /** - Convert <code>val</code> a String parameter to an object of a - given type. - */ + * Convert <code>val</code> a String parameter to an object of a given type. + */ protected Object convertArg(String val, Class type) { if (val == null) { return null; @@ -365,6 +357,10 @@ return new Integer(v); } else if (Long.TYPE.isAssignableFrom(type)) { return new Long(v); + } else if (Float.TYPE.isAssignableFrom(type)) { + return new Float(v); + } else if (Double.TYPE.isAssignableFrom(type)) { + return new Double(v); } else if (Boolean.TYPE.isAssignableFrom(type)) { if ("true".equalsIgnoreCase(v)) { return Boolean.TRUE; Added: logback/trunk/logback-core/src/test/input/joran/fruit1.xml ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/input/joran/fruit1.xml Thu Oct 19 15:45:50 2006 @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<group> + <fruitShell name="fs0"> + <fruit class="ch.qos.logback.core.joran.replay.Fruit"> + <name>blue</name> + </fruit> + </fruitShell> +</group> \ No newline at end of file Added: logback/trunk/logback-core/src/test/input/joran/fruit2.xml ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/input/joran/fruit2.xml Thu Oct 19 15:45:50 2006 @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<group> + <fruitShell name="fs0"> + <fruit class="ch.qos.logback.core.joran.replay.Fruit"> + <name>blue</name> + </fruit> + </fruitShell> + + <fruitShell name="fs1"> + <fruit class="ch.qos.logback.core.joran.replay.WeightytFruit"> + <name>orange</name> + <weight>1.2</weight> + </fruit> + </fruitShell> +</group> \ No newline at end of file Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllTest.java Thu Oct 19 15:45:50 2006 @@ -18,11 +18,11 @@ public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(ch.qos.logback.core.util.PackageTest.suite()); - suite.addTest(ch.qos.logback.core.pattern.AllTest.suite()); + suite.addTest(ch.qos.logback.core.pattern.PackageTest.suite()); + suite.addTest(ch.qos.logback.core.joran.PackageTest.suite()); suite.addTest(ch.qos.logback.core.appender.PackageTest.suite()); suite.addTest(ch.qos.logback.core.rolling.helper.PackageTest.suite()); suite.addTest(ch.qos.logback.core.rolling.PackageTest.suite()); - suite.addTest(ch.qos.logback.core.joran.PackageTest.suite()); return suite; } } Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/PackageTest.java Thu Oct 19 15:45:50 2006 @@ -21,6 +21,7 @@ suite.addTestSuite(TrivialcConfiguratorTest.class); suite.addTest(ch.qos.logback.core.joran.event.PackageTest.suite()); suite.addTest(ch.qos.logback.core.joran.spi.PackageTest.suite()); + suite.addTest(ch.qos.logback.core.joran.replay.PackageTest.suite()); return suite; } } Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/event/InPlayFireTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/event/InPlayFireTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/event/InPlayFireTest.java Thu Oct 19 15:45:50 2006 @@ -42,6 +42,27 @@ assertTrue(listenAction.getSeList().get(1) instanceof StartEvent); assertTrue(listenAction.getSeList().get(2) instanceof BodyEvent); assertTrue(listenAction.getSeList().get(3) instanceof EndEvent); + } + + public void testReplay() throws JoranException { + ListenAction listenAction = new ListenAction(); + + rulesMap.put(new Pattern("fire"), listenAction); + TrivialConfigurator gc = new TrivialConfigurator(rulesMap); + + gc.setContext(context); + gc.doConfigure(Constants.TEST_DIR_PREFIX + "input/joran/fire1.xml"); + for(SaxEvent se: listenAction.getSeList()) { + System.out.println(se); + } + assertEquals(5, listenAction.getSeList().size()); + assertTrue(listenAction.getSeList().get(0) instanceof StartEvent); + assertTrue(listenAction.getSeList().get(1) instanceof StartEvent); + assertTrue(listenAction.getSeList().get(2) instanceof BodyEvent); + assertTrue(listenAction.getSeList().get(3) instanceof EndEvent); } + + + } Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/Fruit.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,28 @@ +package ch.qos.logback.core.joran.replay; + +public class Fruit { + + String name; + + public Fruit() { + System.out.println("Fruit constructor called"); + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public String toString() { + final String TAB = " "; + + StringBuilder retValue = new StringBuilder(); + + retValue.append("xFruit ( ").append("name = ").append(this.name).append(TAB).append(" )"); + + return retValue.toString(); + } +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitAction.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitAction.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,81 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework for Java. + * + * Copyright (C) 2000-2006, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ + +package ch.qos.logback.core.joran.replay; + +import org.xml.sax.Attributes; + +import ch.qos.logback.core.joran.action.Action; +import ch.qos.logback.core.joran.spi.ActionException; +import ch.qos.logback.core.joran.spi.ExecutionContext; +import ch.qos.logback.core.util.OptionHelper; + +public class FruitAction extends Action { + + Fruit fruit; + private boolean inError = false; + + @Override + public void begin(ExecutionContext ec, String name, Attributes attributes) + throws ActionException { + String className = attributes.getValue(CLASS_ATTRIBUTE); + + // We are just beginning, reset variables + fruit = null; + inError = false; + + try { + addInfo("About to instantiate fruit of type ["+className+"]"); + + fruit = (Fruit) OptionHelper.instantiateByClassName( + className, ch.qos.logback.core.joran.replay.Fruit.class); + + String fruitName = attributes.getValue(NAME_ATTRIBUTE); + + if (OptionHelper.isEmpty(fruitName)) { + addWarn( + "No fruit name given for fruit of type " + className + "]."); + } else { + fruit.setName(fruitName); + addInfo("Fruit named as [" + fruitName + "]"); + } + + ec.pushObject(fruit); + } catch (Exception oops) { + inError = true; + addError( + "Could not create an Fruit of type ["+className+"].", oops); + throw new ActionException(ActionException.SKIP_CHILDREN, oops); + } + + } + + @Override + public void end(ExecutionContext ec, String name) throws ActionException { + if (inError) { + return; + } + + Object o = ec.peekObject(); + + if (o != fruit) { + addWarn( + "The object at the of the stack is not the fruit named [" + + fruit.getName() + "] pushed earlier."); + } else { + addInfo( + "Popping fruit named [" + fruit.getName() + + "] from the object stack"); + ec.popObject(); + } + } + + +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurationTest.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,79 @@ +package ch.qos.logback.core.joran.replay; + +import java.util.HashMap; +import java.util.List; + +import junit.framework.TestCase; +import ch.qos.logback.core.joran.NOPAction; +import ch.qos.logback.core.joran.action.Action; +import ch.qos.logback.core.joran.spi.Pattern; +import ch.qos.logback.core.util.Constants; +import ch.qos.logback.core.util.StatusPrinter; + +public class FruitConfigurationTest extends TestCase { + + FruitContext fruitContext = new FruitContext(); + + public FruitConfigurationTest(String arg0) { + super(arg0); + } + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public List<FruitShell> doFirstPart(String filename) throws Exception { + + HashMap<Pattern, Action> rulesMap = new HashMap<Pattern, Action>(); + rulesMap.put(new Pattern("group/fruitShell"), new FruitShellAction()); + rulesMap.put(new Pattern("group/fruitShell/fruit"), new FruitFactoryAction()); + rulesMap.put(new Pattern("group/fruitShell/fruit/*"), new NOPAction()); + SimpleConfigurator gc = new SimpleConfigurator(rulesMap); + + gc.setContext(fruitContext); + + gc.doConfigure(Constants.TEST_DIR_PREFIX + "input/joran/" + filename); + + StatusPrinter.print(fruitContext); + return fruitContext.getFruitShellList(); + + } + + public void test1() throws Exception { + List<FruitShell> fsList = doFirstPart("fruit1.xml"); + assertNotNull(fsList); + assertEquals(1, fsList.size()); + + FruitShell fs0 = fsList.get(0); + assertNotNull(fs0); + assertEquals("fs0", fs0.getName()); + Fruit fruit0 = fs0.fruitFactory.buildFruit(); + assertTrue(fruit0 instanceof Fruit); + assertEquals("blue", fruit0.getName()); + } + + public void test2() throws Exception { + List<FruitShell> fsList = doFirstPart("fruit2.xml"); + assertNotNull(fsList); + assertEquals(2, fsList.size()); + + FruitShell fs0 = fsList.get(0); + assertNotNull(fs0); + assertEquals("fs0", fs0.getName()); + Fruit fruit0 = fs0.fruitFactory.buildFruit(); + assertTrue(fruit0 instanceof Fruit); + assertEquals("blue", fruit0.getName()); + + FruitShell fs1 = fsList.get(1); + assertNotNull(fs1); + assertEquals("fs1", fs1.getName()); + Fruit fruit1 = fs1.fruitFactory.buildFruit(); + assertTrue(fruit1 instanceof WeightytFruit); + assertEquals("orange", fruit1.getName()); + assertEquals(1.2, ((WeightytFruit) fruit1).getWeight()); + } +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitConfigurator.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,58 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework. + * + * Copyright (C) 1999-2006, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ +package ch.qos.logback.core.joran.replay; + +import java.util.List; + +import ch.qos.logback.core.joran.GenericConfigurator; +import ch.qos.logback.core.joran.NOPAction; +import ch.qos.logback.core.joran.action.NestedComponentIA; +import ch.qos.logback.core.joran.action.NestedSimplePropertyIA; +import ch.qos.logback.core.joran.event.SaxEvent; +import ch.qos.logback.core.joran.spi.EventPlayer; +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; + +public class FruitConfigurator extends GenericConfigurator { + + FruitFactory ff; + public FruitConfigurator(FruitFactory ff) { + this.ff = ff; + } + + @Override + final public void doConfigure(final List<SaxEvent> eventList) + throws JoranException { + buildInterpreter(); + interpreter.getExecutionContext().pushObject(ff); + EventPlayer player = new EventPlayer(interpreter); + player.play(eventList); + } + + @Override + protected void addImplicitRules(Interpreter interpreter) { + NestedComponentIA nestedIA = new NestedComponentIA(); + nestedIA.setContext(context); + interpreter.addImplicitAction(nestedIA); + + NestedSimplePropertyIA nestedSimpleIA = new NestedSimplePropertyIA(); + nestedIA.setContext(context); + interpreter.addImplicitAction(nestedSimpleIA); + } + + + @Override + protected void addInstanceRules(RuleStore rs) { + rs.addRule(new Pattern("fruitShell"), new NOPAction()); + } + +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitContext.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitContext.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,23 @@ +package ch.qos.logback.core.joran.replay; + +import java.util.ArrayList; +import java.util.List; + +import ch.qos.logback.core.ContextBase; + +public class FruitContext extends ContextBase { + + List<FruitShell> fruitShellList = new ArrayList<FruitShell>(); + + public void addFruitShell(FruitShell fs) { + fruitShellList.add(fs); + } + + public List<FruitShell> getFruitShellList() { + return fruitShellList; + } + + public void setFruitShellList(List<FruitShell> fruitShellList) { + this.fruitShellList = fruitShellList; + } +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactory.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactory.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,49 @@ +package ch.qos.logback.core.joran.replay; + +import java.util.List; + +import ch.qos.logback.core.Context; +import ch.qos.logback.core.ContextBase; +import ch.qos.logback.core.joran.event.SaxEvent; +import ch.qos.logback.core.joran.spi.JoranException; + +public class FruitFactory { + + List<SaxEvent> eventList; + Fruit fruit; + + public void setFruit(Fruit fruit) { + this.fruit = fruit; + } + + public Fruit buildFruit() { + for (SaxEvent se : eventList) { + System.out.println(se); + } + Context context = new ContextBase(); + this.fruit = null; + FruitConfigurator fruitConfigurator = new FruitConfigurator(this); + fruitConfigurator.setContext(context); + try { + fruitConfigurator.doConfigure(eventList); + } catch(JoranException je) { + je.printStackTrace(); + } + return fruit; + } + + public String toString() { + final String TAB = " "; + + StringBuilder retValue = new StringBuilder(); + + retValue.append("FruitFactory ( "); + if (eventList != null && eventList.size() > 0) { + retValue.append("event1 = ").append(eventList.get(0)).append(TAB); + } + retValue.append(" )"); + + return retValue.toString(); + } + +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactoryAction.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitFactoryAction.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,55 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework for Java. + * + * Copyright (C) 2000-2006, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ + +package ch.qos.logback.core.joran.replay; + +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.ExecutionContext; + +public class FruitFactoryAction extends Action implements InPlayListener { + + List<SaxEvent> seList = new ArrayList<SaxEvent>(); + + @Override + public void begin(ExecutionContext ec, String name, Attributes attributes) + throws ActionException { + ec.addInPlayListener(this); + } + + @Override + public void end(ExecutionContext ec, String name) throws ActionException { + ec.removeInPlayListener(this); + + Object o = ec.peekObject(); + if(o instanceof FruitShell) { + FruitShell fs = (FruitShell) o; + FruitFactory fruitFactory = new FruitFactory(); + fruitFactory.eventList = new ArrayList<SaxEvent>(seList); + fs.setFruitFactory(fruitFactory); + } + } + + public void inPlay(SaxEvent event) { + seList.add(event); + } + + public List<SaxEvent> getSeList() { + return seList; + } + +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShell.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShell.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,49 @@ +package ch.qos.logback.core.joran.replay; + +import ch.qos.logback.core.spi.ContextAwareBase; + +public class FruitShell extends ContextAwareBase { + + FruitFactory fruitFactory; + String name; + + public void setFruitFactory(FruitFactory fruitFactory) { + this.fruitFactory = fruitFactory; + } + + void testFruit() { + + Fruit fruit = fruitFactory.buildFruit(); + System.out.println(fruit); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * Constructs a <code>String</code> with all attributes + * in name = value format. + * + * @return a <code>String</code> representation + * of this object. + */ + public String toString() + { + final String TAB = " "; + + String retValue = ""; + + retValue = "FruitShell ( " + + "fruitFactory = " + this.fruitFactory + TAB + + "name = " + this.name + TAB + + " )"; + + return retValue; + } + +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShellAction.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/FruitShellAction.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,81 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework for Java. + * + * Copyright (C) 2000-2006, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ + +package ch.qos.logback.core.joran.replay; + +import org.xml.sax.Attributes; + +import ch.qos.logback.core.joran.action.Action; +import ch.qos.logback.core.joran.spi.ActionException; +import ch.qos.logback.core.joran.spi.ExecutionContext; +import ch.qos.logback.core.util.OptionHelper; + +public class FruitShellAction extends Action { + + FruitShell fruitShell; + private boolean inError = false; + + + @Override + public void begin(ExecutionContext ec, String name, Attributes attributes) + throws ActionException { + + // We are just beginning, reset variables + fruitShell = new FruitShell(); + inError = false; + + try { + + + fruitShell.setContext(context); + + String shellName = attributes.getValue(NAME_ATTRIBUTE); + + if (OptionHelper.isEmpty(shellName)) { + addWarn( + "No appender name given for fruitShell]."); + } else { + fruitShell.setName(shellName); + addInfo("FruitShell named as [" + shellName + "]"); + } + + ec.pushObject(fruitShell); + } catch (Exception oops) { + inError = true; + addError( + "Could not create an FruitShell", oops); + throw new ActionException(ActionException.SKIP_CHILDREN, oops); + } + } + + @Override + public void end(ExecutionContext ec, String name) throws ActionException { + if (inError) { + return; + } + + Object o = ec.peekObject(); + + if (o != fruitShell) { + addWarn( + "The object at the of the stack is not the fruitShell named [" + + fruitShell.getName() + "] pushed earlier."); + } else { + addInfo( + "Popping fruitSHell named [" + fruitShell.getName() + + "] from the object stack"); + ec.popObject(); + FruitContext fruitContext = (FruitContext) ec.getContext(); + fruitContext.addFruitShell(fruitShell); + } + } + + +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/PackageTest.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/PackageTest.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,23 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework for Java. + * + * Copyright (C) 2000-2006, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ +package ch.qos.logback.core.joran.replay; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class PackageTest extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTestSuite(FruitConfigurationTest.class); + return suite; + } +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/SimpleConfigurator.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/SimpleConfigurator.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,49 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework. + * + * Copyright (C) 1999-2006, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ +package ch.qos.logback.core.joran.replay; + +import java.util.HashMap; + +import ch.qos.logback.core.joran.GenericConfigurator; +import ch.qos.logback.core.joran.action.Action; +import ch.qos.logback.core.joran.action.NestedComponentIA; +import ch.qos.logback.core.joran.action.NestedSimplePropertyIA; +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 SimpleConfigurator extends GenericConfigurator { + + HashMap<Pattern, Action> rulesMap; + + public SimpleConfigurator(HashMap<Pattern, Action> rules) { + this.rulesMap = rules; + } + + @Override + protected void addImplicitRules(Interpreter interpreter) { + NestedComponentIA nestedIA = new NestedComponentIA(); + nestedIA.setContext(context); + interpreter.addImplicitAction(nestedIA); + + NestedSimplePropertyIA nestedSimpleIA = new NestedSimplePropertyIA(); + nestedIA.setContext(context); + interpreter.addImplicitAction(nestedSimpleIA); + } + + @Override + protected void addInstanceRules(RuleStore rs) { + for(Pattern pattern : rulesMap.keySet()) { + Action action = rulesMap.get(pattern); + rs.addRule(pattern, action); + } + } + +} Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/WeightytFruit.java ============================================================================== --- (empty file) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/replay/WeightytFruit.java Thu Oct 19 15:45:50 2006 @@ -0,0 +1,16 @@ +package ch.qos.logback.core.joran.replay; + +public class WeightytFruit extends Fruit { + + double weight; + + public double getWeight() { + return weight; + } + + public void setWeight(double weight) { + this.weight = weight; + } + + +} Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java Thu Oct 19 15:45:50 2006 @@ -13,7 +13,6 @@ import ch.qos.logback.core.joran.spi.Pattern; import junit.framework.TestCase; - /** * Test pattern manipulation code. * @@ -22,6 +21,7 @@ public class PatternTest extends TestCase { /** * Constructor for PatternTestCase. + * * @param name */ public PatternTest(String name) { @@ -85,6 +85,67 @@ assertEquals("a", p.get(0)); assertEquals("b", p.get(1)); } + + + // test tail matching + public void testTailMatch() { + { + Pattern p = new Pattern("/a/b"); + Pattern rulePattern = new Pattern("*"); + assertEquals(0, p.getTailMatchLength(rulePattern)); + } + + { + Pattern p = new Pattern("/a"); + Pattern rulePattern = new Pattern("*/a"); + assertEquals(1, p.getTailMatchLength(rulePattern)); + } + + { + Pattern p = new Pattern("/a/b"); + Pattern rulePattern = new Pattern("*/b"); + assertEquals(1, p.getTailMatchLength(rulePattern)); + } + + + { + Pattern p = new Pattern("/a/b/c"); + Pattern rulePattern = new Pattern("*/b/c"); + assertEquals(2, p.getTailMatchLength(rulePattern)); + } + } + // test prefix matching + public void testPrefixMatch() { + { + Pattern p = new Pattern("/a/b"); + Pattern rulePattern = new Pattern("/x/*"); + assertEquals(0, p.getPrefixMatchLength(rulePattern)); + } + + { + Pattern p = new Pattern("/a"); + Pattern rulePattern = new Pattern("/x/*"); + assertEquals(0, p.getPrefixMatchLength(rulePattern)); + } + + { + Pattern p = new Pattern("/a/b"); + Pattern rulePattern = new Pattern("/a/*"); + assertEquals(2, p.getPrefixMatchLength(rulePattern)); + } + + { + Pattern p = new Pattern("/a/b"); + Pattern rulePattern = new Pattern("/a/b/*"); + assertEquals(2, p.getPrefixMatchLength(rulePattern)); + } + + { + Pattern p = new Pattern("/a/b"); + Pattern rulePattern = new Pattern("/*"); + assertEquals(1, p.getPrefixMatchLength(rulePattern)); + } + } } Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java ============================================================================== --- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java Thu Oct 19 15:45:50 2006 @@ -10,22 +10,14 @@ package ch.qos.logback.core.joran.spi; +import java.util.List; + import junit.framework.TestCase; -import org.w3c.dom.Document; import org.xml.sax.Attributes; import ch.qos.logback.core.ContextBase; import ch.qos.logback.core.joran.action.Action; -import ch.qos.logback.core.joran.spi.ExecutionContext; -import ch.qos.logback.core.joran.spi.Pattern; -import ch.qos.logback.core.joran.spi.SimpleRuleStore; - - -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; /** * @@ -58,7 +50,7 @@ assertEquals(1, r.size()); if (!(r.get(0) instanceof XAction)) { - fail("Wring type"); + fail("Wrong type"); } srs = new SimpleRuleStore(new ContextBase()); @@ -91,7 +83,7 @@ assertEquals(1, r.size()); if (!(r.get(0) instanceof XAction)) { - fail("Wring type"); + fail("Wrong type"); } } @@ -107,7 +99,7 @@ assertEquals(1, r.size()); if (!(r.get(0) instanceof YAction)) { - fail("Wring type"); + fail("Wrong type"); } } @@ -124,19 +116,25 @@ assertEquals(1, r.size()); if (!(r.get(0) instanceof ZAction)) { - fail("Wring type"); + fail("Wrong type"); } } + + public void testSuffix() throws Exception { + SimpleRuleStore srs = new SimpleRuleStore(new ContextBase()); + srs.addRule(new Pattern("a"), new XAction()); + srs.addRule(new Pattern("a/*"), new YAction()); - Document getW3Document(String file) throws Exception { - DocumentBuilderFactory dbf = null; - dbf = DocumentBuilderFactory.newInstance(); + List r = srs.matchActions(new Pattern("a/b")); + assertNotNull(r); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + assertEquals(1, r.size()); - // inputSource.setSystemId("dummy://log4j.dtd"); - return docBuilder.parse(file); + if (!(r.get(0) instanceof YAction)) { + fail("Wrong type"); + } } + class XAction extends Action { public void begin(ExecutionContext ec, String name, Attributes attributes) { Copied: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/pattern/PackageTest.java (from r714, /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/pattern/AllTest.java) ============================================================================== --- /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/pattern/AllTest.java (original) +++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/pattern/PackageTest.java Thu Oct 19 15:45:50 2006 @@ -1,14 +1,12 @@ package ch.qos.logback.core.pattern; - - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -public class AllTest extends TestCase { +public class PackageTest extends TestCase { - public static Test suite() { + public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(ch.qos.logback.core.pattern.parser.PackageTest.suite()); return suite;
participants (1)
-
noreply.ceki@qos.ch