[logback-dev] svn commit: r2095 - in logback/trunk: logback-access/src/main/java/ch/qos/logback/access/sift logback-access/src/test/input/jetty logback-access/src/test/java/ch/qos/logback/access/sift logback-classic/src/main/java/ch/qos/logback/classic/sift logback-classic/src/test/input/joran/sift logback-classic/src/test/java/ch/qos/logback/classic/sift logback-core/src/main/java/ch/qos/logback/core/joran/action logback-core/src/main/java/ch/qos/logback/core/joran/spi logback-core/src/main/java/ch/qos/logback/core/sift logback-core/src/test/java/ch/qos/logback/core/joran/spi

noreply.ceki at qos.ch noreply.ceki at qos.ch
Mon Dec 22 23:18:36 CET 2008


Author: ceki
Date: Mon Dec 22 23:18:36 2008
New Revision: 2095

Added:
   logback/trunk/logback-access/src/test/input/jetty/siftingFile.xml
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultClass.java
Modified:
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/AccessEventDiscriminator.java
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/SiftAction.java
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
   logback/trunk/logback-access/src/test/input/jetty/sifting.xml
   logback/trunk/logback-access/src/test/java/ch/qos/logback/access/sift/SiftingAppenderTest.java
   logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/MDCBasedDiscriminator.java
   logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java
   logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
   logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml
   logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml
   logback/trunk/logback-classic/src/test/input/joran/sift/unsetDefaultValueProperty.xml
   logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/Discriminator.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java

Log:
- It is now possible to declare a default class for a sub-component as an @annotation.
  Thus, it is no longer necessary to specify the class name as an xml attribute for sub-components
  
- refactoring of sibling appender 

Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/AccessEventDiscriminator.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/AccessEventDiscriminator.java	(original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/AccessEventDiscriminator.java	Mon Dec 22 23:18:36 2008
@@ -32,6 +32,7 @@
   }
 
   String defaultValue;
+  String key;
   FieldName fieldName;
   String optionalKey;
 
@@ -156,5 +157,13 @@
     this.defaultValue = defaultValue;
   }
 
+  public String getKey() {
+    return key;
+  }
+
+  public void setKey(String key) {
+    this.key = key;
+  }
+
   
 }

Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/SiftAction.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/SiftAction.java	(original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/SiftAction.java	Mon Dec 22 23:18:36 2008
@@ -36,7 +36,7 @@
     Object o = ec.peekObject();
     if (o instanceof SiftingAppender) {
       SiftingAppender siftingAppender = (SiftingAppender) o; 
-      AppenderFactory appenderFactory = new AppenderFactory(context, seList, siftingAppender.getKeyName());
+      AppenderFactory appenderFactory = new AppenderFactory(context, seList, siftingAppender.getDiscriminatorKey());
       siftingAppender.setAppenderFactory(appenderFactory);
     }
   }

Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java	(original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java	Mon Dec 22 23:18:36 2008
@@ -10,9 +10,10 @@
 package ch.qos.logback.access.sift;
 
 import ch.qos.logback.access.spi.AccessEvent;
+import ch.qos.logback.core.joran.spi.DefaultClass;
 import ch.qos.logback.core.sift.AppenderTracker;
+import ch.qos.logback.core.sift.Discriminator;
 import ch.qos.logback.core.sift.SiftingAppenderBase;
-import ch.qos.logback.core.util.OptionHelper;
 
 /**
  * This appender can contains other appenders which it can build dynamically
@@ -26,18 +27,9 @@
  */
 public class SiftingAppender extends SiftingAppenderBase<AccessEvent> {
 
-  String keyName;
-
   @Override
   public void start() {
-    int errors = 0;
-    if (OptionHelper.isEmpty(keyName)) {
-      errors++;
-      addError("The \"keyName\" property must be set");
-    }
-    if (errors == 0) {
-      super.start();
-    }
+    super.start();
   }
 
   AppenderTracker<AccessEvent> getAppenderTracker() {
@@ -49,12 +41,9 @@
     return event.getTimeStamp();
   }
 
-  public String getKeyName() {
-    return keyName;
-  }
-
-  public void setKeyName(String keyName) {
-    this.keyName = keyName;
+  @Override
+  @DefaultClass(AccessEventDiscriminator.class)
+  public void setDiscriminator(Discriminator<AccessEvent> discriminator) {
+    super.setDiscriminator(discriminator);
   }
-
 }

Modified: logback/trunk/logback-access/src/test/input/jetty/sifting.xml
==============================================================================
--- logback/trunk/logback-access/src/test/input/jetty/sifting.xml	(original)
+++ logback/trunk/logback-access/src/test/input/jetty/sifting.xml	Mon Dec 22 23:18:36 2008
@@ -1,13 +1,15 @@
 <configuration>
 
-  <appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
-    <KeyName>uri</KeyName>
-    <Discriminator class="ch.qos.logback.access.sift.AccessEventDiscriminator">
+  <appender name="SIFTING"
+    class="ch.qos.logback.access.sift.SiftingAppender">
+
+    <Discriminator>
+      <Key>uri</Key>
       <FieldName>REQUEST_URI</FieldName>
       <DefaultValue>NA</DefaultValue>
     </Discriminator>
     <sift>
-      <appender name="${uri}" class="ch.qos.logback.core.read.ListAppender"/>
+      <appender name="${uri}" class="ch.qos.logback.core.read.ListAppender" />
     </sift>
   </appender>
 

Added: logback/trunk/logback-access/src/test/input/jetty/siftingFile.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/input/jetty/siftingFile.xml	Mon Dec 22 23:18:36 2008
@@ -0,0 +1,16 @@
+<configuration>
+
+  <appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
+    <KeyName>client</KeyName>
+    <Discriminator class="ch.qos.logback.access.sift.AccessEventDiscriminator">
+      <DefaultValue>NA</DefaultValue>
+      <FieldName>REQUEST_URI</FieldName>
+    </Discriminator>
+    <sift>
+      <appender name="file-${client}"
+        class="ch.qos.logback.core.read.ListAppender" />
+    </sift>
+  </appender>
+
+  <appender-ref ref="SIFTING" />
+</configuration>
\ No newline at end of file

Modified: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/sift/SiftingAppenderTest.java
==============================================================================
--- logback/trunk/logback-access/src/test/java/ch/qos/logback/access/sift/SiftingAppenderTest.java	(original)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/sift/SiftingAppenderTest.java	Mon Dec 22 23:18:36 2008
@@ -25,6 +25,7 @@
 import ch.qos.logback.access.spi.Util;
 import ch.qos.logback.core.read.ListAppender;
 import ch.qos.logback.core.testUtil.RandomUtil;
+import ch.qos.logback.core.util.StatusPrinter;
 
 public class SiftingAppenderTest {
   static final String PREFIX = "src/test/input/jetty/";
@@ -51,11 +52,14 @@
     rli.setFileName(PREFIX + "sifting.xml");
     jettyFixture.start();
 
+
+    StatusPrinter.print(rli);
     invokeServer("/");
     invokeServer("/x");
     invokeServer("/x");
     invokeServer("/y");
 
+    
     SiftingAppender siftingAppender = (SiftingAppender) rli
         .getAppender("SIFTING");
     List<String> keyList = siftingAppender.getAppenderTracker().keyList();

Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/MDCBasedDiscriminator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/MDCBasedDiscriminator.java	(original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/MDCBasedDiscriminator.java	Mon Dec 22 23:18:36 2008
@@ -13,21 +13,21 @@
 
 import ch.qos.logback.classic.spi.LoggingEvent;
 import ch.qos.logback.core.sift.Discriminator;
+import ch.qos.logback.core.spi.ContextAwareBase;
+import ch.qos.logback.core.util.OptionHelper;
 
-public class MDCBasedDiscriminator implements Discriminator<LoggingEvent> {
+public class MDCBasedDiscriminator extends ContextAwareBase implements Discriminator<LoggingEvent> {
 
-  final String mdcKey;
-  final String defaultValue;
+  String key;
+  String defaultValue;
 
-  boolean started = true;
+  boolean started = false;
 
-  MDCBasedDiscriminator(String mdcKey, String defaultValue) {
-    this.mdcKey = mdcKey;
-    this.defaultValue = defaultValue;
+  public MDCBasedDiscriminator() {
   }
 
   public String getDiscriminatingValue(LoggingEvent event) {
-    String mdcValue = MDC.get(mdcKey);
+    String mdcValue = MDC.get(key);
     if (mdcValue == null) {
       return defaultValue;
     } else {
@@ -40,11 +40,54 @@
   }
 
   public void start() {
-    started = true;
+    int errors = 0;
+    if (OptionHelper.isEmpty(key)) {
+      errors++;
+      addError("The \"Key\" property must be set");
+    }
+    if (OptionHelper.isEmpty(defaultValue)) {
+      errors++;
+      addError("The \"DefaultValue\" property must be set");
+    }
+    if (errors == 0) {
+      started = true;
+    }
   }
 
   public void stop() {
     started = false;
   }
 
+  public String getKey() {
+    return key;
+  }
+
+  public void setKey(String key) {
+    this.key = key;
+  }
+
+  /**
+   * @see #setDefaultValue(String)
+   * @return
+   */
+  public String getDefaultValue() {
+    return defaultValue;
+  }
+
+  /**
+   * The default MDC value in case the MDC is not set for
+   * {@link #setMdcKey(String) mdcKey}.
+   * 
+   * <p> For example, if {@link #setMdcKey(String) mdcKey} is set to the value
+   * "someKey", and the MDC is not set for "someKey", then this appender will
+   * use the default value, which you can set with the help of method.
+   * 
+   * @param defaultValue
+   */
+  public void setDefaultValue(String defaultValue) {
+    this.defaultValue = defaultValue;
+  }
+
+  
+
 }

Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java	(original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java	Mon Dec 22 23:18:36 2008
@@ -11,9 +11,9 @@
 import ch.qos.logback.core.joran.spi.ActionException;
 import ch.qos.logback.core.joran.spi.InterpretationContext;
 
-public class SiftAction  extends Action implements InPlayListener {
+public class SiftAction extends Action implements InPlayListener {
   List<SaxEvent> seList;
-  
+
   @Override
   public void begin(InterpretationContext ec, String name, Attributes attributes)
       throws ActionException {
@@ -26,22 +26,19 @@
     ec.removeInPlayListener(this);
     Object o = ec.peekObject();
     if (o instanceof SiftingAppender) {
-      SiftingAppender ha = (SiftingAppender) o; 
-      AppenderFactory appenderFactory = new AppenderFactory(context, seList, ha.getMdcKey());
-      ha.setAppenderFactory(appenderFactory);
+      SiftingAppender sa = (SiftingAppender) o;
+      AppenderFactory appenderFactory = new AppenderFactory(context, seList, sa
+          .getDiscriminatorKey());
+      sa.setAppenderFactory(appenderFactory);
     }
   }
 
   public void inPlay(SaxEvent event) {
     seList.add(event);
-    System.out.println(event);
   }
 
   public List<SaxEvent> getSeList() {
     return seList;
   }
 
-    
-
-
 }

Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java	(original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java	Mon Dec 22 23:18:36 2008
@@ -10,9 +10,10 @@
 package ch.qos.logback.classic.sift;
 
 import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.joran.spi.DefaultClass;
 import ch.qos.logback.core.sift.AppenderTracker;
+import ch.qos.logback.core.sift.Discriminator;
 import ch.qos.logback.core.sift.SiftingAppenderBase;
-import ch.qos.logback.core.util.OptionHelper;
 
 /**
  * This appender can contains other appenders which it can build dynamically
@@ -26,71 +27,20 @@
  */
 public class SiftingAppender extends SiftingAppenderBase<LoggingEvent> {
 
-
-  String mdcKey;
-  String defaultValue;
-
-
-  @Override
-  public void start() {
-    int errors = 0;
-    if (OptionHelper.isEmpty(mdcKey)) {
-      errors++;
-      addError("The \"mdcKey\" property must be set");
-    }
-    if (OptionHelper.isEmpty(defaultValue)) {
-      errors++;
-      addError("The \"defaultValue\" property must be set");
-    }
-    setDiscriminator(new MDCBasedDiscriminator(mdcKey, defaultValue));
-    if (errors == 0) {
-      super.start();
-    }
-  }
-
   AppenderTracker<LoggingEvent> getAppenderTracker() {
     return appenderTracker;
   }
 
-
   @Override
   protected long getTimestamp(LoggingEvent event) {
     return event.getTimeStamp();
   }
-
   
-  public String getMdcKey() {
-    return mdcKey;
-  }
-
-  public void setMdcKey(String mdcKey) {
-    this.mdcKey = mdcKey;
-  }
-
-  /**
-   * @see #setDefaultValue(String)
-   * @return
-   */
-  public String getDefaultValue() {
-    return defaultValue;
-  }
 
-  /**
-   * The default MDC value in case the MDC is not set for
-   * {@link #setMdcKey(String) mdcKey}.
-   * 
-   * <p> For example, if {@link #setMdcKey(String) mdcKey} is set to the value
-   * "someKey", and the MDC is not set for "someKey", then this appender will
-   * use the default value, which you can set with the help of method.
-   * 
-   * <p>The "defaultValue" property is set to the value "DEFAULT" by default.
-   * 
-   * @param defaultValue
-   */
-  public void setDefaultValue(String defaultValue) {
-    this.defaultValue = defaultValue;
+  @Override
+  @DefaultClass(MDCBasedDiscriminator.class)
+  public void setDiscriminator(Discriminator<LoggingEvent> discriminator) {
+    super.setDiscriminator(discriminator);
   }
 
-
-
 }

Modified: logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml	(original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml	Mon Dec 22 23:18:36 2008
@@ -3,13 +3,15 @@
 
 <configuration debug="true">
 
-  <appender name="SIFT"
-    class="ch.qos.logback.classic.sift.SiftingAppender">
+  <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
 
-    <mdcKey>cycle</mdcKey>
-    <defaultValue>cycleDefault</defaultValue>
+    <discriminator>
+      <Key>cycle</Key>
+      <defaultValue>cycleDefault</defaultValue>
+    </discriminator>
     <sift>
-      <appender name="list-${cycle}" class="ch.qos.logback.core.read.ListAppender"/>
+      <appender name="list-${cycle}"
+        class="ch.qos.logback.core.read.ListAppender" />
     </sift>
   </appender>
 

Modified: logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml	(original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml	Mon Dec 22 23:18:36 2008
@@ -3,13 +3,15 @@
 
 <configuration debug="true">
 
-  <appender name="SIFT"
-    class="ch.qos.logback.classic.sift.SiftingAppender">
+  <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
 
-    <mdcKey>userid</mdcKey>
-    <defaultValue>smoke</defaultValue>
+    <discriminator>
+      <Key>userid</Key>
+      <defaultValue>smoke</defaultValue>
+    </discriminator>
     <sift>
-      <appender name="list-${userid}" class="ch.qos.logback.core.read.ListAppender"/>
+      <appender name="list-${userid}"
+        class="ch.qos.logback.core.read.ListAppender" />
     </sift>
   </appender>
 

Modified: logback/trunk/logback-classic/src/test/input/joran/sift/unsetDefaultValueProperty.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/sift/unsetDefaultValueProperty.xml	(original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/unsetDefaultValueProperty.xml	Mon Dec 22 23:18:36 2008
@@ -3,12 +3,14 @@
 
 <configuration debug="true">
 
-  <appender name="SIFT"
-    class="ch.qos.logback.classic.sift.SiftingAppender">
+  <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
 
-    <mdcKey>userid</mdcKey>
+    <discriminator>
+      <Key>userid</Key>
+    </discriminator>
     <sift>
-      <appender name="list-${userid}" class="ch.qos.logback.core.read.ListAppender"/>
+      <appender name="list-${userid}"
+        class="ch.qos.logback.core.read.ListAppender" />
     </sift>
   </appender>
 

Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java	(original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java	Mon Dec 22 23:18:36 2008
@@ -47,9 +47,8 @@
   public void unsetDefaultValueProperty() throws JoranException {
     configure(PREFIX + "unsetDefaultValueProperty.xml");
     logger.debug("hello");
-    SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
-    assertFalse(ha.isStarted());
-    
+    SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
+    assertFalse(sa.isStarted());
   }
 
   @Test

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java	Mon Dec 22 23:18:36 2008
@@ -74,7 +74,7 @@
 
       return true;
     default:
-      addError("PropertySetter.canContainComponent returned " + aggregationType);
+      addError("PropertySetter.computeAggregationType returned " + aggregationType);
       return false;
     }
   }
@@ -87,9 +87,13 @@
         .peek();
 
     String className = attributes.getValue(CLASS_ATTRIBUTE);
-
     // perform variable name substitution
     className = ec.subst(className);
+    if (className == null) {
+      PropertySetter parentBean = actionData.parentBean;
+      className = parentBean.getDefaultClassNameByAnnonation(actionData
+          .getComplexPropertyName(), actionData.getAggregationType());
+    }
 
     if (OptionHelper.isEmpty(className)) {
       Class clazz = actionData.parentBean

Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultClass.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/DefaultClass.java	Mon Dec 22 23:18:36 2008
@@ -0,0 +1,21 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ * 
+ * Copyright (C) 2000-2008, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package ch.qos.logback.core.joran.spi;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target(ElementType.METHOD)
+public @interface DefaultClass {
+  Class value();
+}

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java	Mon Dec 22 23:18:36 2008
@@ -22,6 +22,7 @@
 import java.beans.Introspector;
 import java.beans.MethodDescriptor;
 import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 
@@ -37,8 +38,7 @@
  * the Object specified in the constructor. This class relies on the JavaBeans
  * {@link Introspector} to analyze the given Object Class using reflection.
  * 
- * <p>
- * Usage:
+ * <p> Usage:
  * 
  * <pre>
  * PropertySetter ps = new PropertySetter(anObject);
@@ -97,11 +97,10 @@
    * 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).
+   * <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
@@ -530,4 +529,36 @@
   public Object getObj() {
     return obj;
   }
+
+  public <T extends Annotation> T getAnnotation(String name,
+      Class<T> annonationClass, AggregationType aggregationType) {
+    String cName = capitalizeFirstLetter(name);
+    Method relevantMethod;
+    if (aggregationType == AggregationType.AS_COMPLEX_PROPERTY_COLLECTION) {
+      relevantMethod = getMethod("add" + cName);
+    } else if (aggregationType == AggregationType.AS_COMPLEX_PROPERTY) {
+      relevantMethod = findSetterMethod(cName);
+    } else {
+      throw new IllegalStateException(aggregationType + " not allowed here");
+    }
+    if (relevantMethod != null) {
+      return relevantMethod.getAnnotation(annonationClass);
+    } else {
+      return null;
+    }
+  }
+
+  public String getDefaultClassNameByAnnonation(String name,
+      AggregationType aggregationType) {
+
+    DefaultClass defaultClassAnnon = getAnnotation(name, DefaultClass.class,
+        aggregationType);
+    if (defaultClassAnnon != null) {
+      Class defaultClass = defaultClassAnnon.value();
+      if (defaultClass != null) {
+        return defaultClass.getName();
+      }
+    }
+    return null;
+  }
 }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/Discriminator.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/Discriminator.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/Discriminator.java	Mon Dec 22 23:18:36 2008
@@ -14,4 +14,5 @@
 
 public interface Discriminator<E> extends LifeCycle {
   String getDiscriminatingValue(E e);
+  String getKey();
 }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java	Mon Dec 22 23:18:36 2008
@@ -14,12 +14,11 @@
 import ch.qos.logback.core.joran.spi.JoranException;
 
 /**
- * This appender can contains other appenders which it can build dynamically
- * depending on MDC values. The built appender is specified as part of a
- * configuration file.
- * 
- * <p>See the logback manual for further details.
- * 
+ * This appender serves as the base class for actual SiftingAppenders
+ * implemented by the logback-classic and logback-access modules. In a nutshell,
+ * a SiftingAppender contains other appenders which it can build dynamically
+ * depending on discriminating values supplied by event currently being
+ * processed. The built appender is specified as part of a configuration file.
  * 
  * @author Ceki Gulcu
  */
@@ -28,23 +27,27 @@
 
   protected AppenderTracker<E> appenderTracker = new AppenderTrackerImpl<E>();
   AppenderFactoryBase<E> appenderFactory;
-  
+
   Discriminator<E> discriminator;
-  
+
   public void setAppenderFactory(AppenderFactoryBase<E> appenderFactory) {
     this.appenderFactory = appenderFactory;
   }
 
   @Override
   public void start() {
-    if(discriminator == null) {
+    int errors = 0;
+    if (discriminator == null) {
       addError("Missing discriminator. Aborting");
-      return;
+      errors++;
     }
-    if(!discriminator.isStarted()) {
+    if (!discriminator.isStarted()) {
       addError("Discriminator has not started successfully. Aborting");
+      errors++;
+    }
+    if (errors == 0) {
+      super.start();
     }
-    super.start();
   }
 
   @Override
@@ -90,4 +93,12 @@
     this.discriminator = discriminator;
   }
 
+  
+  public String getDiscriminatorKey() {
+    if(discriminator != null) {
+      return discriminator.getKey();
+    } else {
+      return null;
+    }
+  }
 }

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/joran/spi/PropertySetterTest.java	Mon Dec 22 23:18:36 2008
@@ -180,6 +180,15 @@
     setter.setProperty("houseColor", "BLUE");
     assertEquals(HouseColor.BLUE, house.getHouseColor());
   }
+  
+  
+  @Test
+  public void testDefaultClassAnnonation() {
+    House house = new House();
+    PropertySetter setter = new PropertySetter(house);
+    String spClassName = setter.getDefaultClassNameByAnnonation("SwimmingPool", AggregationType.AS_COMPLEX_PROPERTY);
+    assertEquals(SwimmingPool.class.getName(), spClassName);
+  }
 }
 
 class House {
@@ -237,6 +246,7 @@
     this.open = open;
   }
   
+  @DefaultClass(SwimmingPool.class)
   public void setSwimmingPool(SwimmingPool pool) {
     this.pool = pool;
   }


More information about the logback-dev mailing list