[logback-dev] [GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.21-2-g060efd8

added by portage for gitosis-gentoo git-noreply at pixie.qos.ch
Tue May 18 23:41:54 CEST 2010


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".

The branch, master has been updated
       via  060efd8495dedc95fc0f6abb688b8e0a1eaa1628 (commit)
      from  2cec26a3063cfa89133cc83e13e07f3c4a2d7746 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=060efd8495dedc95fc0f6abb688b8e0a1eaa1628
http://github.com/ceki/logback/commit/060efd8495dedc95fc0f6abb688b8e0a1eaa1628

commit 060efd8495dedc95fc0f6abb688b8e0a1eaa1628
Author: Ceki Gulcu <ceki at qos.ch>
Date:   Tue May 18 23:38:53 2010 +0200

    - significant progress made with the groovy DSL
    - logback-translator now supports XML to .groovy translations

diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
new file mode 100644
index 0000000..ef2ed83
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
@@ -0,0 +1,32 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import ch.qos.logback.core.Appender
+import ch.qos.logback.core.spi.ContextAwareBase
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+class AppenderDelegate extends ComponentDelegate {
+
+  AppenderDelegate(Appender appender) {
+    super(appender)
+  }
+
+  String getLabel() {
+    "appender"  
+  }
+
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
new file mode 100644
index 0000000..1db63a6
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
@@ -0,0 +1,146 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import ch.qos.logback.core.Appender
+import ch.qos.logback.core.spi.ContextAwareBase
+import ch.qos.logback.core.spi.LifeCycle
+import ch.qos.logback.core.spi.ContextAware
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+
+ at Mixin(ContextAwareBase)
+class ComponentDelegate {
+
+  final Object component;
+
+  ComponentDelegate(Object component) {
+    this.component = component;
+  }
+
+  String getLabel() { "component" }
+
+  String getLabelFistLetterInUpperCase() { getLabel()[0].toUpperCase() + getLabel().substring(1) }
+
+  void methodMissing(String name, def args) {
+    
+    if (component.hasProperty(name)) {
+      String subComponentName
+      Class clazz
+      Closure closure
+      (subComponentName, clazz, closure) = analyzeArgs(args)
+      if (clazz != null) {
+        Object subComponent = clazz.newInstance()
+        if (subComponentName && subComponent.hasProperty(name)) {
+          subComponent.name = subComponentName;
+        }
+        if (subComponent instanceof ContextAware) {
+          subComponent.context = context;
+        }
+        if (closure) {
+          ComponentDelegate subDelegate = new ComponentDelegate(subComponent)
+          subDelegate.context = context
+          closure.delegate = subDelegate
+          closure.resolveStrategy = Closure.DELEGATE_FIRST
+          closure()
+        }
+        if (subComponent instanceof LifeCycle) {
+          subComponent.start();
+        }
+        component."${name}" = subComponent;
+      }
+    } else {
+      addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no [${name}] property ")
+    }
+  }
+
+  def analyzeArgs(Object[] args) {
+    String name;
+    Class clazz;
+    Closure closure;
+
+    if (args.size() > 3) {
+      addError("At most 3 arguments allowed but you passed $args")
+      return [name, clazz, closure]
+    }
+
+    if (args[-1] instanceof Closure) {
+      closure = args[-1]
+      args -= args[-1]
+    }
+
+    if (args.size() == 1) {
+      clazz = parseClassArgument(args[0])
+    }
+
+    if (args.size() == 2) {
+      name = parseNameArgument(args[0])
+      clazz = parseClassArgument(args[1])
+    }
+
+    return [name, clazz, closure]
+  }
+
+  Class parseClassArgument(arg) {
+    if (arg instanceof Class) {
+      return arg
+    } else if (arg instanceof String) {
+      return Class.forName(arg)
+    } else {
+      addError("Unexpected argument type ${arg.getClass().canonicalName}")
+      return null;
+    }
+  }
+
+  String parseNameArgument(arg) {
+    if (arg instanceof String) {
+      return arg
+    } else {
+      addError("With 2 or 3 arguments, the first argument must be the component name, i.e of type string")
+      return null;
+    }
+  }
+
+  String getComponentName() {
+    if (component.hasProperty("name"))
+      return "[${component.name}]"
+    else
+      return ""
+
+  }
+
+  void propertyMissing(String name, def value) {
+    name = camelCasify(name);
+    if (component.hasProperty(name)) {
+      //println "-- component has property $name"
+      component."${name}" = value;
+    } else {
+      // println "-- component does not have property [$name]"
+      addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no [${name}] property ")
+    }
+  }
+
+  String camelCasify(String name) {
+    if(name == null || name.length() == 0)
+      return name;
+
+    String firstLetter = new String(name.getAt(0)).toLowerCase();
+    if(name.length() == 1)
+      return firstLetter
+    else
+      return firstLetter + name.substring(1);
+  }
+}
\ No newline at end of file
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
index 8ba018b..e45b223 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
@@ -1,3 +1,16 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
 package ch.qos.logback.classic.gaffer;
 
 import ch.qos.logback.core.util.Duration;
@@ -11,44 +24,61 @@ import ch.qos.logback.core.spi.ContextAwareImpl
 import ch.qos.logback.core.spi.ContextAwareBase
 import ch.qos.logback.classic.Level
 import ch.qos.logback.classic.Logger
-import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.Appender
+import ch.qos.logback.core.status.StatusListener
+import java.text.SimpleDateFormat
+import ch.qos.logback.classic.turbo.TurboFilter
+import ch.qos.logback.core.CoreConstants;
 
 /**
  * @author Ceki G&uuml;c&uuml;
  */
 
- at Mixin(ContextAwareBase)
-public class ConfigurationDelegate {
+public class ConfigurationDelegate extends ContextAwareBase {
 
   List<Appender> appenderList = [];
 
-  void configuration(Closure closure) {
-    configuration([:], closure)
+
+  Object getDeclaredOrigin() {
+    //println "ConfigurationDelegate"
+    return "ConfigurationDelegate"
   }
 
+  void scan(String scanPeriodStr = null) {
+    ReconfigureOnChangeFilter rocf = new ReconfigureOnChangeFilter();
+    rocf.setContext(context);
+    if (scanPeriodStr) {
+      try {
+        Duration duration = Duration.valueOf(scanPeriodStr);
+        rocf.setRefreshPeriod(duration.getMilliseconds());
+        addInfo("Setting ReconfigureOnChangeFilter scanning period to "
+                + duration);
+      } catch (NumberFormatException nfe) {
+        addError("Error while converting [" + scanAttrib + "] to long", nfe);
+      }
+    }
+    rocf.start();
+    addInfo("Adding ReconfigureOnChangeFilter as a turbo filter");
+    context.addTurboFilter(rocf);
+  }
 
-  void configuration(Map map, Closure closure) {
-    processScanAttributes(map.scan, map.scanPeriod);
+  void statusListener(Class listenerClass) {
+    StatusListener statusListener = listenerClass.newInstance()
+    context.statusManager.add(statusListener)
+    addInfo("Added status listener of type [${listenerClass.canonicalName}]");
   }
 
-  private void processScanAttributes(boolean scan, String scanPeriodStr) {
-    if (scan) {
-      ReconfigureOnChangeFilter rocf = new ReconfigureOnChangeFilter();
-      rocf.setContext(context);
-      if (scanPeriodStr) {
-        try {
-          Duration duration = Duration.valueOf(scanPeriodStr);
-          rocf.setRefreshPeriod(duration.getMilliseconds());
-          addInfo("Setting ReconfigureOnChangeFilter scanning period to "
-                  + duration);
-        } catch (NumberFormatException nfe) {
-          addError("Error while converting [" + scanAttrib + "] to long", nfe);
-        }
-      }
-      rocf.start();
-      addInfo("Adding ReconfigureOnChangeFilter as a turbo filter");
-      context.addTurboFilter(rocf);
+  void conversionRule(String conversionWord, Class converterClass) {
+    String converterClassName = converterClass.getName();
+
+    Map<String, String> ruleRegistry = (Map) context.getObject(CoreConstants.PATTERN_RULE_REGISTRY);
+    if (ruleRegistry == null) {
+      ruleRegistry = new HashMap<String, String>();
+      context.putObject(CoreConstants.PATTERN_RULE_REGISTRY, ruleRegistry);
     }
+    // put the new rule into the rule registry
+    addInfo("registering conversion word " + conversionWord + " with class [" + converterClassName + "]");
+    ruleRegistry.put(conversionWord, converterClassName);
   }
 
   void root(Level level, List<String> appenderNames = []) {
@@ -66,11 +96,11 @@ public class ConfigurationDelegate {
 
       if (appenderNames) {
         appenderNames.each { aName ->
-          Appender appender = appenderList.find { it.name == aName };
+          Appender appender = appenderList.find { it -> it.name == aName };
           if (appender != null) {
             logger.addAppender(appender);
           } else {
-            addError("Failed to find appender named [${it.name}]");
+            addError("Failed to find appender named [${aName}]");
           }
         }
       }
@@ -84,7 +114,9 @@ public class ConfigurationDelegate {
   }
 
   void appender(String name, Class clazz, Closure closure = null) {
+    addInfo("About to instantiate appender of type [" + clazz.name + "]");
     Appender appender = clazz.newInstance();
+    addInfo("Naming appender as [" + name + "]");
     appender.name = name
     appender.context = context
     appenderList.add(appender)
@@ -97,5 +129,27 @@ public class ConfigurationDelegate {
     }
     appender.start();
   }
+
+  void turboFilter(Class clazz, Closure closure = null) {
+    addInfo("About to instantiate turboFilter of type [" + clazz.name + "]");
+    TurboFilter turboFilter = clazz.newInstance();
+    turboFilter.context = context
+
+    if (closure != null) {
+      ComponentDelegate componentDelegate = new ComponentDelegate(turboFilter);
+      componentDelegate.context = context;
+      closure.delegate = componentDelegate;
+      closure.resolveStrategy = Closure.DELEGATE_FIRST
+      closure();
+    }
+    turboFilter.start();
+    addInfo("Adding aforementioned turbo filter to context");
+    context.addTurboFilter(turboFilter)
+  }
+
+  String timestamp(String datePattern) {
+    SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
+    sdf.format(new Date());
+  }
 }
 
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/Configurator.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/Configurator.groovy
index 9c18e68..09d6baf 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/Configurator.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/Configurator.groovy
@@ -13,35 +13,32 @@
  */
 package ch.qos.logback.classic.gaffer
 
-class Configurator {
+import ch.qos.logback.classic.LoggerContext
+import ch.qos.logback.core.util.ContextUtil
 
-  static void main(String[] args) {
-    runArchitectureRules(new File("src/ch/test/toto.groovy"))
-  }
+class Configurator {
 
-  static void runArchitectureRules(File dsl) {
-    //LoggerFactory loggerFactory = new LoggerFactory();
-    ConfigurationDelegate configurationDelegate = new ConfigurationDelegate();
-    //AppenderAction appenderAction = new AppenderAction();
+  LoggerContext context
+  //ConfigurationDelegate configurationDelegate = new ConfigurationDelegate();
 
+  Configurator(LoggerContext context) {
+    this.context = context
+    //configurationDelegate.context = context;
+  }
 
+  void run(String dslText) {
     Binding binding = new Binding();
-    binding.setProperty("DEBUG", new Integer(1));
-    Script dslScript = new GroovyShell(binding).parse(dsl.text)
-    ExpandoMetaClass emc = new ExpandoMetaClass(dslScript.class, false);
-
-    //configurationDelegate.metaClass.logger = loggerFactory.&logger
-    //configurationDelegate.metaClass.appender = appenderAction.&appender
-
-    emc.configuration = {Closure cl ->
-      println "executing configuration"
-      cl.delegate = configuration
-      cl();
-    }
-
-
-    emc.initialize();
-    dslScript.metaClass = emc;
+    binding.setProperty("hostname", ContextUtil.getLocalHostName());
+    Script dslScript = new GroovyShell(binding).parse(dslText)
+    
+    dslScript.metaClass.mixin(ConfigurationDelegate)
+    dslScript.setContext(context)
+    dslScript.metaClass.getDeclaredOrigin = { println "getDeclaredOrigin"; dslScript }
+//    metaClass.statusListener = configurationDelegate.&statusListener
+//    dslScript.metaClass.scan = configurationDelegate.&scan
+//    dslScript.metaClass.appender = configurationDelegate.&appender
+//    dslScript.metaClass.root = configurationDelegate.&root
+//    dslScript.metaClass.logger = configurationDelegate.&logger
 
     dslScript.run()
   }
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
index 5bc712f..451891d 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/filter/LevelFilter.java
@@ -45,8 +45,8 @@ public class LevelFilter extends AbstractMatcherFilter<ILoggingEvent> {
     }
   }
 
-  public void setLevel(String level) {
-    this.level = Level.toLevel(level);
+  public void setLevel(Level level) {
+    this.level = level;
   }
 
   public void start() {
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
deleted file mode 100644
index 3898a41..0000000
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
+++ /dev/null
@@ -1,32 +0,0 @@
-package ch.qos.logback.classic.gaffer
-
-import ch.qos.logback.core.Appender
-import ch.qos.logback.core.spi.ContextAwareBase
-
-/**
- * @author Ceki G&uuml;c&uuml;
- */
- at Mixin(ContextAwareBase)
-class AppenderDelegate {
-
-  Appender appender;
-
-  AppenderDelegate(Appender appender) {
-    this.appender = appender;
-  }
-
-  void methodMissing(String name, args) {
-    println "method $name accessed"
-  }
-  
-  void propertyMissing(String name, def value) {
-    println "-- propertyMissing"
-    if(appender.hasProperty(name)) {
-      //println "-- appender has property $name"
-      appender."${name}" = value;
-    } else {
-      //println "-- appender does not have property [$name]"
-      addError("Appender [${appender.name}] of type [${appender.getClass().canonicalName}] has no [${name}] property " )
-    }
-  }
-}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
index 7125a97..66d6b4d 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
@@ -13,13 +13,14 @@ import ch.qos.logback.classic.Logger
 import ch.qos.logback.core.Appender
 import ch.qos.logback.core.helpers.NOPAppender
 import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
 
 /**
  * @author Ceki G&uuml;c&uuml;
  */
 class ConfigurationDelegateTest {
 
-
   LoggerContext context = new LoggerContext()
   ConfigurationDelegate configurationDelegate = new ConfigurationDelegate();
   StatusChecker statusChecker = new StatusChecker(context)
@@ -39,7 +40,7 @@ class ConfigurationDelegateTest {
 
   @Test
   void scan() {
-    configurationDelegate.configuration([scan: true, scanPeriod: "10seconds"]) {}
+    configurationDelegate.scan("10seconds")
     assertTrue(statusChecker.containsMatch("Setting ReconfigureOnChangeFilter"))
     assertTrue(statusChecker.containsMatch("Adding ReconfigureOnChangeFilter as a turbo filter"))
 
@@ -50,6 +51,14 @@ class ConfigurationDelegateTest {
   }
 
   @Test
+  void timestamp() {
+    String result = configurationDelegate.timestamp("yyyy")
+    long year = Calendar.getInstance().get(Calendar.YEAR);
+    assertEquals(year.toString(), result)
+  }
+
+
+  @Test
   void loggerWithoutName() {
     configurationDelegate.logger("", Level.DEBUG)
     assertTrue(statusChecker.containsMatch("No name attribute for logger"))
@@ -132,4 +141,25 @@ class ConfigurationDelegateTest {
     assertEquals("C", back.name)
     assertEquals("System.err", back.target)
   }
+
+
+  @Test
+  void appenderWithEncoder() {
+    configurationDelegate.appender("C", ConsoleAppender) {
+      encoder (LayoutWrappingEncoder) {
+        layout (PatternLayout) {
+          pattern = "%m%n"
+        }
+      }
+    }
+    Appender back = configurationDelegate.appenderList.find {it.name = "C"}
+    assertNotNull(back)
+    assertEquals("C", back.name)
+    ConsoleAppender ca = back
+    assertNotNull(ca.encoder)
+    assertNotNull(ca.encoder.layout)
+    PatternLayout layout =  ca.encoder.layout
+    assertEquals("%m%n", layout.pattern)
+
+  }
 }
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
new file mode 100644
index 0000000..53ee836
--- /dev/null
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
@@ -0,0 +1,103 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import ch.qos.logback.classic.ClassicTestConstants
+import ch.qos.logback.classic.LoggerContext
+import org.junit.Before
+import ch.qos.logback.core.testUtil.RandomUtil
+import org.junit.Test
+import ch.qos.logback.classic.Logger
+import ch.qos.logback.classic.Level
+import static junit.framework.Assert.assertNotNull
+import static junit.framework.Assert.assertEquals
+import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.classic.spi.ILoggingEvent
+import ch.qos.logback.core.testUtil.StringListAppender
+import ch.qos.logback.classic.testUtil.SampleConverter
+import ch.qos.logback.core.util.StatusPrinter
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+class ConfiguratorTest {
+
+  LoggerContext context = new LoggerContext();
+  Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME)
+  Logger logger = context.getLogger(this.getClass())
+  int diff = RandomUtil.getPositiveInt();
+  Configurator configurator = new Configurator(context);
+
+  @Before
+  void setUp() {
+
+  }
+
+  @Test
+  void smoke() {
+    File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "smoke.groovy")
+    String dslText = file.text
+    configurator.run dslText
+    Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME);
+    assertEquals(Level.WARN, root.level)
+    assertNotNull(root.getAppender("C"))
+    ConsoleAppender ca = root.getAppender("C")
+    assertNotNull(ca.encoder)
+    assertNotNull(ca.encoder.layout)
+    PatternLayout layout = ca.encoder.layout
+    assertEquals("%m%n", layout.pattern)
+  }
+
+  @Test
+  void onTheFly() {
+    File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "onTheFly.groovy")
+    String dslText = file.text
+    configurator.run dslText
+  }
+
+  @Test
+  void contextName() {
+    String dslText = "context.name = 'a'"
+    configurator.run dslText
+    assertEquals("a", context.name)
+  }
+
+  @Test
+  void contextProperty() {
+    String dslText = "context.putProperty('x', 'a')"
+    configurator.run dslText
+    assertEquals("a", context.getProperty("x"))
+  }
+
+  @Test
+  void conversionRule() {
+    File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "conversionRule.groovy")
+    String dslText = file.text
+    configurator.run dslText
+
+    StringListAppender<ILoggingEvent> sla = (StringListAppender<ILoggingEvent>) root.getAppender("LIST");
+    assertNotNull(sla);
+    assertEquals(0, sla.strList.size());
+
+    assertEquals(Level.DEBUG, root.level);
+
+    String msg = "Simon says";
+    logger.debug(msg);
+    StatusPrinter.print context
+    assertEquals(1, sla.strList.size());
+    assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
+  }
+
+}
diff --git a/logback-classic/src/test/input/gaffer/conversionRule.groovy b/logback-classic/src/test/input/gaffer/conversionRule.groovy
new file mode 100644
index 0000000..c59fe09
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/conversionRule.groovy
@@ -0,0 +1,13 @@
+import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.classic.testUtil.SampleConverter
+import ch.qos.logback.core.testUtil.StringListAppender
+
+import static ch.qos.logback.classic.Level.DEBUG
+
+conversionRule("sample", SampleConverter)
+appender("LIST", StringListAppender) {
+  layout(PatternLayout) {
+    Pattern = "%sample - %msg"
+  }
+}
+root(DEBUG, ["LIST"])
diff --git a/logback-classic/src/test/input/gaffer/onTheFly.groovy b/logback-classic/src/test/input/gaffer/onTheFly.groovy
new file mode 100644
index 0000000..d4dda9f
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/onTheFly.groovy
@@ -0,0 +1,9 @@
+import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.classic.Level
+
+
+scan ()
+metaClass.xxx = { println "xxxxx"}
+xxx()
diff --git a/logback-classic/src/test/input/gaffer/smoke.groovy b/logback-classic/src/test/input/gaffer/smoke.groovy
new file mode 100644
index 0000000..3f7a1c5
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/smoke.groovy
@@ -0,0 +1,28 @@
+import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.classic.Level
+import ch.qos.logback.core.status.OnConsoleStatusListener
+import ch.qos.logback.classic.Logger
+
+
+context.name = "a"
+
+Logger xLogger = context.getLogger("x")
+xLogger.setLevel(Level.INFO)
+
+statusListener OnConsoleStatusListener
+
+println "hostname ${hostname}"
+
+addInfo("xxx")
+
+appender("C", ConsoleAppender) {
+  encoder(LayoutWrappingEncoder) {
+    layout(PatternLayout) {
+      pattern = "%m%n"
+    }
+  }
+}
+
+root Level.WARN, ["C"]
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java b/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
index c9471fd..fab5c7e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/ClassicTestConstants.java
@@ -14,10 +14,10 @@
 package ch.qos.logback.classic;
 
 public class ClassicTestConstants {
-
-  final static public String ISO_REGEX =  "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}";
-  final static public String NAKED_MAIN_REGEX =  "[mM]ain(\\sThread)?";
-  final static public String MAIN_REGEX =  "\\["+NAKED_MAIN_REGEX+"\\]";
+  final static public String ISO_REGEX = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}";
+  final static public String NAKED_MAIN_REGEX = "[mM]ain(\\sThread)?";
+  final static public String MAIN_REGEX = "\\[" + NAKED_MAIN_REGEX + "\\]";
   final static public String INPUT_PREFIX = "src/test/input/";
-  final static public String JORAN_INPUT_PREFIX = INPUT_PREFIX+"joran/";
+  final static public String JORAN_INPUT_PREFIX = INPUT_PREFIX + "joran/";
+  final static public String GAFFER_INPUT_PREFIX = INPUT_PREFIX + "gaffer/";
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
index f10afcb..3ea6b12 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/ContextUtil.java
@@ -1,13 +1,13 @@
 /**
  * Logback: the reliable, generic, fast and flexible logging framework.
  * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
- * 
+ *
  * This program and the accompanying materials are dual-licensed under either
  * the terms of the Eclipse Public License v1.0 as published by the Eclipse
  * Foundation
- * 
+ *
  * or (per the licensee's choosing)
- * 
+ *
  * under the terms of the GNU Lesser General Public License version 2.1 as
  * published by the Free Software Foundation.
  */
@@ -25,14 +25,19 @@ public class ContextUtil extends ContextAwareBase {
   public ContextUtil(Context context) {
     setContext(context);
   }
-  
+
+  static String getLocalHostName() throws UnknownHostException {
+    InetAddress localhost = InetAddress.getLocalHost();
+    return localhost.getHostName();
+  }
+
   /**
    * Add the local host's name as a property
    */
   public void addHostNameAsProperty() {
     try {
-      InetAddress localhost = InetAddress.getLocalHost();
-      context.putProperty(CoreConstants.HOSTNAME_KEY, localhost.getHostName());
+      String localhostName =  getLocalHostName();
+      context.putProperty(CoreConstants.HOSTNAME_KEY, localhostName);
     } catch (UnknownHostException e) {
       addError("Failed to get local hostname", e);
     } catch (SecurityException e) {
diff --git a/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml b/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
index bcc3c14..b435900 100644
--- a/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
+++ b/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
@@ -6,7 +6,7 @@
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     <encoder>
       <pattern>%-4relative [%thread] %sample - %msg%n</pattern>
-    </encoder>>
+    </encoder>
   </appender>
 
   <root level="DEBUG">
diff --git a/logback-site/src/site/pages/css/_print.css b/logback-site/src/site/pages/css/_print.css
index b385779..84b45b0 100644
--- a/logback-site/src/site/pages/css/_print.css
+++ b/logback-site/src/site/pages/css/_print.css
@@ -6,7 +6,7 @@ body {
 	font-size: 12px;
 }
 
-#left, #right {
+#left, #right, span.asGroovy {
 	width: 0px;
 	height: 0px;
   display: none;
@@ -28,4 +28,3 @@ table.bodyTable th {
 	text-align:center;
 }
 
-
diff --git a/logback-site/src/site/pages/css/common.css b/logback-site/src/site/pages/css/common.css
index d3a58aa..b3c76ad 100644
--- a/logback-site/src/site/pages/css/common.css
+++ b/logback-site/src/site/pages/css/common.css
@@ -25,7 +25,7 @@ div.source {
 .source, .command, .console { 
   border-top: 1px solid #DDDDDD;
   border-bottom: 1px solid #DDDDDD;
-  background:#eee;
+  background: #eee;
   font-family: Courier, "MS Courier New", Prestige, monospace;
   padding-left: 1ex;
   white-space: pre;
diff --git a/logback-site/src/site/pages/css/screen.css b/logback-site/src/site/pages/css/screen.css
index 5369a7a..303ba61 100644
--- a/logback-site/src/site/pages/css/screen.css
+++ b/logback-site/src/site/pages/css/screen.css
@@ -113,3 +113,25 @@ p.menu_header {
 	margin-right: auto;
 	display: block;
 }
+
+span.asGroovy {
+   background: #fff; 
+   color: #0079C5;   
+   font-family: "Comic Sans MS", sans-serif;
+   white-space: nowrap;
+   font-size: 80%;
+
+   border-top:    2px solid #DDD;  
+   border-left:   2px solid #DDD;  
+   border-right:  2px solid #888;  
+   border-bottom: 2px solid #888;    
+   padding: 0px 1em 0px 1em;
+   margin:  -1ex 0px 0px 0px; 
+   float: right;
+}
+ 
+span.asGroovy:hover {
+   background: #E0E0EF;
+   cursor: pointer;
+}
+
diff --git a/logback-site/src/site/pages/js/dsl.js b/logback-site/src/site/pages/js/dsl.js
new file mode 100644
index 0000000..baeef73
--- /dev/null
+++ b/logback-site/src/site/pages/js/dsl.js
@@ -0,0 +1,39 @@
+
+var asGroovyURL='http://logback.qos.ch/translator/dsl/asGroovy';
+
+function asGroovy(id) {
+
+  var form = document.getElementById('aForm');
+  if(form == null) {
+    form = document.createElement("form");
+    document.body.appendChild(form); 
+  }
+  var p = document.getElementById(id);
+  
+  var inner = p.innerHTML;
+  //alert("==="+inner);  
+  inner = inner.replace(/&lt;/gi, '<');
+  inner = inner.replace(/&gt;/gi, '>');
+
+  inner = inner.replace(/<span class="?\w{3,5}"?>/gi, '');
+  inner = inner.replace(/<\/span>/gi, '');
+  inner = inner.replace(/<br>/gi, '');
+  inner = inner.replace(/&nbsp;/gi, '');
+  inner = inner.replace(/<b>/gi, '');
+  inner = inner.replace(/<\/b>/gi, '');
+
+  form.setAttribute("method", "post");
+  form.setAttribute("action", asGroovyURL);
+  
+  var hiddenField = document.createElement("input");
+  hiddenField.setAttribute("type", "hidden");
+  hiddenField.setAttribute("name", "val");
+  hiddenField.setAttribute("value", inner);
+  form.appendChild(hiddenField);
+
+  //alert("==="+inner);  
+  form.submit();
+  return false;
+}
+
+ 
diff --git a/logback-site/src/site/pages/manual/appenders.html b/logback-site/src/site/pages/manual/appenders.html
index b6ab67e..5ad977a 100644
--- a/logback-site/src/site/pages/manual/appenders.html
+++ b/logback-site/src/site/pages/manual/appenders.html
@@ -7,12 +7,13 @@
     <link rel="stylesheet" type="text/css" href="../css/common.css" />
     <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
     <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
-    <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen" /    
+    <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen"/>    
   </head>
   <body onload="prettyPrint()">
     <script type="text/javascript">prefix='../';</script>
     <script type="text/javascript" src="../js/prettify.js"></script>
     <script src="../templates/header.js" type="text/javascript"></script>
+    <script type="text/javascript" src="../js/dsl.js"></script>
     <div id="left">      
       <noscript>Please turn on Javascript to view this menu</noscript>
       <script src="../templates/left.js" type="text/javascript"></script>
@@ -334,8 +335,10 @@ public interface Appender&lt;E> extends LifeCycle, ContextAware, FilterAttachabl
 	<code>ConsoleAppender</code>.
 	</p>
 
-  <em>Example 4.<span class="autoEx"/>: ConsoleAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</em>
-  <pre class="prettyprint source">&lt;configuration>
+  <em>Example: ConsoleAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</em>
+  <span class="asGroovy" onclick="return asGroovy('logback_Console');">View as .grovvy</span>
+
+  <pre id="logback_Console" class="prettyprint source">&lt;configuration>
 
   <b>&lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     &lt;!-- encoders are assigned the type
@@ -470,8 +473,9 @@ public interface Appender&lt;E> extends LifeCycle, ContextAware, FilterAttachabl
    <code>FileAppender</code>:
 	 </p>
 
-   <em>Example 4.<span class="autoEx"/>: FileAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</em>
-   <pre class="prettyprint source">&lt;configuration>
+   <em>Example: FileAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</em>
+   <span class="asGroovy" onclick="return asGroovy('logback-fileAppender');">View as .grovvy</span>
+   <pre id="logback-fileAppender"  class="prettyprint source">&lt;configuration>
 
   <b>&lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
     &lt;file>testFile.log&lt;/file>
@@ -508,8 +512,9 @@ public interface Appender&lt;E> extends LifeCycle, ContextAware, FilterAttachabl
    element. Here's an example.</p>
 
 
-   <em>Example 4.<span class="autoEx"/>: Uniquely named FileAppender configuration by timestamp (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</em>
-   <pre class="prettyprint source">&lt;configuration>
+   <em>Example: Uniquely named FileAppender configuration by timestamp (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</em>
+  <span class="asGroovy" onclick="return asGroovy('logback-timestamp');">View as .grovvy</span>
+   <pre id="logback-timestamp" class="prettyprint source">&lt;configuration>
 
   &lt;!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
        the key "bySecond" into the logger context. This value will be
@@ -848,10 +853,11 @@ public interface RollingPolicy extends LifeCycle {
    class="option">fileNamePattern</span> option.
    </p>
 	
-   <em>Example 4.<span class="autoEx"/>: Sample configuration of a <code>RollingFileAppender</code> using a 
+   <em>Example: Sample configuration of a <code>RollingFileAppender</code> using a 
    <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)</em>
 
-   <pre class="prettyprint source">&lt;configuration>
+   <span class="asGroovy" onclick="return asGroovy('logback-RollingFixedWindow');">View as .grovvy</span>
+   <pre id="logback-RollingFixedWindow" class="prettyprint source">&lt;configuration>
   &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     <b>&lt;file>test.log&lt;/file></b>
 
@@ -1159,13 +1165,14 @@ public interface RollingPolicy extends LifeCycle {
    <code>TimeBasedRollingPolicy</code>.
    </p>
 	
-   <em>Example 4.<span class="autoEx"/>: Sample configuration of a
+   <em>Example: Sample configuration of a
    <code>RollingFileAppender</code> using a
 
    <code>TimeBasedRollingPolicy</code>
    (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)</em>
 
-   <pre class="prettyprint source">&lt;configuration>
+   <span class="asGroovy" onclick="return asGroovy('logback-RollingTimeBased');">View as .grovvy</span>
+   <pre id="logback-RollingTimeBased" class="prettyprint source">&lt;configuration>
   &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     &lt;file>logFile.log&lt;/file>
     <b>&lt;rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
@@ -1192,12 +1199,13 @@ public interface RollingPolicy extends LifeCycle {
     mode.
     </p>
 
-   <em>Example 4.<span class="autoEx"/>: Sample configuration of a
+   <em>Example: Sample configuration of a
    <code>RollingFileAppender</code> using a
    <code>TimeBasedRollingPolicy</code>
    (logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</em>
 
-  <pre class="prettyprint source">&lt;configuration>
+  <span class="asGroovy" onclick="return asGroovy('logback-PrudentTimeBasedRolling');">View as .grovvy</span>
+  <pre id="logback-PrudentTimeBasedRolling" class="prettyprint source">&lt;configuration>
   &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     <b>&lt;!-- Support multiple-JVM writing to the same log file --></b>
     <b>&lt;prudent>true&lt;/prudent></b>
@@ -1208,7 +1216,7 @@ public interface RollingPolicy extends LifeCycle {
 
     &lt;encoder>
       &lt;pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n&lt;/pattern>
-    &lt;/encocer>
+    &lt;/encoder>
   &lt;/appender> 
 
   &lt;root level="DEBUG">
@@ -1233,15 +1241,17 @@ public interface RollingPolicy extends LifeCycle {
     <p>Here is a sample configuration file demonstrating time and size
     based log file archiving.</p>
     
-  <em>Example 4.<span class="autoEx"/>: Sample configuration for
+  <em>Example: Sample configuration for
   <code>SizeAndTimeBasedFNATP</code> 
   (logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)</em>
-  <pre class="prettyprint source">&lt;configuration>
+
+  <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">View as .grovvy</span>
+  <pre id="logback-sizeAndTime" class="prettyprint source">&lt;configuration>
   &lt;appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
     &lt;file>mylog.txt&lt;/file>
     &lt;rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       &lt;!-- rollover daily -->
-      &lt;fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big red">%i</span>.txt</b>&lt;/fileNamePattern>
+      &lt;fileNamePattern><b>mylog-%d{yyyy-MM-dd}.<span class="big">%i</span>.txt</b>&lt;/fileNamePattern>
       <b>&lt;timeBasedFileNamingAndTriggeringPolicy</b>
             <b>class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"></b>
         &lt;!-- or whenever the file size reaches 100MB -->
@@ -1339,9 +1349,11 @@ public interface TriggeringPolicy&lt;E&gt; extends LifeCycle {
 		the log file reaches 5MB in size.
 		</p>
 
-    <em>Example 4.<span class="autoEx"/>: Sample configuration of a <code>RollingFileAppender</code> using a 
+    <em>Example: Sample configuration of a <code>RollingFileAppender</code> using a 
     <code>SizeBasedTriggeringPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)</em>
-    <pre class="prettyprint source">&lt;configuration>
+
+    <span class="asGroovy" onclick="return asGroovy('logback-RollingSizeBased');">View as .grovvy</span>
+    <pre id="logback-RollingSizeBased" class="prettyprint source">&lt;configuration>
   &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     &lt;file>test.log&lt;/file>
     &lt;rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
@@ -1353,7 +1365,7 @@ public interface TriggeringPolicy&lt;E&gt; extends LifeCycle {
     <b>&lt;triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
       &lt;maxFileSize>5MB&lt;/maxFileSize>
     &lt;/triggeringPolicy></b>
-    &lt;encoder
+    &lt;encoder>
       &lt;pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n&lt;/pattern>
     &lt;/encoder>
   &lt;/appender>
@@ -1558,8 +1570,9 @@ public interface TriggeringPolicy&lt;E&gt; extends LifeCycle {
 			and attaches it to the root logger.
 		</p>
 
-		<em>Example 4.<span class="autoEx"/>: SocketAppender configuration (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+		<em>Example: SocketAppender configuration (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('client1');">View as .grovvy</span>
+<pre id="client1" class="prettyprint source">&lt;configuration>
 	  
   &lt;appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
     &lt;RemoteHost>${host}&lt;/RemoteHost>
@@ -2017,8 +2030,9 @@ Context ctx = new InitialContext(env);</pre>
 			<code>JMSTopicAppender</code> is rather straightforward to configure:
 		</p>
 
-		<em>Example 4.<span class="autoEx"/>: JMSTopicAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+		<em>Example: JMSTopicAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('logback-JMSTopic');">View as .grovvy</span>
+<pre id="logback-JMSTopic" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="Topic"
     class="ch.qos.logback.classic.net.JMSTopicAppender">
@@ -2085,8 +2099,9 @@ Context ctx = new InitialContext(env);</pre>
 			A typical <code>JMSQueueAppender</code> configuration file looks very
 			similar to that of a <code>JMSTopicAppender</code>.
 		</p>
-		<em>Example 4.<span class="autoEx"/>: JMSQueueAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+		<em>Example: JMSQueueAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('logback-JMSQueue');">View as .grovvy</span>
+    <pre id="logback-JMSQueue" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="Queue"
     class="ch.qos.logback.classic.net.JMSQueueAppender">
@@ -2300,8 +2315,9 @@ Context ctx = new InitialContext(env);</pre>
 		<code>Email</code> application:
 		</p>	
 		
-    <em>Example 4.<span class="autoEx"/>: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</em>		
-    <pre class="prettyprint source">&lt;configuration>	  
+    <em>Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</em>	
+    <span class="asGroovy" onclick="return asGroovy('mail1');">View as .grovvy</span>	
+    <pre id="mail1" class="prettyprint source">&lt;configuration>	  
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
     &lt;SMTPHost>ADDRESS-OF-YOUR-SMTP-HOST&lt;/SMTPHost>
     &lt;To>EMAIL-DESTINATION&lt;/To>
@@ -2415,9 +2431,10 @@ Context ctx = new InitialContext(env);</pre>
 		1024th event triggers an email message.
 		</p>
 
-<em>Example 4.<span class="autoEx"/>: A <code>EventEvaluator</code> implementation
+    <em>Example: A <code>EventEvaluator</code> implementation
 that evaluates to <code>true</code> every 1024th event (<a href="../xref/chapters/appenders/mail/CounterBasedEvaluator.html">logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java</a>)</em>
-<pre class="prettyprint source">package chapters.appenders.mail;
+   
+   <pre class="prettyprint source">package chapters.appenders.mail;
 
 import ch.qos.logback.core.boolex.EvaluationException;
 import ch.qos.logback.core.boolex.EventEvaluator;
@@ -2466,10 +2483,10 @@ public class CounterBasedEvaluator extends ContextAwareBase implements EventEval
 		evaluator.
 		</p>
 
-<em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> with custom 
-<code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</em>
-
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: <code>SMTPAppender</code> with custom 
+    <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('mail3');">View as .grovvy</span>	
+    <pre id="mail3" class="prettyprint source">&lt;configuration>
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
     <b>&lt;Evaluator class="chapters.appenders.mail.CounterBasedEvaluator" /></b>
     &lt;BufferSize>1050&lt;/BufferSize>
@@ -2515,10 +2532,11 @@ logger.error(<b>notifyAdminMarker</b>,
    TRANSACTION_FAILURE marker.
    </p>
 
-   <em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> with 
+   <em>Example: <code>SMTPAppender</code> with 
    <code>OnMarkerEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml)</em>
 
-    <pre class="prettyprint source">&lt;configuration>
+   <span class="asGroovy" onclick="return asGroovy('mailWithMarker');">View as .grovvy</span>	
+   <pre id="mailWithMarker" class="prettyprint source">&lt;configuration>
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
     <b>&lt;evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
       &lt;marker>NOTIFY_ADMIN&lt;/marker>
@@ -2563,9 +2581,10 @@ logger.error(<b>notifyAdminMarker</b>,
     <p>The next example shows you how to configure
     <code>SMTPAppender</code> for Gmail with the SSL protocol. </p>
     
-    <em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> to Gmail using SSL (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</em>
+    <em><code>SMTPAppender</code> to Gmail using SSL (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</em>
 
-    <pre class="prettyprint source">&lt;configuration>
+    <span class="asGroovy" onclick="return asGroovy('gmailSSL');">View as .grovvy</span>	
+    <pre id="gmailSSL" class="prettyprint source">&lt;configuration>
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
     <b>&lt;SMTPHost>smtp.gmail.com&lt;/SMTPHost></b>
     <b>&lt;SMTPPort>465&lt;/SMTPPort></b>
@@ -2594,9 +2613,10 @@ logger.error(<b>notifyAdminMarker</b>,
     <p>The next example shows you how to configure
     <code>SMTPAppender</code> for Gmail for the STARTTLS protocol. </p>
 
-    <em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</em>
+    <em>Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</em>
 
-    <pre class="prettyprint source">&lt;configuration>	  
+    <span class="asGroovy" onclick="return asGroovy('gmailSTARTTLS');">View as .grovvy</span>	
+    <pre id="gmailSTARTTLS" class="prettyprint source">&lt;configuration>	  
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
     &lt;SMTPHost>smtp.gmail.com&lt;/SMTPHost>
     &lt;SMTPPort>587&lt;/SMTPPort>
@@ -2913,8 +2933,9 @@ logger.error(<b>notifyAdminMarker</b>,
 			The following configuration file is what one would need.
 		</p>
 		
-<em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-driverManager');">View as .grovvy</span>	
+    <pre id="append-toMySQL-with-driverManager" class="prettyprint source">&lt;configuration>
 
   <b>&lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
     &lt;connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
@@ -2991,8 +3012,11 @@ logger.error(<b>notifyAdminMarker</b>,
 			<code>javax.sql.DataSource</code>.
 		</p>
 	
-<em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</em>	
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</em>	
+
+
+    <span class="asGroovy" onclick="return asGroovy('append-with-datasource');">View as .grovvy</span>	
+    <pre id="append-with-datasource" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
      <b>&lt;connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
@@ -3104,8 +3128,11 @@ logger.error(<b>notifyAdminMarker</b>,
 			without any pooling.
 		</p>
     
-    <em>Example 4.<span class="autoEx"/> <code>DBAppender</code> configuration without pooling (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</em>	
-    <pre class="prettyprint source">&lt;configuration>
+    <em>Example 4.<span class="autoEx"/> <code>DBAppender</code>
+    configuration without pooling
+    (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource');">View as .grovvy</span>	
+    <pre id="append-toMySQL-with-datasource" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
     &lt;connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
@@ -3122,7 +3149,7 @@ logger.error(<b>notifyAdminMarker</b>,
   &lt;root level="DEBUG">
     &lt;appender-ref ref="DB" />
   &lt;/root>
-&lt;/configuration</pre>
+&lt;/configuration></pre>
 
 		<p>With this configuration file, sending 500 logging events to a
 		MySQL database takes a whopping 5 seconds, that is 10 milliseconds
@@ -3137,8 +3164,9 @@ logger.error(<b>notifyAdminMarker</b>,
 		<em>c3p0-VERSION.jar</em> in the classpath.
 		</p>
 
-    <em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration with pooling (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</em>			
-    <pre class="prettyprint source">&lt;configuration>
+    <em>Example: <code>DBAppender</code> configuration with pooling (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</em>			
+    <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource-and-pooling');">View as .grovvy</span>	
+    <pre id="append-toMySQL-with-datasource-and-pooling" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
     &lt;connectionSource
@@ -3272,8 +3300,9 @@ logger.error(<b>notifyAdminMarker</b>,
 			Here is a sample configuration using a <code>SyslogAppender</code>.
 		</p>
 		
-<em>Example 4.<span class="autoEx"/>: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</em>				
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</em>	
+    <span class="asGroovy" onclick="return asGroovy('logback-syslog');">View as .grovvy</span>	
+    <pre id="logback-syslog" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="SYSLOG"
     class="ch.qos.logback.classic.net.SyslogAppender">
@@ -3283,7 +3312,7 @@ logger.error(<b>notifyAdminMarker</b>,
   &lt;/appender>
 
   &lt;root level="DEBUG">
-    &lt;appender-ref ref="STDOUT" />
+    &lt;appender-ref ref="SYSLOG" />
   &lt;/root>
 &lt;/configuration></pre>
 
@@ -3328,7 +3357,7 @@ logger.debug("Alice says hello"); </p>
     <code>SiftingAppender</code>.</p>
 
 
-    <em>Example 4.<span class="autoEx"/>: <code>SiftingAppender</code>
+    <em>Example: <code>SiftingAppender</code>
     configuration
     (logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml)</em>
 
@@ -3538,7 +3567,7 @@ public class CountingConsoleAppender extends AppenderBase&lt;ILoggingEvent> {
 		<p>
 			Here is a sample configuration of a <code>SMTPAppender</code> in the access environment.
 		</p>
-<em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</em>					
+<em>Example: <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</em>					
 <pre class="prettyprint source">&lt;appender name="SMTP"
   class="ch.qos.logback.access.net.SMTPAppender">
   &lt;layout class="ch.qos.logback.access.html.HTMLLayout">
@@ -3708,7 +3737,7 @@ public class CountingConsoleAppender extends AppenderBase&lt;ILoggingEvent> {
 			Here is a sample configuration that uses <code>DBAppender</code>.
 		</p>
 
-    <em>Example 4.<span class="autoEx"/>: DBAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em>		
+    <em>Example: DBAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em>		
     <pre class="prettyprint source">&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.access.db.DBAppender">
@@ -3747,7 +3776,7 @@ public class CountingConsoleAppender extends AppenderBase&lt;ILoggingEvent> {
     
     <p>Below is an example configuration file.</p>
 
-    <em>Example 4.<span class="autoEx"/>: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</em>		
+    <em>Example: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</em>		
     
     <pre class="prettyprint source">&lt;configuration>
   &lt;appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
diff --git a/logback-site/src/site/pages/manual/configuration.html b/logback-site/src/site/pages/manual/configuration.html
index f6de8cc..d73e024 100644
--- a/logback-site/src/site/pages/manual/configuration.html
+++ b/logback-site/src/site/pages/manual/configuration.html
@@ -17,6 +17,7 @@
     <script type="text/javascript">prefix='../'</script>
     <script type="text/javascript" src="../js/prettify.js"></script>
     <script src="../templates/header.js" type="text/javascript"></script>
+     <script type="text/javascript" src="../js/dsl.js"></script>
     <div id="left">
       <noscript>Please turn on Javascript to view this menu</noscript>
       <script src="../templates/left.js" type="text/javascript"></script>
@@ -231,11 +232,12 @@ public class Foo {
    seen.
    </p>
 
- <p><em>Example: Basic configuration file
-  (logback-examples/src/main/java/chapters/configuration/sample0.xml)</em></p>
+  <em>Example: Basic configuration file
+  (logback-examples/src/main/java/chapters/configuration/sample0.xml)</em>
+  <span class="asGroovy" onclick="return asGroovy('sample0');">View as .grovvy</span>
 
 
-<pre class="prettyprint source">&lt;configuration>
+  <pre id="sample0" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     &lt;!-- encoders are assigned the type
@@ -328,8 +330,9 @@ public class Foo {
    <em>Example: Basic configuration file
    using debug mode
    (logback-examples/src/main/java/chapters/configuration/sample1.xml)</em>
+   <span class="asGroovy" onclick="return asGroovy('sample1');">View as .grovvy</span>
 
-<pre class="prettyprint source">
+   <pre id="sample1" class="prettyprint source">
 &lt;configuration <b>debug="true"</b>> 
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
@@ -403,9 +406,10 @@ public class Foo {
   configuration file and automatic re-configuraion
   (logback-examples/src/main/java/chapters/configuration/scan1.xml)</em>
 
-<pre class="prettyprint source">
+  <span class="asGroovy" onclick="return asGroovy('scan1');">View as .grovvy</span>
+<pre id="scan1" class="prettyprint source">
 &lt;configuration <b>scan="true"</b>> 
-  ...
+  ... 
 &lt;/configuration> </pre>
 
 
@@ -419,8 +423,8 @@ public class Foo {
   <em>Example: Specifying a different
   scanning period
   (logback-examples/src/main/java/chapters/configuration/scan2.xml)</em>
-
-<pre class="prettyprint source">
+  <span class="asGroovy" onclick="return asGroovy('scan2');">View as .grovvy</span>
+  <pre id="scan2" class="prettyprint source">
 &lt;configuration scan="true" <b>scanPeriod="30 seconds"</b> > 
   ...
 &lt;/configuration> </pre>
@@ -605,9 +609,11 @@ public class MyApp3 {
    <p>It is also possible to register one or more status listeners
    within a configuration file. Here is an example.</p>
 
-  <p><em>Example: Registering a status listener (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</em></p>
+   <p><em>Example: Registering a status listener
+   (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</em></p>
 
-   <pre class="prettyprint source">&lt;configuration>
+   <span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">View as .grovvy</span>
+   <pre id="onConsoleStatusListener" class="prettyprint source">&lt;configuration>
   <b>&lt;statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /></b>  
 
   ... the rest of the configuration file  
@@ -761,8 +767,11 @@ public class MyApp3 {
    shows how to achieve that.
    </p>
 
-<em>Example: Setting the level of a logger (logback-examples/src/main/java/chapters/configuration/sample2.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+   <em>Example: Setting the level of a logger
+   (logback-examples/src/main/java/chapters/configuration/sample2.xml)</em>
+
+   <span class="asGroovy" onclick="return asGroovy('sample2');">View as .grovvy</span>
+   <pre id="sample2" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     &lt;!-- encoders are assigned the type
@@ -799,8 +808,11 @@ public class MyApp3 {
   of the <em>chapters.configuration.Foo</em> logger to <code>DEBUG</code>.
   </p>
 
-<em>Example: Setting the level of multiple loggers (logback-examples/src/main/java/chapters/configuration/sample3.xml)</em>
-<pre class="source prettyprint">&lt;configuration>
+  <em>Example: Setting the level of multiple loggers
+  (logback-examples/src/main/java/chapters/configuration/sample3.xml)</em>
+  
+  <span class="asGroovy" onclick="return asGroovy('sample3');">View as .grovvy</span>
+  <pre id="sample3" class="source prettyprint">&lt;configuration>
 
   &lt;appender name="STDOUT"
     class="ch.qos.logback.core.ConsoleAppender">
@@ -880,7 +892,8 @@ public class MyApp3 {
 
   <em>Example: Logger level sample
   (logback-examples/src/main/java/chapters/configuration/sample4.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+  <span class="asGroovy" onclick="return asGroovy('sample4');">View as .grovvy</span>
+  <pre id="sample4" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
@@ -1002,8 +1015,10 @@ public class MyApp3 {
   configuration file illustrates:
   </p>
 
-<em>Example: Multiple loggers (logback-examples/src/main/java/chapters/configuration/multiple.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+  <em>Example: Multiple loggers
+  (logback-examples/src/main/java/chapters/configuration/multiple.xml)</em>
+  <span class="asGroovy" onclick="return asGroovy('multiple');">View as .grovvy</span>
+  <pre id="multiple" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="<b>FILE</b>" class="ch.qos.logback.core.FileAppender">
     &lt;file>myApp.log&lt;/file>
@@ -1056,7 +1071,9 @@ public class MyApp3 {
 
   <em>Example: Duplicate appender
   (logback-examples/src/main/java/chapters/configuration/duplicate.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+
+  <span class="asGroovy" onclick="return asGroovy('duplicate');">View as .grovvy</span>
+  <pre id="duplicate" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     &lt;encoder>
@@ -1102,7 +1119,8 @@ public class MyApp3 {
 
   <em>Example: Multiple appender
   (logback-examples/src/main/java/chapters/configuration/restricted.xml)</em>
-  <pre class="prettyprint source">&lt;configuration>
+  <span class="asGroovy" onclick="return asGroovy('restricted');">View as .grovvy</span>
+  <pre id="restricted" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
     &lt;file>myApp.log&lt;/file>
@@ -1127,9 +1145,9 @@ public class MyApp3 {
 &lt;/configuration></pre>
 
   <p>In this example, the console appender will log all the messages
-  (for all loggers in the system) whereas only logging request
-  originating from loggers <em>chapters.configuration</em> and below go into the
-  <em>myApp.log</em> file.
+  (for all loggers in the system) whereas only logging requests
+  originating from the <em>chapters.configuration</em> logger and its
+  children will go into the <em>myApp.log</em> file.
   </p>
 	
   <h4>
@@ -1145,8 +1163,11 @@ public class MyApp3 {
   of the tree.
   </p>
 
-<em>Example: Additivity flag (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+  <em>Example: Additivity flag
+  (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</em>
+
+  <span class="asGroovy" onclick="return asGroovy('additivityFlag');">View as .grovvy</span>
+  <pre id="additivityFlag" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
     &lt;file>foo.log&lt;/file>
@@ -1200,7 +1221,9 @@ public class MyApp3 {
   
   <em>Example: Set the context name and display it
   (logback-examples/src/main/java/chapters/configuration/contextName.xml)</em>
-  <pre class="prettyprint source">&lt;configuration>
+
+  <span class="asGroovy" onclick="return asGroovy('contextName');">View as .grovvy</span>
+  <pre id="contextName" class="prettyprint source">&lt;configuration>
   <b>&lt;contextName>myAppName&lt;/contextName></b>
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     &lt;encoder>
@@ -1255,7 +1278,8 @@ public class MyApp3 {
   (logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml)
   </em>
 
-  <pre class="prettyprint source">&lt;configuration>
+  <span class="asGroovy" onclick="return asGroovy('variableSubstitution1');">View as .grovvy</span>
+  <pre id="variableSubstitution1" class="prettyprint source">&lt;configuration>
 
   <b>&lt;property name="USER_HOME" value="/home/sebastien" /></b>
 
@@ -1283,8 +1307,8 @@ public class MyApp3 {
   <em>Example: System Variable substitution
   (logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml)
   </em>
-  
-  <pre class="prettyprint source">&lt;configuration>
+  <span class="asGroovy" onclick="return asGroovy('variableSubstitution2');">View as .grovvy</span>
+  <pre id="variableSubstitution2" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <b>&lt;file>${USER_HOME}/myApp.log&lt;/file></b>
diff --git a/logback-site/src/site/pages/manual/filters.html b/logback-site/src/site/pages/manual/filters.html
index 43d5e82..5e49139 100644
--- a/logback-site/src/site/pages/manual/filters.html
+++ b/logback-site/src/site/pages/manual/filters.html
@@ -15,6 +15,7 @@
     <script type="text/javascript">prefix='../';</script>
     <script type="text/javascript" src="../js/prettify.js"></script>
     <script src="../templates/header.js" type="text/javascript"></script>
+    <script type="text/javascript" src="../js/dsl.js"></script>
     <div id="left">
       <noscript>Please turn on Javascript to view this menu</noscript>
       <script src="../templates/left.js" type="text/javascript"></script>
@@ -105,8 +106,9 @@
 		events, the value NEUTRAL is returned.
 		</p>
 		
-<em>Example 6.<span class="autoEx"/>: Basic custom filter (<a href="../xref/chapters/filters/SampleFilter.html">logback-examples/src/main/java/chapters/filters/SampleFilter.java</a>)</em>		
-<pre class="prettyprint source">package chapters.filters;
+    <em>Example: Basic custom filter (<a
+    href="../xref/chapters/filters/SampleFilter.html">logback-examples/src/main/java/chapters/filters/SampleFilter.java</a>)</em>
+    <pre class="prettyprint source">package chapters.filters;
 
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.filter.Filter;
@@ -128,8 +130,10 @@ public class SampleFilter extends Filter&gt;ILoggingEvent> {
 		<code>SampleFilter</code> to a <code>ConsoleAppener</code>.
 		</p>
 
-<em>Example 6.<span class="autoEx"/>: SampleFilter configuration (logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml)</em>				
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: SampleFilter configuration
+    (logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('SampleFilterConfig');">View as .grovvy</span>
+    <pre id="SampleFilterConfig" class="prettyprint source">&lt;configuration>
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
 
     <b>&lt;filter class="chapters.filters.SampleFilter" /></b>
@@ -183,8 +187,10 @@ public class SampleFilter extends Filter&gt;ILoggingEvent> {
 		configuration file.
 		</p>
 		
-<em>Example 6.<span class="autoEx"/>: Sample LevelFilter configuration (logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml)</em>				
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: Sample LevelFilter configuration
+    (logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('levelFilterConfig');">View as .grovvy</span>
+    <pre id="levelFilterConfig" class="prettyprint source">&lt;configuration>
   &lt;appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
     <b>&lt;filter class="ch.qos.logback.classic.filter.LevelFilter">
       &lt;level>INFO&lt;/level>
@@ -214,8 +220,10 @@ public class SampleFilter extends Filter&gt;ILoggingEvent> {
 		configuration file.
 		</p>
 
-<em>Example 6.<span class="autoEx"/>: Sample ThresholdFilter configuration (logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml)</em>				
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: Sample ThresholdFilter configuration
+    (logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('thresholdFilterConfig');">View as .grovvy</span>
+    <pre id="thresholdFilterConfig"  class="prettyprint source">&lt;configuration>
   &lt;appender name="CONSOLE"
     class="ch.qos.logback.core.ConsoleAppender">
     &lt;!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
@@ -294,8 +302,9 @@ public class SampleFilter extends Filter&gt;ILoggingEvent> {
 
     <p>Here is a more complete example.</p>
 
-<pre class="prettyprint source">&lt;configuration>
-
+    <span class="asGroovy" onclick="return asGroovy('GEventEvaluator');">View as .grovvy</span>
+    <pre id="GEventEvaluator"  class="prettyprint source">&lt;configuration>
+    
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     <b>&lt;filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
       &lt;evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator"> 
@@ -506,9 +515,11 @@ public class SampleFilter extends Filter&gt;ILoggingEvent> {
 
     <p>Here is a concrete example.</p>
 
-<em>Example 6.<span class="autoEx"/>: Basic event evaluator usage (logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml)</em>
+    <em>Example: Basic event evaluator usage
+    (logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml)</em>
 
-<pre class="prettyprint source longline">&lt;configuration>
+    <span class="asGroovy" onclick="return asGroovy('basicEventEvaluator');">View as .grovvy</span>
+    <pre id="basicEventEvaluator" class="prettyprint source longline">&lt;configuration>
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     <b>&lt;filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
@@ -614,9 +625,10 @@ java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfigura
 
     <p>An example should clarify the point:</p>
 
-<em>Example 6.<span class="autoEx"/>: Defining matchers in an event evaluator (logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml)</em>
+    <em>Example: Defining matchers in an event evaluator (logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml)</em>
+    <span class="asGroovy" onclick="return asGroovy('evaluatorWithMatcher');">View as .grovvy</span>
 
-    <pre class="prettyprint source">&lt;configuration debug="true">
+    <pre id="evaluatorWithMatcher" class="prettyprint source">&lt;configuration debug="true">
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     &lt;filter class="ch.qos.logback.core.filter.EvaluatorFilter">
@@ -703,7 +715,7 @@ java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfigura
     slightly more complex filter:
     </p>
     
-<em>Example 6.<span class="autoEx"/>: Basic custom <code>TurboFilter</code> (<a href="../xref/chapters/filters/SampleTurboFilter.html">logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java</a>)</em>		
+<em>Example: Basic custom <code>TurboFilter</code> (<a href="../xref/chapters/filters/SampleTurboFilter.html">logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java</a>)</em>		
 <pre class="prettyprint source">package chapters.filters;
 
 import org.slf4j.Marker;
@@ -768,8 +780,12 @@ public class SampleTurboFilter extends TurboFilter {
 		created <code>TurboFilter</code>.
 		</p>
 		
-<em>Example 6.<span class="autoEx"/>: Basic custom <code>TurboFilter</code> configuration (logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml)</em>		
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: Basic custom <code>TurboFilter</code> configuration
+    (logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml)</em>
+
+    <span class="asGroovy" onclick="return asGroovy('sampleTurboFilterConfig');">View as .grovvy</span>
+
+    <pre id="sampleTurboFilterConfig"  class="prettyprint source">&lt;configuration>
   <b>&lt;turboFilter class="chapters.filters.SampleTurboFilter">
     &lt;Marker>sample&lt;/Marker>
   &lt;/turboFilter></b>
@@ -803,9 +819,12 @@ public class SampleTurboFilter extends TurboFilter {
    	<code>MDCFilter</code> and <code>MarkerFilter</code>.
    	</p>
    	
-<em>Example 6.<span class="autoEx"/>: <code>MDCFilter</code> and <code>MarkerFilter</code> 
-configuration (logback-examples/src/main/java/chapters/filters/turboFilters.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: <code>MDCFilter</code> and <code>MarkerFilter</code>
+    configuration
+    (logback-examples/src/main/java/chapters/filters/turboFilters.xml)</em>
+
+    <span class="asGroovy" onclick="return asGroovy('turboFilters');">View as .grovvy</span>
+    <pre id="turboFilters" class="prettyprint source">&lt;configuration>
 
   &lt;turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
     &lt;MDCKey>username&lt;/MDCKey>
@@ -930,9 +949,11 @@ logger.debug("Hello {}.", name1);</pre>
     </p>
 
     
-<em>Example 6.<span class="autoEx"/>: <code>DuplicateMessageFilter</code> 
-configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+    <em>Example: <code>DuplicateMessageFilter</code> 
+    configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.xml)</em>
+
+    <span class="asGroovy" onclick="return asGroovy('duplicateMessage');">View as .grovvy</span>
+    <pre id="duplicateMessage" class="prettyprint source">&lt;configuration>
 
   <b>&lt;turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter"/></b>
 
@@ -1005,7 +1026,7 @@ configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.
     error will be logged:
     </p>
    	
-<em>Example 6.<span class="autoEx"/>: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml)</em>
+<em>Example: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml)</em>
 <pre class="prettyprint source">&lt;configuration>
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
diff --git a/logback-site/src/site/pages/manual/layouts.html b/logback-site/src/site/pages/manual/layouts.html
index ab07ec8..23e5bfc 100644
--- a/logback-site/src/site/pages/manual/layouts.html
+++ b/logback-site/src/site/pages/manual/layouts.html
@@ -14,6 +14,7 @@
   <body onload="prettyPrint()">
     <script type="text/javascript">prefix='../';</script>
     <script type="text/javascript" src="../js/prettify.js"></script>
+    <script type="text/javascript" src="../js/dsl.js"></script>
     <script src="../templates/header.js" type="text/javascript"></script>
     <div id="left">
       <noscript>Please turn on Javascript to view this menu</noscript>
@@ -159,7 +160,8 @@ public class MySampleLayout extends LayoutBase&lt;ILoggingEvent> {
 		
 		<em>Example: Configuration of MySampleLayout
 		(logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+    <span class="asGroovy" onclick="return asGroovy('sampleLayoutConfig');">View as .grovvy</span>
+<pre id="sampleLayoutConfig" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     <b>&lt;encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"></b>
@@ -171,7 +173,7 @@ public class MySampleLayout extends LayoutBase&lt;ILoggingEvent> {
     &lt;appender-ref ref="STDOUT" />
   &lt;/root>
 &lt;/configuration></pre>
-
+   
 		<p>The sample application <a
 		href="../xref/chapters/layouts/SampleLogging.html">
 		<code>chapters.layouts.SampleLogging</code></a> configures logback
@@ -266,7 +268,8 @@ public class MySampleLayout2 extends LayoutBase&lt;ILoggingEvent> {
     </p> 
 
 
-    <pre class="prettyprint source">&lt;configuration>
+    <span class="asGroovy" onclick="return asGroovy('MySampleLayout2');">View as .grovvy</span>
+    <pre id="MySampleLayout2" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     &lt;encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
@@ -1291,7 +1294,11 @@ Caller+2   at mainPackage.ConfigTester.main(ConfigTester.java:38)</pre>
 			Example: Sample usage of EventEvaluators
 			(logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml)
 		</em>
-		<pre class="prettyprint source">&lt;configuration>
+
+    <span class="asGroovy" onclick="return asGroovy('callerEvaluatorConfig');">View as .grovvy</span>
+
+
+		<pre id="callerEvaluatorConfig" class="prettyprint source">&lt;configuration>
   <b>&lt;evaluator name="DISP_CALLER_EVAL">
     &lt;expression>logger.contains("chapters.layouts") &amp;amp;&amp;amp; \
       message.contains("who calls thee")&lt;/expression>
@@ -1598,7 +1605,8 @@ public class MySampleConverter extends ClassicConverter {
 		new conversion word in the configuration file, as shown below:</p>
 		
 <em> Example: Sample Converter Example (src/main/java/chapters/layouts/mySampleConverterConfig.xml)</em>
-<pre class="prettyprint source">&lt;configuration>
+ <span class="asGroovy" onclick="return asGroovy('mySampleConverterConfig');">View as .grovvy</span>
+<pre id="mySampleConverterConfig" class="prettyprint source">&lt;configuration>
 
   <b>&lt;conversionRule conversionWord="sample" 
                   converterClass="chapters.layouts.MySampleConverter" /></b>
@@ -1606,7 +1614,7 @@ public class MySampleConverter extends ClassicConverter {
   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     &lt;encoder>
       &lt;pattern>%-4relative [%thread] <b>%sample</b> - %msg%n&lt;/pattern>
-    &lt;/encoder
+    &lt;/encoder>
   &lt;/appender>
 
   &lt;root level="DEBUG">
@@ -1681,7 +1689,8 @@ public class MySampleConverter extends ClassicConverter {
     </p>
 
 <em> Example: HTMLLayout Example (src/main/java/chapters/layouts/htmlLayoutConfig1.xml)</em>
-<pre class="prettyprint source">&lt;configuration debug="true"&gt;
+<span class="asGroovy" onclick="return asGroovy('htmlLayoutConfig1');">View as .grovvy</span>
+<pre id="htmlLayoutConfig1" class="prettyprint source">&lt;configuration debug="true"&gt;
   &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;
     &lt;encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
       &lt;layout class="ch.qos.logback.classic.html.HTMLLayout">
@@ -1793,7 +1802,8 @@ public class MySampleConverter extends ClassicConverter {
     <p>Here is a sample configuration</p>
 
 <em> Example: Log4jXMLLayout Example (src/main/java/chapters/layouts/log4jXMLLayout.xml)</em>
-    <pre class="prettyprint source">&lt;configuration>
+<span class="asGroovy" onclick="return asGroovy('log4jXMLLayout');">View as .grovvy</span>
+    <pre id="log4jXMLLayout" class="prettyprint source">&lt;configuration>
   &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
     &lt;file>test.xml&lt;/file>
     &lt;encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
diff --git a/logback-site/src/site/pages/templates/left.js b/logback-site/src/site/pages/templates/left.js
index b45f09c..dc1400b 100644
--- a/logback-site/src/site/pages/templates/left.js
+++ b/logback-site/src/site/pages/templates/left.js
@@ -16,6 +16,7 @@ document.write('<p class="menu"><a href="http://www.qos.ch/shop/products/trainin
 
 document.write('<p class="menu_header">Online Tools</p>');
 document.write('<p class="menu"><a href="http://logback.qos.ch/translator/">log4j.properties Translator</a>');
+document.write('<p class="menu"><a href="http://logback.qos.ch/translator/asGroovy.html">logback.XML to Groovy</a>');
 
 document.write('</p>');
 

-----------------------------------------------------------------------

Summary of changes:
 .../classic/gaffer/AppenderDelegate.groovy}        |   20 ++-
 .../classic/gaffer/ComponentDelegate.groovy        |  146 ++++++++++++++++++++
 .../classic/gaffer/ConfigurationDelegate.groovy    |  106 +++++++++++----
 .../qos/logback/classic/gaffer/Configurator.groovy |   45 +++----
 .../ch/qos/logback/classic/filter/LevelFilter.java |    4 +-
 .../logback/classic/gaffer/AppenderDelegate.groovy |   32 -----
 .../gaffer/ConfigurationDelegateTest.groovy        |   34 +++++-
 .../logback/classic/gaffer/ConfiguratorTest.groovy |  103 ++++++++++++++
 .../src/test/input/gaffer/conversionRule.groovy    |   13 ++
 .../src/test/input/gaffer/onTheFly.groovy          |    9 ++
 logback-classic/src/test/input/gaffer/smoke.groovy |   28 ++++
 .../qos/logback/classic/ClassicTestConstants.java  |   10 +-
 .../java/ch/qos/logback/core/util/ContextUtil.java |   17 ++-
 .../chapters/layouts/mySampleConverterConfig.xml   |    2 +-
 logback-site/src/site/pages/css/_print.css         |    3 +-
 logback-site/src/site/pages/css/common.css         |    2 +-
 logback-site/src/site/pages/css/screen.css         |   22 +++
 logback-site/src/site/pages/js/dsl.js              |   39 +++++
 logback-site/src/site/pages/manual/appenders.html  |  141 ++++++++++++--------
 .../src/site/pages/manual/configuration.html       |   80 +++++++----
 logback-site/src/site/pages/manual/filters.html    |   69 ++++++----
 logback-site/src/site/pages/manual/layouts.html    |   26 +++-
 logback-site/src/site/pages/templates/left.js      |    1 +
 23 files changed, 728 insertions(+), 224 deletions(-)
 copy logback-classic/src/main/{java/ch/qos/logback/classic/boolex/IEvaluator.java => groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy} (64%)
 create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
 delete mode 100644 logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/AppenderDelegate.groovy
 create mode 100644 logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/conversionRule.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/onTheFly.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/smoke.groovy
 create mode 100644 logback-site/src/site/pages/js/dsl.js


hooks/post-receive
-- 
Logback: the generic, reliable, fast and flexible logging framework.


More information about the logback-dev mailing list