You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by rg...@apache.org on 2010/10/25 07:09:09 UTC

svn commit: r1026947 [1/2] - in /logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src: main/java/org/apache/logging/log4j/core/appender/ main/java/org/apache/logging/log4j/core/config/ main/java/org/apache/logging/log4j/core/config/plu...

Author: rgoers
Date: Mon Oct 25 05:09:08 2010
New Revision: 1026947

URL: http://svn.apache.org/viewvc?rev=1026947&view=rev
Log:
Add support for variable substitution

Added:
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Property.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java
      - copied, changed from r1026837, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PropertiesPlugin.java
      - copied, changed from r1026837, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/FiltersPlugin.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrLookup.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrMatcher.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrSubstitutor.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/SystemPropertiesLookup.java
Modified:
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/AppenderRefPlugin.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MDCFilter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j-test1.xml

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java Mon Oct 25 05:09:08 2010
@@ -18,14 +18,11 @@ package org.apache.logging.log4j.core.ap
 
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
-import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 
-import java.util.Map;
-
 /**
  * ConsoleAppender appends log events to <code>System.out</code> or
  * <code>System.err</code> using a layout specified by the user. The

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java Mon Oct 25 05:09:08 2010
@@ -18,7 +18,6 @@ package org.apache.logging.log4j.core.ap
 
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
-import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
@@ -27,7 +26,6 @@ import org.apache.logging.log4j.core.con
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
-import java.util.Map;
 
 /**
  *

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java Mon Oct 25 05:09:08 2010
@@ -18,7 +18,6 @@ package org.apache.logging.log4j.core.ap
 
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
@@ -27,7 +26,6 @@ import org.apache.logging.log4j.core.con
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 /**
  * This appender is primarily used for testing. Use in a real environment is discouraged as the

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java Mon Oct 25 05:09:08 2010
@@ -24,7 +24,11 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginManager;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginType;
+import org.apache.logging.log4j.core.config.plugins.PluginValue;
 import org.apache.logging.log4j.core.helpers.NameUtil;
+import org.apache.logging.log4j.core.lookup.Interpolator;
+import org.apache.logging.log4j.core.lookup.MapLookup;
+import org.apache.logging.log4j.core.lookup.StrSubstitutor;
 import org.apache.logging.log4j.internal.StatusLogger;
 
 import java.lang.annotation.Annotation;
@@ -51,6 +55,8 @@ public class BaseConfiguration implement
 
     private ConcurrentMap<String, LoggerConfig> loggers = new ConcurrentHashMap<String, LoggerConfig>();
 
+    private StrSubstitutor subst = new StrSubstitutor();
+
     private LoggerConfig root = new LoggerConfig();
 
     private List<Filter> filters = new CopyOnWriteArrayList<Filter>();
@@ -99,12 +105,14 @@ public class BaseConfiguration implement
     }
 
     protected void doConfigure() {
-        createConfiguration(rootNode);
         for (Node child : rootNode.getChildren()) {
+            createConfiguration(child);
             if (child.getObject() == null) {
                 continue;
             }
-            if (child.getName().equals("appenders")) {
+            if (child.getName().equalsIgnoreCase("properties")) {
+                subst = (StrSubstitutor) child.getObject();
+            } else if (child.getName().equals("appenders")) {
                 appenders = (ConcurrentMap<String, Appender>) child.getObject();
             } else if (child.getName().equals("filters")) {
                 filters = new CopyOnWriteArrayList((Filter[]) child.getObject());
@@ -313,7 +321,7 @@ public class BaseConfiguration implement
     * @return the instantiate method or null if there is none by that
     * description.
     */
-    public static Object createPluginObject(PluginType type, Node node)
+    public Object createPluginObject(PluginType type, Node node)
     {
         Class clazz = type.getPluginClass();
 
@@ -383,9 +391,15 @@ public class BaseConfiguration implement
                 } else {
                     sb.append(", ");
                 }
+                if (a instanceof PluginValue) {
+                    String name = ((PluginValue)a).value();
+                    String value = subst.replace(node.getValue());
+                    sb.append(name +"=" + "\"" + value + "\"");
+                    parms[index] = value;
+                }
                 if (a instanceof PluginAttr) {
                     String name = ((PluginAttr)a).value();
-                    String value = getAttrValue(name, attrs);
+                    String value = subst.replace(getAttrValue(name, attrs));
                     sb.append(name +"=" + "\"" + value + "\"");
                     parms[index] = value;
                 } else if (a instanceof PluginElement) {
@@ -503,7 +517,7 @@ public class BaseConfiguration implement
         return null;
     }
 
-    private static void printArray(StringBuilder sb, Object[] array) {
+    private void printArray(StringBuilder sb, Object[] array) {
         boolean first = true;
         for (Object obj : array) {
             if (!first) {
@@ -513,7 +527,7 @@ public class BaseConfiguration implement
         }
     }
 
-    private static String getAttrValue(String name, Map<String, String>attrs) {
+    private String getAttrValue(String name, Map<String, String>attrs) {
         for (String key : attrs.keySet()) {
             if (key.equalsIgnoreCase(name)) {
                 String attr = attrs.get(key);

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Property.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Property.java?rev=1026947&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Property.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Property.java Mon Oct 25 05:09:08 2010
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.config;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.config.plugins.PluginValue;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+/**
+ *
+ */
+@Plugin(name = "property", type = "Core", printObject = true)
+public class Property {
+
+    protected final static Logger logger = StatusLogger.getLogger();
+
+    private String name;
+    private String value;
+
+    public Property(String name, String value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    @PluginFactory
+    public static Property createProperty(@PluginAttr("name") String key,
+                                          @PluginValue("value") String value) {
+        if (key == null) {
+            logger.error("Property key cannot be null");
+        }
+        return new Property(key, value);
+    }
+
+    public String toString() {
+        return name + "=" + value;
+    }
+}

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java Mon Oct 25 05:09:08 2010
@@ -17,11 +17,6 @@
 package org.apache.logging.log4j.core.config;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.Filter;
-import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttr;
-import org.apache.logging.log4j.core.config.plugins.PluginElement;
-import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.config.plugins.PluginManager;
 import org.apache.logging.log4j.core.config.plugins.PluginType;
 import org.apache.logging.log4j.core.config.plugins.ResolverUtil;
@@ -41,7 +36,6 @@ import javax.xml.parsers.DocumentBuilder
 import javax.xml.parsers.ParserConfigurationException;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/AppenderRefPlugin.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/AppenderRefPlugin.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/AppenderRefPlugin.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/AppenderRefPlugin.java Mon Oct 25 05:09:08 2010
@@ -16,9 +16,8 @@
  */
 package org.apache.logging.log4j.core.config.plugins;
 
-import org.apache.logging.log4j.core.config.Node;
-
-import java.util.Map;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.internal.StatusLogger;
 
 /**
  *
@@ -26,8 +25,14 @@ import java.util.Map;
 @Plugin(name = "appender-ref", type = "Core", printObject = true)
 public class AppenderRefPlugin {
 
+    protected final static Logger logger = StatusLogger.getLogger();
+
     @PluginFactory
     public static String createAppenderRef(@PluginAttr("ref") String ref) {
+
+        if (ref == null) {
+            logger.error("Appender references must contain a reference");
+        }
         return ref;
     }
 }

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java?rev=1026947&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java Mon Oct 25 05:09:08 2010
@@ -0,0 +1,16 @@
+package org.apache.logging.log4j.core.config.plugins;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface PluginAttr {
+
+    public String value();
+}

Copied: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java (from r1026837, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java?p2=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java&p1=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java&r1=1026837&r2=1026947&rev=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttr.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java Mon Oct 25 05:09:08 2010
@@ -10,7 +10,7 @@ import java.lang.annotation.Target;
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.PARAMETER)
-public @interface PluginAttr {
+public @interface PluginValue {
 
     public String value();
 }

Copied: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PropertiesPlugin.java (from r1026837, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/FiltersPlugin.java)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PropertiesPlugin.java?p2=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PropertiesPlugin.java&p1=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/FiltersPlugin.java&r1=1026837&r2=1026947&rev=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/FiltersPlugin.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PropertiesPlugin.java Mon Oct 25 05:09:08 2010
@@ -16,16 +16,29 @@
  */
 package org.apache.logging.log4j.core.config.plugins;
 
-import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.config.Property;
+import org.apache.logging.log4j.core.lookup.Interpolator;
+import org.apache.logging.log4j.core.lookup.MapLookup;
+import org.apache.logging.log4j.core.lookup.StrSubstitutor;
+
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  *
  */
-@Plugin(name="filters", type="Core")
-public class FiltersPlugin {
+@Plugin(name="properties", type="Core", printObject=true)
+public class PropertiesPlugin {
 
     @PluginFactory
-    public static Filter[] createFilters(@PluginElement("filters") Filter[] filters) {
-        return filters;
+    public static StrSubstitutor configureSubstitutor(@PluginElement("properties") Property[] properties) {
+        Map<String, String> map = new HashMap<String, String>();
+        
+        for (Property prop : properties) {
+            map.put(prop.getName(), prop.getValue());
+        }
+
+        Interpolator inter = new Interpolator(properties == null ? null : new MapLookup(map));
+        return new StrSubstitutor(inter);
     }
 }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MDCFilter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MDCFilter.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MDCFilter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MDCFilter.java Mon Oct 25 05:09:08 2010
@@ -21,14 +21,11 @@ import org.apache.logging.log4j.ThreadCo
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.message.Message;
 
-import java.util.Map;
-
 /**
  *
  */

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java Mon Oct 25 05:09:08 2010
@@ -20,14 +20,11 @@ import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.message.Message;
 
-import java.util.Map;
-
 /**
  * This filter returns the onMatch result if the level in the LogEvent is the same or more specific
  * than the configured level and the onMismatch value otherwise. For example, if the ThresholdFilter

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java?rev=1026947&r1=1026946&r2=1026947&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java Mon Oct 25 05:09:08 2010
@@ -18,7 +18,6 @@
 package org.apache.logging.log4j.core.layout;
 
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
@@ -27,7 +26,6 @@ import org.apache.logging.log4j.core.lay
 import org.apache.logging.log4j.core.layout.pattern.PatternParser;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * <p>A flexible layout configurable with pattern string. The goal of this class

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java?rev=1026947&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java Mon Oct 25 05:09:08 2010
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.lookup;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+/**
+ * Looks up keys from system properties
+ */
+@Plugin(name="ctx",type="Lookup")
+public class ContextMapLookup implements StrLookup {
+
+    public String lookup(String key) {
+        return ThreadContext.get(key).toString();
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java?rev=1026947&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java Mon Oct 25 05:09:08 2010
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.lookup;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.config.plugins.PluginManager;
+import org.apache.logging.log4j.core.config.plugins.PluginType;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public class Interpolator implements StrLookup {
+
+    protected final static Logger logger = StatusLogger.getLogger();
+
+    /** Constant for the prefix separator. */
+    private static final char PREFIX_SEPARATOR = ':';
+
+    private final Map<String, StrLookup> lookups = new HashMap<String, StrLookup>();
+
+    private final StrLookup defaultLookup;
+
+    public Interpolator(StrLookup defaultLookup) {
+        this.defaultLookup = defaultLookup;
+        PluginManager manager = new PluginManager("Lookup");
+        manager.collectPlugins();
+        Map<String, PluginType> plugins = manager.getPlugins();
+        Map<String, StrLookup> lookups = new HashMap<String, StrLookup>();
+
+        for (Map.Entry<String, PluginType> entry : plugins.entrySet()) {
+            Class<StrLookup> clazz = entry.getValue().getPluginClass();
+            try {
+                lookups.put(entry.getKey(), clazz.newInstance());
+            } catch (Exception ex) {
+                logger.error("Unable to create Lookup for " + entry.getKey(), ex);
+            }
+        }
+    }
+
+     /**
+     * Resolves the specified variable. This implementation will try to extract
+     * a variable prefix from the given variable name (the first colon (':') is
+     * used as prefix separator). It then passes the name of the variable with
+     * the prefix stripped to the lookup object registered for this prefix. If
+     * no prefix can be found or if the associated lookup object cannot resolve
+     * this variable, the default lookup object will be used.
+     *
+     * @param var the name of the variable whose value is to be looked up
+     * @return the value of this variable or <b>null</b> if it cannot be
+     * resolved
+     */
+    public String lookup(String var)
+    {
+        if (var == null)
+        {
+            return null;
+        }
+
+        int prefixPos = var.indexOf(PREFIX_SEPARATOR);
+        if (prefixPos >= 0)
+        {
+            String prefix = var.substring(0, prefixPos);
+            String name = var.substring(prefixPos + 1);
+            StrLookup lookup = lookups.get(prefix);
+            String value = null;
+            if (lookup != null) {
+                value = lookup.lookup(name);
+            }
+
+            if (value != null)
+            {
+                return value;
+            }
+            var = var.substring(prefixPos);
+        }
+        if (defaultLookup != null) {
+            return defaultLookup.lookup(var);
+        }
+        return null;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        for (String name : lookups.keySet()) {
+            if (sb.length() == 0) {
+                sb.append("{");
+            } else {
+                sb.append(", ");
+            }
+
+            sb.append(name);
+        }
+        if (sb.length() > 0) {
+            sb.append("}");
+        }
+        return sb.toString();
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java?rev=1026947&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/MapLookup.java Mon Oct 25 05:09:08 2010
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.lookup;
+
+import java.util.Map;
+
+/**
+ * The basis for a lookup based on a Map.
+ */
+public class MapLookup<V> implements StrLookup<V> {
+    /**
+     * Map keys are variable names and value.
+     */
+    private final Map<String, V> map;
+
+    /**
+     * Creates a new instance backed by a Map.
+     *
+     * @param map the map of keys to values, may be null
+     */
+    public MapLookup(Map<String, V> map) {
+        this.map = map;
+    }
+
+    /**
+     * Looks up a String key to a String value using the map.
+     * <p/>
+     * If the map is null, then null is returned.
+     * The map result object is converted to a string using toString().
+     *
+     * @param key the key to be looked up, may be null
+     * @return the matching value, null if no match
+     */
+    public String lookup(String key) {
+        if (map == null) {
+            return null;
+        }
+        Object obj = map.get(key);
+        if (obj == null) {
+            return null;
+        }
+        return obj.toString();
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrLookup.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrLookup.java?rev=1026947&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrLookup.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrLookup.java Mon Oct 25 05:09:08 2010
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.lookup;
+
+/**
+ * Lookup a String key to a String value.
+ * <p>
+ * This class represents the simplest form of a string to string map.
+ * It has a benefit over a map in that it can create the result on
+ * demand based on the key.
+ * <p>
+ * This class comes complete with various factory methods.
+ * If these do not suffice, you can subclass and implement your own matcher.
+ * <p>
+ * For example, it would be possible to implement a lookup that used the
+ * key as a primary key, and looked up the value on demand from the database
+ *
+ * @author Apache Software Foundation
+ * @version $Id$
+ */
+public interface StrLookup<V> {
+    /**
+     * Looks up a String key to a String value.
+     * <p>
+     * The internal implementation may use any mechanism to return the value.
+     * The simplest implementation is to use a Map. However, virtually any
+     * implementation is possible.
+     * <p>
+     * For example, it would be possible to implement a lookup that used the
+     * key as a primary key, and looked up the value on demand from the database
+     * Or, a numeric based implementation could be created that treats the key
+     * as an integer, increments the value and return the result as a string -
+     * converting 1 to 2, 15 to 16 etc.
+     * <p>
+     * The {@link #lookup(String)} method always returns a String, regardless of
+     * the underlying data, by converting it as necessary. For example:
+     * <pre>
+     * Map<String, Object> map = new HashMap<String, Object>();
+     * map.put("number", new Integer(2));
+     * assertEquals("2", StrLookup.mapLookup(map).lookup("number"));
+     * </pre>
+     * @param key  the key to be looked up, may be null
+     * @return the matching value, null if no match
+     */
+    public String lookup(String key);
+}
\ No newline at end of file

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrMatcher.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrMatcher.java?rev=1026947&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrMatcher.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/lookup/StrMatcher.java Mon Oct 25 05:09:08 2010
@@ -0,0 +1,435 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.lookup;
+
+import java.util.Arrays;
+
+/**
+ * A matcher class that can be queried to determine if a character array
+ * portion matches.
+ * <p>
+ * This class comes complete with various factory methods.
+ * If these do not suffice, you can subclass and implement your own matcher.
+ *
+ * @author Apache Software Foundation
+ * @since 2.2
+ * @version $Id$
+ */
+public abstract class StrMatcher {
+
+    /**
+     * Matches the comma character.
+     */
+    private static final StrMatcher COMMA_MATCHER = new CharMatcher(',');
+    /**
+     * Matches the tab character.
+     */
+    private static final StrMatcher TAB_MATCHER = new CharMatcher('\t');
+    /**
+     * Matches the space character.
+     */
+    private static final StrMatcher SPACE_MATCHER = new CharMatcher(' ');
+    /**
+     * Matches the same characters as StringTokenizer,
+     * namely space, tab, newline, formfeed.
+     */
+    private static final StrMatcher SPLIT_MATCHER = new CharSetMatcher(" \t\n\r\f".toCharArray());
+    /**
+     * Matches the String trim() whitespace characters.
+     */
+    private static final StrMatcher TRIM_MATCHER = new TrimMatcher();
+    /**
+     * Matches the double quote character.
+     */
+    private static final StrMatcher SINGLE_QUOTE_MATCHER = new CharMatcher('\'');
+    /**
+     * Matches the double quote character.
+     */
+    private static final StrMatcher DOUBLE_QUOTE_MATCHER = new CharMatcher('"');
+    /**
+     * Matches the single or double quote character.
+     */
+    private static final StrMatcher QUOTE_MATCHER = new CharSetMatcher("'\"".toCharArray());
+    /**
+     * Matches no characters.
+     */
+    private static final StrMatcher NONE_MATCHER = new NoMatcher();
+
+    // -----------------------------------------------------------------------
+
+    /**
+     * Returns a matcher which matches the comma character.
+     *
+     * @return a matcher for a comma
+     */
+    public static StrMatcher commaMatcher() {
+        return COMMA_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the tab character.
+     *
+     * @return a matcher for a tab
+     */
+    public static StrMatcher tabMatcher() {
+        return TAB_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the space character.
+     *
+     * @return a matcher for a space
+     */
+    public static StrMatcher spaceMatcher() {
+        return SPACE_MATCHER;
+    }
+
+    /**
+     * Matches the same characters as StringTokenizer,
+     * namely space, tab, newline and formfeed.
+     *
+     * @return the split matcher
+     */
+    public static StrMatcher splitMatcher() {
+        return SPLIT_MATCHER;
+    }
+
+    /**
+     * Matches the String trim() whitespace characters.
+     *
+     * @return the trim matcher
+     */
+    public static StrMatcher trimMatcher() {
+        return TRIM_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the single quote character.
+     *
+     * @return a matcher for a single quote
+     */
+    public static StrMatcher singleQuoteMatcher() {
+        return SINGLE_QUOTE_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the double quote character.
+     *
+     * @return a matcher for a double quote
+     */
+    public static StrMatcher doubleQuoteMatcher() {
+        return DOUBLE_QUOTE_MATCHER;
+    }
+
+    /**
+     * Returns a matcher which matches the single or double quote character.
+     *
+     * @return a matcher for a single or double quote
+     */
+    public static StrMatcher quoteMatcher() {
+        return QUOTE_MATCHER;
+    }
+
+    /**
+     * Matches no characters.
+     *
+     * @return a matcher that matches nothing
+     */
+    public static StrMatcher noneMatcher() {
+        return NONE_MATCHER;
+    }
+
+    /**
+     * Constructor that creates a matcher from a character.
+     *
+     * @param ch  the character to match, must not be null
+     * @return a new Matcher for the given char
+     */
+    public static StrMatcher charMatcher(char ch) {
+        return new CharMatcher(ch);
+    }
+
+    /**
+     * Constructor that creates a matcher from a set of characters.
+     *
+     * @param chars  the characters to match, null or empty matches nothing
+     * @return a new matcher for the given char[]
+     */
+    public static StrMatcher charSetMatcher(char[] chars) {
+        if (chars == null || chars.length == 0) {
+            return NONE_MATCHER;
+        }
+        if (chars.length == 1) {
+            return new CharMatcher(chars[0]);
+        }
+        return new CharSetMatcher(chars);
+    }
+
+    /**
+     * Constructor that creates a matcher from a string representing a set of characters.
+     *
+     * @param chars  the characters to match, null or empty matches nothing
+     * @return a new Matcher for the given characters
+     */
+    public static StrMatcher charSetMatcher(String chars) {
+        if (chars == null || chars.length() == 0) {
+            return NONE_MATCHER;
+        }
+        if (chars.length() == 1) {
+            return new CharMatcher(chars.charAt(0));
+        }
+        return new CharSetMatcher(chars.toCharArray());
+    }
+
+    /**
+     * Constructor that creates a matcher from a string.
+     *
+     * @param str  the string to match, null or empty matches nothing
+     * @return a new Matcher for the given String
+     */
+    public static StrMatcher stringMatcher(String str) {
+        if (str == null || str.length() == 0) {
+            return NONE_MATCHER;
+        }
+        return new StringMatcher(str);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Constructor.
+     */
+    protected StrMatcher() {
+        super();
+    }
+
+    /**
+     * Returns the number of matching characters, zero for no match.
+     * <p>
+     * This method is called to check for a match.
+     * The parameter <code>pos</code> represents the current position to be
+     * checked in the string <code>buffer</code> (a character array which must
+     * not be changed).
+     * The API guarantees that <code>pos</code> is a valid index for <code>buffer</code>.
+     * <p>
+     * The character array may be larger than the active area to be matched.
+     * Only values in the buffer between the specifed indices may be accessed.
+     * <p>
+     * The matching code may check one character or many.
+     * It may check characters preceeding <code>pos</code> as well as those
+     * after, so long as no checks exceed the bounds specified.
+     * <p>
+     * It must return zero for no match, or a positive number if a match was found.
+     * The number indicates the number of characters that matched.
+     *
+     * @param buffer  the text content to match against, do not change
+     * @param pos  the starting position for the match, valid for buffer
+     * @param bufferStart  the first active index in the buffer, valid for buffer
+     * @param bufferEnd  the end index (exclusive) of the active buffer, valid for buffer
+     * @return the number of matching characters, zero for no match
+     */
+    public abstract int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd);
+
+    /**
+     * Returns the number of matching characters, zero for no match.
+     * <p>
+     * This method is called to check for a match.
+     * The parameter <code>pos</code> represents the current position to be
+     * checked in the string <code>buffer</code> (a character array which must
+     * not be changed).
+     * The API guarantees that <code>pos</code> is a valid index for <code>buffer</code>.
+     * <p>
+     * The matching code may check one character or many.
+     * It may check characters preceeding <code>pos</code> as well as those after.
+     * <p>
+     * It must return zero for no match, or a positive number if a match was found.
+     * The number indicates the number of characters that matched.
+     *
+     * @param buffer  the text content to match against, do not change
+     * @param pos  the starting position for the match, valid for buffer
+     * @return the number of matching characters, zero for no match
+     * @since 2.4
+     */
+    public int isMatch(char[] buffer, int pos) {
+        return isMatch(buffer, pos, 0, buffer.length);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to define a set of characters for matching purposes.
+     */
+    static final class CharSetMatcher extends StrMatcher {
+        /** The set of characters to match. */
+        private final char[] chars;
+
+        /**
+         * Constructor that creates a matcher from a character array.
+         *
+         * @param chars  the characters to match, must not be null
+         */
+        CharSetMatcher(char chars[]) {
+            super();
+            this.chars = chars.clone();
+            Arrays.sort(this.chars);
+        }
+
+        /**
+         * Returns whether or not the given character matches.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        @Override
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            return Arrays.binarySearch(chars, buffer[pos]) >= 0 ? 1 : 0;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to define a character for matching purposes.
+     */
+    static final class CharMatcher extends StrMatcher {
+        /** The character to match. */
+        private final char ch;
+
+        /**
+         * Constructor that creates a matcher that matches a single character.
+         *
+         * @param ch  the character to match
+         */
+        CharMatcher(char ch) {
+            super();
+            this.ch = ch;
+        }
+
+        /**
+         * Returns whether or not the given character matches.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        @Override
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            return ch == buffer[pos] ? 1 : 0;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to define a set of characters for matching purposes.
+     */
+    static final class StringMatcher extends StrMatcher {
+        /** The string to match, as a character array. */
+        private final char[] chars;
+
+        /**
+         * Constructor that creates a matcher from a String.
+         *
+         * @param str  the string to match, must not be null
+         */
+        StringMatcher(String str) {
+            super();
+            chars = str.toCharArray();
+        }
+
+        /**
+         * Returns whether or not the given text matches the stored string.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        @Override
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            int len = chars.length;
+            if (pos + len > bufferEnd) {
+                return 0;
+            }
+            for (int i = 0; i < chars.length; i++, pos++) {
+                if (chars[i] != buffer[pos]) {
+                    return 0;
+                }
+            }
+            return len;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to match no characters.
+     */
+    static final class NoMatcher extends StrMatcher {
+
+        /**
+         * Constructs a new instance of <code>NoMatcher</code>.
+         */
+        NoMatcher() {
+            super();
+        }
+
+        /**
+         * Always returns <code>false</code>.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        @Override
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            return 0;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Class used to match whitespace as per trim().
+     */
+    static final class TrimMatcher extends StrMatcher {
+
+        /**
+         * Constructs a new instance of <code>TrimMatcher</code>.
+         */
+        TrimMatcher() {
+            super();
+        }
+
+        /**
+         * Returns whether or not the given character matches.
+         *
+         * @param buffer  the text content to match against, do not change
+         * @param pos  the starting position for the match, valid for buffer
+         * @param bufferStart  the first active index in the buffer, valid for buffer
+         * @param bufferEnd  the end index of the active buffer, valid for buffer
+         * @return the number of matching characters, zero for no match
+         */
+        @Override
+        public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
+            return buffer[pos] <= 32 ? 1 : 0;
+        }
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org