[logback-dev] svn commit: r1628 - in logback/trunk/logback-core/src: main/java/ch/qos/logback/core/joran/action main/java/ch/qos/logback/core/util test/input/joran/inclusion test/java/ch/qos/logback/core/joran/action

noreply.ceki at qos.ch noreply.ceki at qos.ch
Tue Mar 4 17:38:28 CET 2008


Author: ceki
Date: Tue Mar  4 17:38:27 2008
New Revision: 1628

Added:
   logback/trunk/logback-core/src/test/input/joran/inclusion/multiIncludeByFile.xml
   logback/trunk/logback-core/src/test/input/joran/inclusion/second.xml
   logback/trunk/logback-core/src/test/input/joran/inclusion/subByFile.xml
   logback/trunk/logback-core/src/test/input/joran/inclusion/topByFile.xml
      - copied, changed from r1622, /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByFile.xml
   logback/trunk/logback-core/src/test/input/joran/inclusion/topByResource.xml
      - copied, changed from r1622, /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByResource.xml
   logback/trunk/logback-core/src/test/input/joran/inclusion/topByUrl.xml
      - copied, changed from r1622, /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByUrl.xml
Removed:
   logback/trunk/logback-core/src/test/input/joran/inclusion/includeByFile.xml
   logback/trunk/logback-core/src/test/input/joran/inclusion/includeByResource.xml
   logback/trunk/logback-core/src/test/input/joran/inclusion/includeByUrl.xml
Modified:
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncAction.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java

Log:
- fixing bug #129 see also http://bugzilla.qos.ch/show_bug.cgi?id=129\

- refactored the IncludeAction for clarity
- IncludeActionTest has been enhanced to check for bug 129

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/IncludeAction.java	Tue Mar  4 17:38:27 2008
@@ -14,10 +14,10 @@
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.List;
 
 import org.xml.sax.Attributes;
 
-import ch.qos.logback.core.joran.action.Action;
 import ch.qos.logback.core.joran.event.SaxEvent;
 import ch.qos.logback.core.joran.event.SaxEventRecorder;
 import ch.qos.logback.core.joran.spi.ActionException;
@@ -32,41 +32,27 @@
   private static final String FILE_ATTR = "file";
   private static final String URL_ATTR = "url";
   private static final String RESOURCE_ATTR = "resource";
-  private SaxEventRecorder recorder = new SaxEventRecorder();;
+  
+
+  private String attributeInUse;
 
   @Override
   public void begin(InterpretationContext ec, String name, Attributes attributes)
       throws ActionException {
 
-    String fileAttribute = attributes.getValue(FILE_ATTR);
-    String urlAttribute = attributes.getValue(URL_ATTR);
-    String resourceAttribute = attributes.getValue(RESOURCE_ATTR);
-    String attributeInUse = null;
+    SaxEventRecorder recorder = new SaxEventRecorder();
+    
+    this.attributeInUse = null;
 
-    if(!checkAttributes(fileAttribute, urlAttribute, resourceAttribute)) {
+    if (!checkAttributes(attributes)) {
       return;
     }
 
-    InputStream in = null;
-
-    if (!OptionHelper.isEmpty(fileAttribute)) {
-      attributeInUse = ec.subst(fileAttribute);
-      in = getInputStreamByFilePath(attributeInUse);
-    }
-
-    if (!OptionHelper.isEmpty(urlAttribute)) {
-      attributeInUse = ec.subst(urlAttribute);
-      in = getInputStreamByUrl(attributeInUse);
-    }
-
-    if (!OptionHelper.isEmpty(resourceAttribute)) {
-      attributeInUse = ec.subst(resourceAttribute);
-      in = getInputStreamByResource(attributeInUse);
-    }
+    InputStream in = getInputStream(ec, attributes);
 
     try {
       if (in != null) {
-        parseAndRecord(in);
+        parseAndRecord(in, recorder);
         in.close();
       }
     } catch (JoranException e) {
@@ -75,27 +61,17 @@
       // called if in.close did not work
     }
 
-    if (recorder.saxEventList.size() == 0) {
-      return;
-    }
-
-    // Let's remove the two <included> events before
-    // adding the events to the player.
-    SaxEvent first = recorder.saxEventList.get(0);
-    if (first != null && first.qName.equalsIgnoreCase(INCLUDED_TAG)) {
-      recorder.saxEventList.remove(0);
-    }
-
-    SaxEvent last = recorder.saxEventList.get(recorder.saxEventList.size() - 1);
-    if (last != null && last.qName.equalsIgnoreCase(INCLUDED_TAG)) {
-      recorder.saxEventList.remove(recorder.saxEventList.size() - 1);
-    }
-
+    // remove the <included> tag from the beginning and </included> from the end
+    trimHeadAndTail(recorder);
+    
     ec.getJoranInterpreter().addEvents(recorder.saxEventList);
   }
 
-  private boolean checkAttributes(String fileAttribute,
-      String urlAttribute, String resourceAttribute) {
+  private boolean checkAttributes(Attributes attributes) {
+    String fileAttribute = attributes.getValue(FILE_ATTR);
+    String urlAttribute = attributes.getValue(URL_ATTR);
+    String resourceAttribute = attributes.getValue(RESOURCE_ATTR);
+
     int count = 0;
 
     if (!OptionHelper.isEmpty(fileAttribute)) {
@@ -117,7 +93,8 @@
     } else if (count == 1) {
       return true;
     }
-    throw new IllegalStateException("Count value ["+count+"] is not expected");
+    throw new IllegalStateException("Count value [" + count
+        + "] is not expected");
   }
 
   private InputStream getInputStreamByFilePath(String pathToFile) {
@@ -163,7 +140,51 @@
     return openURL(url);
   }
 
-  private void parseAndRecord(InputStream inputSource) throws JoranException {
+  InputStream getInputStream(InterpretationContext ec, Attributes attributes) {
+    String fileAttribute = attributes.getValue(FILE_ATTR);
+    String urlAttribute = attributes.getValue(URL_ATTR);
+    String resourceAttribute = attributes.getValue(RESOURCE_ATTR);
+
+    if (!OptionHelper.isEmpty(fileAttribute)) {
+      attributeInUse = ec.subst(fileAttribute);
+      return getInputStreamByFilePath(attributeInUse);
+    }
+
+    if (!OptionHelper.isEmpty(urlAttribute)) {
+      attributeInUse = ec.subst(urlAttribute);
+      return getInputStreamByUrl(attributeInUse);
+    }
+
+    if (!OptionHelper.isEmpty(resourceAttribute)) {
+      attributeInUse = ec.subst(resourceAttribute);
+      return getInputStreamByResource(attributeInUse);
+    }
+    // given previous checkAttributes() check we cannot reach this line
+    throw new IllegalStateException("A input stream should have been returned");
+  }
+
+  private void trimHeadAndTail(SaxEventRecorder recorder) {
+    // Let's remove the two <included> events before
+    // adding the events to the player.
+    
+    List<SaxEvent> saxEventList = recorder.saxEventList;
+    
+    if (saxEventList.size() == 0) {
+      return;
+    }
+    
+    SaxEvent first = saxEventList.get(0);
+    if (first != null && first.qName.equalsIgnoreCase(INCLUDED_TAG)) {
+      saxEventList.remove(0);
+    }
+
+    SaxEvent last = saxEventList.get(recorder.saxEventList.size() - 1);
+    if (last != null && last.qName.equalsIgnoreCase(INCLUDED_TAG)) {
+      saxEventList.remove(recorder.saxEventList.size() - 1);
+    }
+  }
+
+  private void parseAndRecord(InputStream inputSource, SaxEventRecorder recorder) throws JoranException {
     recorder.setContext(context);
     recorder.recordEvents(inputSource);
   }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java	Tue Mar  4 17:38:27 2008
@@ -90,16 +90,16 @@
    * <p>
    * If no value could be found for the specified key in the context map, then 
    * the system properties are searched, if that fails, then substitution defaults 
-   * to the empty string.
+   * to appending "_IS_UNDEFINED" to the key name.
    * 
    * <p>
-   * For example, if system properties contains no value for the key
+   * For example, if not the context not the system properties contains no value for the key
    * "inexistentKey", then the call
    * 
    * <pre>
    * String s = OptionConverter.subsVars(
    *     &quot;Value of inexistentKey is [${inexistentKey}]&quot;, context);</pre>
-   * will set <code>s</code> to "Value of inexistentKey is []".
+   * will set <code>s</code> to "Value of inexistentKey is [inexistentKey_IS_UNDEFINED]".
    * 
    * <p>
    * Nevertheless, it is possible to specify a default substitution value using
@@ -108,13 +108,14 @@
    * <pre>
    * String s = OptionConverter.subsVars(&quot;Value of key is [${key2:-val2}]&quot;, context);</pre>
    * will set <code>s</code> to "Value of key is [val2]" even if the "key2"
-   * property is unset.
+   * property is not set.
    * 
    * <p>
    * An {@link java.lang.IllegalArgumentException} is thrown if <code>val</code>
    * contains a start delimeter "${" which is not balanced by a stop delimeter
    * "}".
    * </p>
+
    * 
    * @param val
    *          The string on which variable substitution is performed.

Added: logback/trunk/logback-core/src/test/input/joran/inclusion/multiIncludeByFile.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/input/joran/inclusion/multiIncludeByFile.xml	Tue Mar  4 17:38:27 2008
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE x>
+
+<x>
+  <include file="${includeKey}" />
+  <include file="${secondFileKey}" />
+</x>

Added: logback/trunk/logback-core/src/test/input/joran/inclusion/second.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/input/joran/inclusion/second.xml	Tue Mar  4 17:38:27 2008
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE included>
+
+<included>
+
+  <inc increment="1"/>
+  
+</included>
\ No newline at end of file

Added: logback/trunk/logback-core/src/test/input/joran/inclusion/subByFile.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/input/joran/inclusion/subByFile.xml	Tue Mar  4 17:38:27 2008
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE included>
+
+<included>
+  <include file="${includeKey}" />
+</<included>

Copied: logback/trunk/logback-core/src/test/input/joran/inclusion/topByFile.xml (from r1622, /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByFile.xml)
==============================================================================
--- /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByFile.xml	(original)
+++ logback/trunk/logback-core/src/test/input/joran/inclusion/topByFile.xml	Tue Mar  4 17:38:27 2008
@@ -2,5 +2,5 @@
 <!DOCTYPE x>
 
 <x>
-  <include file="${testing}" />
+  <include file="${includeKey}" />
 </x>

Copied: logback/trunk/logback-core/src/test/input/joran/inclusion/topByResource.xml (from r1622, /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByResource.xml)
==============================================================================
--- /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByResource.xml	(original)
+++ logback/trunk/logback-core/src/test/input/joran/inclusion/topByResource.xml	Tue Mar  4 17:38:27 2008
@@ -3,6 +3,6 @@
 
 <x>
 
-  <include resource="${testing}" />
+  <include resource="${includeKey}" />
 
 </x>

Copied: logback/trunk/logback-core/src/test/input/joran/inclusion/topByUrl.xml (from r1622, /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByUrl.xml)
==============================================================================
--- /logback/trunk/logback-core/src/test/input/joran/inclusion/includeByUrl.xml	(original)
+++ logback/trunk/logback-core/src/test/input/joran/inclusion/topByUrl.xml	Tue Mar  4 17:38:27 2008
@@ -2,5 +2,5 @@
 <!DOCTYPE x>
 
 <x>
-  <include url="${testing}" />
+  <include url="${includeKey}" />
 </x>

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncAction.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncAction.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncAction.java	Tue Mar  4 17:38:27 2008
@@ -24,6 +24,11 @@
   static public int  endCount;
   static public int  errorCount;
 
+  static public void reset() {
+    beginCount = 0;
+    endCount = 0;
+    errorCount = 0;
+  }
   /**
    * Instantiates an layout of the given class and sets its name.
    *

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/action/IncludeActionTest.java	Tue Mar  4 17:38:27 2008
@@ -24,20 +24,34 @@
 
 public class IncludeActionTest  {
 
-  final static String FILE_KEY = "testing";
-
+  final static String INCLUDE_KEY = "includeKey";
+  final static String SUB_FILE_KEY = "subFileKey";
+  final static String SECOND_FILE_KEY = "secondFileKey";
+  
+  
   Context context = new ContextBase();
   TrivialConfigurator tc;
 
   static final String INCLUSION_DIR_PREFIX = "src/test/input/joran/inclusion/";
 
-  static final String INCLUDE_BY_FILE = INCLUSION_DIR_PREFIX
-      + "includeByFile.xml";
-  static final String INCLUDE_BY_URL = INCLUSION_DIR_PREFIX
-      + "includeByUrl.xml";
+  static final String TOP_BY_FILE = INCLUSION_DIR_PREFIX
+      + "topByFile.xml";
+  
+  static final String SUB_FILE = INCLUSION_DIR_PREFIX
+  + "subByFile.xml";
+  
+  static final String MULTI_INCLUDE_BY_FILE = INCLUSION_DIR_PREFIX
+  + "multiIncludeByFile.xml";
+  
+  static final String SECOND_FILE = INCLUSION_DIR_PREFIX
+  + "second.xml";
+  
+  
+  static final String TOP_BY_URL = INCLUSION_DIR_PREFIX
+      + "topByUrl.xml";
 
   static final String INCLUDE_BY_RESOURCE = INCLUSION_DIR_PREFIX
-      + "includeByResource.xml";
+      + "topByResource.xml";
 
   static final String INCLUDED_FILE = INCLUSION_DIR_PREFIX + "included.xml";
   static final String URL_TO_INCLUDE = "file:./" + INCLUDED_FILE;
@@ -66,19 +80,20 @@
   @After
   public void tearDown() throws Exception {
     context = null;
-    System.clearProperty(FILE_KEY);
+    System.clearProperty(INCLUDE_KEY);
+    IncAction.reset();
   }
 
   @Test
   public void basicFile() throws JoranException {
-    System.setProperty(FILE_KEY, INCLUDED_FILE);
-    tc.doConfigure(INCLUDE_BY_FILE);
+    System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
+    tc.doConfigure(TOP_BY_FILE);
     verifyConfig(2);
   }
 
   @Test
   public void basicResource() throws JoranException {
-    System.setProperty(FILE_KEY, INCLUDED_AS_RESOURCE);
+    System.setProperty(INCLUDE_KEY, INCLUDED_AS_RESOURCE);
     tc.doConfigure(INCLUDE_BY_RESOURCE);
     StatusPrinter.print(context);
     verifyConfig(2);
@@ -86,16 +101,16 @@
 
   @Test
    public void testBasicURL() throws JoranException {
-    System.setProperty(FILE_KEY, URL_TO_INCLUDE);
-    tc.doConfigure(INCLUDE_BY_URL);
+    System.setProperty(INCLUDE_KEY, URL_TO_INCLUDE);
+    tc.doConfigure(TOP_BY_URL);
     StatusPrinter.print(context);
     verifyConfig(2);
   }
 
   @Test
   public void noFileFound() throws JoranException {
-    System.setProperty(FILE_KEY, "toto");
-    tc.doConfigure(INCLUDE_BY_FILE);
+    System.setProperty(INCLUDE_KEY, "toto");
+    tc.doConfigure(TOP_BY_FILE);
     assertEquals(Status.ERROR, context.getStatusManager().getLevel());
     StatusChecker sc = new StatusChecker(context.getStatusManager());
     assertTrue(sc.containsException(FileNotFoundException.class));
@@ -103,8 +118,8 @@
 
   @Test
   public void withCorruptFile() throws JoranException {
-    System.setProperty(FILE_KEY, INVALID);
-    tc.doConfigure(INCLUDE_BY_FILE);
+    System.setProperty(INCLUDE_KEY, INVALID);
+    tc.doConfigure(TOP_BY_FILE);
     assertEquals(Status.ERROR, context.getStatusManager().getLevel());
     StatusChecker sc = new StatusChecker(context.getStatusManager());
     assertTrue(sc.containsException(SAXParseException.class));
@@ -112,22 +127,42 @@
 
   @Test
   public void malformedURL() throws JoranException {
-    System.setProperty(FILE_KEY, "htp://logback.qos.ch");
-    tc.doConfigure(INCLUDE_BY_URL);
+    System.setProperty(INCLUDE_KEY, "htp://logback.qos.ch");
+    tc.doConfigure(TOP_BY_URL);
     assertEquals(Status.ERROR, context.getStatusManager().getLevel());
     StatusChecker sc = new StatusChecker(context.getStatusManager());
     assertTrue(sc.containsException(MalformedURLException.class));
   }
 
   @Test
-  public void testUnknownURL() throws JoranException {
-    System.setProperty(FILE_KEY, "http://logback2345.qos.ch");
-    tc.doConfigure(INCLUDE_BY_URL);
+  public void unknownURL() throws JoranException {
+    System.setProperty(INCLUDE_KEY, "http://logback2345.qos.ch");
+    tc.doConfigure(TOP_BY_URL);
     assertEquals(Status.ERROR, context.getStatusManager().getLevel());
     StatusChecker sc = new StatusChecker(context.getStatusManager());
     assertTrue(sc.containsException(UnknownHostException.class));
   }
 
+  @Test
+  public void nestedInclude() throws JoranException {
+    System.setProperty(SUB_FILE_KEY, INCLUDED_FILE);
+    System.setProperty(INCLUDE_KEY, SECOND_FILE);
+    tc.doConfigure(TOP_BY_FILE);
+    StatusPrinter.print(context);
+    verifyConfig(1);
+
+  }
+  
+  @Test
+  public void multiInclude() throws JoranException {
+    System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
+    System.setProperty(SECOND_FILE_KEY, SECOND_FILE);
+    tc.doConfigure(MULTI_INCLUDE_BY_FILE);
+    verifyConfig(3);
+  }
+  
+
+  
   void verifyConfig(int expected) {
     assertEquals(expected, IncAction.beginCount);
     assertEquals(expected, IncAction.endCount);



More information about the logback-dev mailing list