[logback-dev] svn commit: r2426 - 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 test/java/ch/qos/logback/core/joran test/java/ch/qos/logback/core/joran/spi

noreply.ceki at qos.ch noreply.ceki at qos.ch
Sun Aug 9 13:54:23 CEST 2009


Author: ceki
Date: Sun Aug  9 13:54:23 2009
New Revision: 2426

Added:
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinator.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinatorTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleRuleStoreTest.java
      - copied, changed from r2425, /logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java
Removed:
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleStoreTest.java
Modified:
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/TimestampAction.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/Pattern.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PatternTest.java

Log:
- Explicit patterns in Joran are now case insensitive. 
  The following config files will be interpreted identically:

First config file:
   
<configuration>
  <logger>...</logger>
</configuration>

Second config file:

<CONFIGURAtion>
  <loGGer>...</loGGer>
</CONFIGURAtion>
  
  This addresses http://jira.qos.ch/browse/LBCORE-76

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java	Sun Aug  9 13:54:23 2009
@@ -25,6 +25,7 @@
 import ch.qos.logback.core.joran.action.ParamAction;
 import ch.qos.logback.core.joran.action.PropertyAction;
 import ch.qos.logback.core.joran.action.StatusListenerAction;
+import ch.qos.logback.core.joran.action.TimestampAction;
 import ch.qos.logback.core.joran.spi.InterpretationContext;
 import ch.qos.logback.core.joran.spi.Interpreter;
 import ch.qos.logback.core.joran.spi.Pattern;
@@ -59,6 +60,9 @@
     rs.addRule(new Pattern("configuration/substitutionProperty"),
         new PropertyAction());
     
+    rs.addRule(new Pattern("configuration/timestamp"),
+        new TimestampAction());
+    
     // the contextProperty pattern is deprecated. It is undocumented
     // and will be dropped in future versions of logback
     rs.addRule(new Pattern("configuration/contextProperty"),

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/Action.java	Sun Aug  9 13:54:23 2009
@@ -35,6 +35,7 @@
 public abstract class Action extends ContextAwareBase {
 
   public static final String NAME_ATTRIBUTE = "name";
+  public static final String KEY_ATTRIBUTE = "key";
   public static final String VALUE_ATTRIBUTE = "value";
   public static final String FILE_ATTRIBUTE = "file";
   public static final String CLASS_ATTRIBUTE = "class";

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/TimestampAction.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/TimestampAction.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/TimestampAction.java	Sun Aug  9 13:54:23 2009
@@ -1,3 +1,12 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ * 
+ * Copyright (C) 2000-2009, 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.action;
 
 import java.text.SimpleDateFormat;
@@ -9,32 +18,43 @@
 import ch.qos.logback.core.joran.spi.InterpretationContext;
 import ch.qos.logback.core.util.OptionHelper;
 
+/**
+ * Given a key and a date-and-time pattern, puts a property to the context, with
+ * the specified key and value equal to the current time in the format
+ * corresponding to the specified date-and-time pattern.
+ * 
+ * @author Ceki G&uuml;lc&uuml;
+ * 
+ */
 public class TimestampAction extends Action {
   static String DATE_PATTERN_ATTRIBUTE = "datePattern";
-  
+
   boolean inError = false;
-  
+
   @Override
-  public void begin(InterpretationContext ec, String name, Attributes attributes) throws ActionException {
-    String nameStr = attributes.getValue(NAME_ATTRIBUTE);
-    if(OptionHelper.isEmpty(nameStr)) {
-      addError("["+NAME_ATTRIBUTE+"] attribute cannot be empty");
+  public void begin(InterpretationContext ec, String name, Attributes attributes)
+      throws ActionException {
+    String keyStr = attributes.getValue(KEY_ATTRIBUTE);
+    if (OptionHelper.isEmpty(keyStr)) {
+      addError("Attrubute named [" + KEY_ATTRIBUTE + "] cannot be empty");
       inError = true;
     }
     String datePatternStr = attributes.getValue(DATE_PATTERN_ATTRIBUTE);
-    if(OptionHelper.isEmpty(datePatternStr)) {
-      addError("["+DATE_PATTERN_ATTRIBUTE+"] attribute cannot be empty");
+    if (OptionHelper.isEmpty(datePatternStr)) {
+      addError("Attribute named [" + DATE_PATTERN_ATTRIBUTE
+          + "] cannot be empty");
       inError = true;
     }
-    
-    if(inError)
+
+    if (inError)
       return;
-    
+
     SimpleDateFormat sdf = new SimpleDateFormat(datePatternStr);
     String val = sdf.format(new Date());
 
-    addInfo("Adding property ["+nameStr+"] with value ["+val+"] to the context");
-    context.putProperty(nameStr, val);
+    addInfo("Adding property to the context with key=\"" + keyStr
+        + "\" and value=\"" + val + "\" to the context");
+    context.putProperty(keyStr, val);
   }
 
   @Override

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	Sun Aug  9 13:54:23 2009
@@ -15,8 +15,8 @@
 /**
  * A pattern is used to designate XML elements in a document.
  * 
- * <p>For more information see 
- *   http://logback.qos.ch/manual/onJoran.html#pattern
+ * <p>For more information see
+ * http://logback.qos.ch/manual/onJoran.html#pattern
  * 
  * @author Ceki G&uuml;lc&uuml;
  */
@@ -127,7 +127,7 @@
       String l = (String) this.partList.get(lSize - i);
       String r = (String) p.partList.get(rSize - i);
 
-      if (l.equals(r)) {
+      if (equalityCheck(l, r)) {
         match++;
       } else {
         break;
@@ -162,8 +162,7 @@
       String l = (String) this.partList.get(i);
       String r = (String) p.partList.get(i);
 
-      // if (l.equals(r) || "*".equals(l) || "*".equals(r)) {
-      if (l.equals(r)) {
+      if (equalityCheck(l, r)) {
         match++;
       } else {
         break;
@@ -173,30 +172,31 @@
     return match;
   }
 
+  private boolean equalityCheck(String x, String y) {
+    return x.equalsIgnoreCase(y);
+  }
+
   @Override
   public boolean equals(Object o) {
-    // System.out.println("in equals:" +this+ " vs. " + o);
     if ((o == null) || !(o instanceof Pattern)) {
       return false;
     }
 
-    // System.out.println("both are Patterns");
     Pattern r = (Pattern) o;
 
     if (r.size() != size()) {
       return false;
     }
 
-    // System.out.println("both are size compatible");
     int len = size();
 
     for (int i = 0; i < len; i++) {
-      if (!(get(i).equals(r.get(i)))) {
+      if (!equalityCheck(get(i), r.get(i))) {
         return false;
       }
     }
 
-    // if everything matches, then the twp patterns are equal
+    // if everything matches, then the two patterns are equal
     return true;
   }
 
@@ -206,9 +206,9 @@
     int len = size();
 
     for (int i = 0; i < len; i++) {
-      hc ^= get(i).hashCode();
-
-      // System.out.println("i = "+i+", hc="+hc);
+      // make Pattern comparisons case insensitive
+      // http://jira.qos.ch/browse/LBCORE-76
+      hc ^= get(i).toLowerCase().hashCode();
     }
 
     return hc;

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/TrivialConfiguratorTest.java	Sun Aug  9 13:54:23 2009
@@ -42,7 +42,8 @@
 
   public void doTest(String filename) throws Exception {
 
-    rulesMap.put(new Pattern("x/inc"), new IncAction());
+    // rule store is case insensitve
+    rulesMap.put(new Pattern("x/INC"), new IncAction());
 
     TrivialConfigurator gc = new TrivialConfigurator(rulesMap);
 
@@ -50,7 +51,7 @@
     gc.doConfigure(CoreTestConstants.TEST_DIR_PREFIX + "input/joran/"
         + filename);
   }
-
+ 
   @Test
   public void smoke() throws Exception {
     int oldBeginCount = IncAction.beginCount;

Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinator.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinator.java	Sun Aug  9 13:54:23 2009
@@ -0,0 +1,99 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ * 
+ * Copyright (C) 2000-2009, 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.spi;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CaseCombinator {
+
+
+  List<String> combinations(String in) {
+    int length = in.length();
+    List<String> permutationsList = new ArrayList<String>();
+
+    int totalCombinations = computeTotalNumerOfCombinations(in, length);
+
+    for (int j = 0; j < totalCombinations; j++) {
+      StringBuilder newCombination = new StringBuilder();
+      int pos = 0;
+      for (int i = 0; i < length; i++) {
+        char c = in.charAt(i);
+        if (isEnglishLetter(c)) {
+          c = permute(c, j, pos);
+          pos++;
+        }
+        newCombination.append(c);
+      }
+      permutationsList.add(newCombination.toString());
+    }
+    return permutationsList;
+
+  }
+
+  private char permute(char c, int permutation, int position) {
+    int mask = 1 << position;
+    boolean shouldBeInUpperCase = (permutation & mask) != 0;
+    boolean isEffectivelyUpperCase = isUpperCase(c);
+    if (shouldBeInUpperCase && !isEffectivelyUpperCase)
+      return toUpperCase(c);
+    if (!shouldBeInUpperCase && isEffectivelyUpperCase)
+      return toLowerCase(c);
+    return c;
+  }
+
+  private int computeTotalNumerOfCombinations(String in, int length) {
+    int count = 0;
+    for (int i = 0; i < length; i++) {
+      char c = in.charAt(i);
+      if (isEnglishLetter(c))
+        count++;
+    }
+    // return 2^count (2 to the power of count)
+    return (1 << count);
+  }
+
+  private char toUpperCase(char c) {
+    if ('A' <= c && c <= 'Z') {
+      return c;
+    }
+    if ('a' <= c && c <= 'z') {
+      int ci = c;
+      return (char) (ci + 'A' - 'a');
+    }
+    // code should never reach this point
+    return c;
+  }
+
+  private char toLowerCase(char c) {
+    if ('a' <= c && c <= 'z') {
+      return c;
+    }
+    if ('A' <= c && c <= 'Z') {
+      int ci = c;
+      return (char) (ci + 'a' - 'A');
+    }
+    // code should never reach this point
+    return c;
+  }
+
+  private boolean isEnglishLetter(char c) {
+    if ('a' <= c && c <= 'z')
+      return true;
+
+    if ('A' <= c && c <= 'Z')
+      return true;
+    return false;
+  }
+
+  private boolean isUpperCase(char c) {
+    return ('A' <= c && c <= 'Z');
+  }
+}

Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinatorTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/CaseCombinatorTest.java	Sun Aug  9 13:54:23 2009
@@ -0,0 +1,49 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ * 
+ * Copyright (C) 2000-2009, 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.spi;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+
+
+public class CaseCombinatorTest {
+
+  CaseCombinator p = new CaseCombinator();
+  
+  
+  @Test
+  public void smoke() {
+    CaseCombinator p = new CaseCombinator();
+     
+    List<String> result = p.combinations("a-B=");
+    
+    List<String> witness = new ArrayList<String>();
+    witness.add("a-b=");
+    witness.add("A-b=");
+    witness.add("a-B=");
+    witness.add("A-B=");
+    assertEquals(witness, result);
+  }
+  
+  @Test
+  public void other() {
+    List<String> result = p.combinations("aBCd");
+    assertEquals(16, result.size());
+    Set<String> witness = new HashSet<String>(result);
+    // check that there are no duplicates
+    assertEquals(16, witness.size());
+  }
+}

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PackageTest.java	Sun Aug  9 13:54:23 2009
@@ -14,8 +14,8 @@
 import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
- at SuiteClasses( { PatternTest.class, SimpleStoreTest.class,
+ at SuiteClasses( { PatternTest.class, SimpleRuleStoreTest.class,
     PropertySetterTest.class, NoAutoStartUtilTest.class,
-    DefaultNestedComponentRegistryTest.class })
+    DefaultNestedComponentRegistryTest.class, CaseCombinatorTest.class })
 public class PackageTest {
 }

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	Sun Aug  9 13:54:23 2009
@@ -94,6 +94,19 @@
       Pattern rulePattern = new Pattern("*/a");
       assertEquals(1, p.getTailMatchLength(rulePattern));
     }
+
+    {
+      Pattern p = new Pattern("/A");
+      Pattern rulePattern = new Pattern("*/a");
+      assertEquals(1, p.getTailMatchLength(rulePattern));
+    }
+    
+    {
+      Pattern p = new Pattern("/a");
+      Pattern rulePattern = new Pattern("*/A");
+      assertEquals(1, p.getTailMatchLength(rulePattern));
+    }
+    
     
     {
       Pattern p = new Pattern("/a/b");
@@ -101,6 +114,11 @@
       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");
@@ -129,6 +147,18 @@
       Pattern rulePattern = new Pattern("/a/*");
       assertEquals(1, p.getPrefixMatchLength(rulePattern));
     }
+
+    {
+      Pattern p = new Pattern("/a/b");
+      Pattern rulePattern = new Pattern("/A/*");
+      assertEquals(1, p.getPrefixMatchLength(rulePattern));
+    }
+    
+    {
+      Pattern p = new Pattern("/A/b");
+      Pattern rulePattern = new Pattern("/a/*");
+      assertEquals(1, p.getPrefixMatchLength(rulePattern));
+    }
     
     {
       Pattern p = new Pattern("/a/b");

Copied: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/SimpleRuleStoreTest.java (from r2425, /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/SimpleRuleStoreTest.java	Sun Aug  9 13:54:23 2009
@@ -1,7 +1,7 @@
 /**
  * Logback: the generic, reliable, fast and flexible logging framework.
  * 
- * Copyright (C) 2000-2008, QOS.ch
+ * Copyright (C) 2000-2009, 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
@@ -24,186 +24,203 @@
 import ch.qos.logback.core.joran.action.Action;
 
 /**
+ * Test SimpleRuleStore for various explicit rule combinations.
  * 
- * @author Ceki Gulcu
+ * We also test that explicit patterns are case sensitive.
+ * 
+ * @author Ceki G&uuml;lc&uuml;
  */
-public class SimpleStoreTest  {
+public class SimpleRuleStoreTest {
 
+  SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
+  CaseCombinator cc = new CaseCombinator();
+  
   @Test
-  public void test1() throws Exception {
-    // Document doc = getW3Document("file:input/joran/parser1.xml");
-    SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
+  public void smoke() throws Exception {
     srs.addRule(new Pattern("a/b"), new XAction());
 
-    List r = srs.matchActions(new Pattern("a/b"));
-    assertNotNull(r);
-    assertEquals(1, r.size());
-
-    if (!(r.get(0) instanceof XAction)) {
-      fail("Wrong type");
+    // test for all possible case combinations of "a/b"
+    for (String s : cc.combinations("a/b")) {
+       List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+      assertEquals(1, r.size());
+
+      if (!(r.get(0) instanceof XAction)) {
+        fail("Wrong type");
+      }
     }
+  }
 
-    srs = new SimpleRuleStore(new ContextBase());
+  @Test
+  public void smokeII() throws Exception {
     srs.addRule(new Pattern("a/b"), new XAction());
     srs.addRule(new Pattern("a/b"), new YAction());
 
-    r = srs.matchActions(new Pattern("a/b"));
-    assertNotNull(r);
-    assertEquals(2, r.size());
-
-    if (!(r.get(0) instanceof XAction)) {
-      fail("Wrong type");
-    }
-
-    if (!(r.get(1) instanceof YAction)) {
-      fail("Wrong type");
+    for (String s : cc.combinations("a/b")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+      assertEquals(2, r.size());
+
+      if (!(r.get(0) instanceof XAction)) {
+        fail("Wrong type");
+      }
+
+      if (!(r.get(1) instanceof YAction)) {
+        fail("Wrong type");
+      }
     }
-
   }
 
   @Test
   public void testSlashSuffix() throws Exception {
-    SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
     Pattern pa = new Pattern("a/");
     srs.addRule(pa, new XAction());
-    
-    List r = srs.matchActions(new Pattern("a"));
-    assertNotNull(r);
-    assertEquals(1, r.size());
 
-    if (!(r.get(0) instanceof XAction)) {
-      fail("Wrong type");
+    for (String s : cc.combinations("a")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+      assertEquals(1, r.size());
+
+      if (!(r.get(0) instanceof XAction)) {
+        fail("Wrong type");
+      }
     }
 
- 
   }
-  
+
   @Test
   public void testTail1() throws Exception {
-    SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
     srs.addRule(new Pattern("*/b"), new XAction());
 
-    List r = srs.matchActions(new Pattern("a/b"));
-    assertNotNull(r);
-
-    assertEquals(1, r.size());
-
-    if (!(r.get(0) instanceof XAction)) {
-      fail("Wrong type");
+    for (String s : cc.combinations("a/b")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+
+      assertEquals(1, r.size());
+
+      if (!(r.get(0) instanceof XAction)) {
+        fail("Wrong type");
+      }
     }
   }
 
-  
   @Test
   public void testTail2() throws Exception {
     SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
     srs.addRule(new Pattern("*/c"), new XAction());
 
-    List r = srs.matchActions(new Pattern("a/b/c"));
-    assertNotNull(r);
-
-    assertEquals(1, r.size());
-
-    if (!(r.get(0) instanceof XAction)) {
-      fail("Wrong type");
+    for (String s : cc.combinations("a/b/c")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+
+      assertEquals(1, r.size());
+
+      if (!(r.get(0) instanceof XAction)) {
+        fail("Wrong type");
+      }
     }
   }
-  
+
   @Test
   public void testTail3() throws Exception {
-    SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
     srs.addRule(new Pattern("*/b"), new XAction());
     srs.addRule(new Pattern("*/a/b"), new YAction());
 
-    List r = srs.matchActions(new Pattern("a/b"));
-    assertNotNull(r);
-
-    // System.out.println("restulg list is: "+r);
-    assertEquals(1, r.size());
-
-    if (!(r.get(0) instanceof YAction)) {
-      fail("Wrong type");
+    for (String s : cc.combinations("a/b")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+      assertEquals(1, r.size());
+
+      if (!(r.get(0) instanceof YAction)) {
+        fail("Wrong type");
+      }
     }
   }
 
   @Test
   public void testTail4() throws Exception {
-    SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
     srs.addRule(new Pattern("*/b"), new XAction());
     srs.addRule(new Pattern("*/a/b"), new YAction());
     srs.addRule(new Pattern("a/b"), new ZAction());
 
-    List r = srs.matchActions(new Pattern("a/b"));
-    assertNotNull(r);
-
-    // System.out.println("result list is: "+r);
-    assertEquals(1, r.size());
-
-    if (!(r.get(0) instanceof ZAction)) {
-      fail("Wrong type");
+    for (String s : cc.combinations("a/b")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+      assertEquals(1, r.size());
+
+      if (!(r.get(0) instanceof ZAction)) {
+        fail("Wrong type");
+      }
     }
   }
-  
+
   @Test
   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());
 
-    List r = srs.matchActions(new Pattern("a/b"));
-    assertNotNull(r);
-    assertEquals(1, r.size());
-    assertTrue(r.get(0) instanceof YAction);
+    for (String s : cc.combinations("a/b")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+      assertEquals(1, r.size());
+      assertTrue(r.get(0) instanceof YAction);
+    }
   }
-  
+
   @Test
   public void testDeepSuffix() throws Exception {
-    SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
     srs.addRule(new Pattern("a"), new XAction(1));
     srs.addRule(new Pattern("a/b/*"), new XAction(2));
 
-    List r = srs.matchActions(new Pattern("a/other"));
-    assertNull(r);
+    for (String s : cc.combinations("a/other")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNull(r);
+    }
   }
 
   @Test
   public void testPrefixSuffixInteraction1() throws Exception {
-    SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
     srs.addRule(new Pattern("a"), new ZAction());
     srs.addRule(new Pattern("a/*"), new YAction());
     srs.addRule(new Pattern("*/a/b"), new XAction(3));
 
-    List r = srs.matchActions(new Pattern("a/b"));
-    assertNotNull(r);
-
-    assertEquals(1, r.size());
-    
-    assertTrue(r.get(0) instanceof XAction);
-    XAction xaction = (XAction) r.get(0);
-    assertEquals(3, xaction.id);
+    for (String s : cc.combinations("a/b")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNotNull(r);
+
+      assertEquals(1, r.size());
+
+      assertTrue(r.get(0) instanceof XAction);
+      XAction xaction = (XAction) r.get(0);
+      assertEquals(3, xaction.id);
+    }
   }
 
   @Test
   public void testPrefixSuffixInteraction2() throws Exception {
-    SimpleRuleStore srs = new SimpleRuleStore(new ContextBase());
-    srs.addRule(new Pattern("testGroup"), new XAction());
-    srs.addRule(new Pattern("testGroup/testShell"), new YAction());
-    srs.addRule(new Pattern("testGroup/testShell/test"), new ZAction());
-    srs.addRule(new Pattern("testGroup/testShell/test/*"), new XAction(9));
-    
-    List r = srs.matchActions(new Pattern("testGroup/testShell/toto"));
-    assertNull(r);
+    srs.addRule(new Pattern("tG"), new XAction());
+    srs.addRule(new Pattern("tG/tS"), new YAction());
+    srs.addRule(new Pattern("tG/tS/test"), new ZAction());
+    srs.addRule(new Pattern("tG/tS/test/*"), new XAction(9));
+
+    for (String s : cc.combinations("tG/tS/toto")) {
+      List r = srs.matchActions(new Pattern(s));
+      assertNull(r);
+    }
   }
-  
+
   class XAction extends Action {
     int id = 0;
+
     XAction() {
     }
+
     XAction(int id) {
       this.id = id;
     }
 
-    public void begin(InterpretationContext ec, String name, Attributes attributes) {
+    public void begin(InterpretationContext ec, String name,
+        Attributes attributes) {
     }
 
     public void end(InterpretationContext ec, String name) {
@@ -211,14 +228,15 @@
 
     public void finish(InterpretationContext ec) {
     }
-    
+
     public String toString() {
-     return "XAction("+id+")";
-    }    
+      return "XAction(" + id + ")";
+    }
   }
 
   class YAction extends Action {
-    public void begin(InterpretationContext ec, String name, Attributes attributes) {
+    public void begin(InterpretationContext ec, String name,
+        Attributes attributes) {
     }
 
     public void end(InterpretationContext ec, String name) {
@@ -229,7 +247,8 @@
   }
 
   class ZAction extends Action {
-    public void begin(InterpretationContext ec, String name, Attributes attributes) {
+    public void begin(InterpretationContext ec, String name,
+        Attributes attributes) {
     }
 
     public void end(InterpretationContext ec, String name) {


More information about the logback-dev mailing list