logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rgo...@apache.org
Subject svn commit: r943816 [6/9] - in /logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers: ./ log4j12-api/ log4j12-api/src/ log4j12-api/src/main/ log4j12-api/src/main/java/ log4j12-api/src/main/java/org/ log4j12-api/src/main/java/org/apache/ log4j12-api/sr...
Date Thu, 13 May 2010 06:31:09 GMT
Added: 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=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,89 @@
+/*
+ * 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.filter;
+
+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.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
+ * is configured with Level ERROR and the LogEvent contains Level DEBUG then the onMismatch value will
+ * be returned since ERROR events are more specific than DEBUG.
+ *
+ * The default Level is ERROR.
+ */
+@Plugin(name="Threshold", type="Core")
+public class ThresholdFilter extends FilterBase {
+
+    private static final String LEVEL = "level";
+
+    private final Level level;
+
+    public ThresholdFilter(Level level, Result onMatch, Result onMismatch) {
+        super(onMatch, onMismatch);
+        this.level = level;
+    }
+
+    public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
+        return filter(level);
+    }
+
+    public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
+        return filter(level);
+    }
+
+    public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
+        return filter(level);
+    }
+
+    @Override
+    public Result filter(LogEvent event) {
+        return filter(event.getLevel());
+    }
+
+    private Result filter(Level level) {
+        return this.level.greaterOrEqual(level) ? onMatch : onMismatch;
+    }
+
+    @PluginFactory
+    public static ThresholdFilter createFilter(Node node) {
+        Level level = null;
+        Result onMatch = null;
+        Result onMismatch = null;
+        for (Map.Entry<String, String> entry : node.getAttributes().entrySet()) {
+            String name = entry.getKey().toLowerCase();
+            if (name.equals(LEVEL)) {
+                level = Level.toLevel(entry.getValue().toUpperCase(), Level.ERROR);
+            } else if (name.equals(ON_MATCH)) {
+                onMatch = Result.valueOf(entry.getValue());
+            } else if (name.equals(ON_MISMATCH)) {
+                onMismatch = Result.valueOf(entry.getValue());
+            }
+        }
+        return new ThresholdFilter(level, onMatch, onMismatch);
+    }
+
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/helpers/Loader.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/helpers/Loader.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/helpers/Loader.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/helpers/Loader.java Thu May 13 06:31:04 2010
@@ -0,0 +1,139 @@
+/*
+ * 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.helpers;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import java.net.URL;
+import java.lang.IllegalAccessException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.io.InterruptedIOException;
+
+
+/**
+ * Load resources (or images) from various sources.
+ */
+
+public class Loader {
+
+    static final String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous.";
+
+    static private boolean ignoreTCL = false;
+
+    static Logger logger = StatusLogger.getLogger();
+
+    static {
+        String ignoreTCLProp = OptionConverter.getSystemProperty("log4j.ignoreTCL", null);
+        if (ignoreTCLProp != null) {
+            ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true);
+        }
+    }
+
+    /**
+     * This method will search for <code>resource</code> in different
+     * places. The search order is as follows:
+     * <p/>
+     * <ol>
+     * <p/>
+     * <p><li>Search for <code>resource</code> using the thread context
+     * class loader under Java2. If that fails, search for
+     * <code>resource</code> using the class loader that loaded this
+     * class (<code>Loader</code>). Under JDK 1.1, only the the class
+     * loader that loaded this class (<code>Loader</code>) is used.
+     * <p/>
+     * <p><li>Try one last time with
+     * <code>ClassLoader.getSystemResource(resource)</code>, that is is
+     * using the system class loader in JDK 1.2 and virtual machine's
+     * built-in class loader in JDK 1.1.
+     * <p/>
+     * </ol>
+     */
+    static public URL getResource(String resource) {
+        ClassLoader classLoader = null;
+        URL url = null;
+
+        try {
+            classLoader = getTCL();
+            if (classLoader != null) {
+                logger.debug("Trying to find [" + resource + "] using context classloader "
+                        + classLoader + ".");
+                url = classLoader.getResource(resource);
+                if (url != null) {
+                    return url;
+                }
+            }
+
+            // We could not find resource. Ler us now try with the
+            // classloader that loaded this class.
+            classLoader = Loader.class.getClassLoader();
+            if (classLoader != null) {
+                logger.debug("Trying to find [" + resource + "] using " + classLoader
+                    + " class loader.");
+                url = classLoader.getResource(resource);
+                if (url != null) {
+                    return url;
+                }
+            }
+        } catch (IllegalAccessException t) {
+            logger.warn(TSTR, t);
+        } catch (InvocationTargetException t) {
+            if (t.getTargetException() instanceof InterruptedException
+                || t.getTargetException() instanceof InterruptedIOException) {
+                Thread.currentThread().interrupt();
+            }
+            logger.warn(TSTR, t);
+        } catch (Throwable t) {
+            //
+            //  can't be InterruptedException or InterruptedIOException
+            //    since not declared, must be error or RuntimeError.
+            logger.warn(TSTR, t);
+        }
+
+        // Last ditch attempt: get the resource from the class path. It
+        // may be the case that clazz was loaded by the Extentsion class
+        // loader which the parent of the system class loader. Hence the
+        // code below.
+        logger.debug("Trying to find [" + resource + "] using ClassLoader.getSystemResource().");
+        return ClassLoader.getSystemResource(resource);
+    }
+
+    /**
+     * Get the Thread Context Loader which is a JDK 1.2 feature. If we
+     * are running under JDK 1.1 or anything else goes wrong the method
+     * returns <code>null<code>.
+     */
+    private static ClassLoader getTCL() throws IllegalAccessException, InvocationTargetException {
+        return Thread.currentThread().getContextClassLoader();
+    }
+
+    public static Class loadClass(String clazz) throws ClassNotFoundException {
+        // Just call Class.forName(clazz) if we are instructed to ignore the TCL.
+        if (ignoreTCL) {
+            return Class.forName(clazz);
+        } else {
+            try {
+                return getTCL().loadClass(clazz);
+            }
+            catch (Throwable e) {
+                return Class.forName(clazz);
+            }
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/helpers/OptionConverter.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/helpers/OptionConverter.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/helpers/OptionConverter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/helpers/OptionConverter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,347 @@
+/*
+ * 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.helpers;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import java.util.Properties;
+
+/**
+ * A convenience class to convert property values to specific types.
+ */
+public class OptionConverter {
+
+    private static Logger logger = StatusLogger.getLogger();
+
+    static String DELIM_START = "${";
+    static char DELIM_STOP = '}';
+    static int DELIM_START_LEN = 2;
+    static int DELIM_STOP_LEN = 1;
+
+    /**
+     * OptionConverter is a static class.
+     */
+    private OptionConverter() {
+    }
+
+    public static String[] concatanateArrays(String[] l, String[] r) {
+        int len = l.length + r.length;
+        String[] a = new String[len];
+
+        System.arraycopy(l, 0, a, 0, l.length);
+        System.arraycopy(r, 0, a, l.length, r.length);
+
+        return a;
+    }
+
+    public static String convertSpecialChars(String s) {
+        char c;
+        int len = s.length();
+        StringBuffer sbuf = new StringBuffer(len);
+
+        int i = 0;
+        while (i < len) {
+            c = s.charAt(i++);
+            if (c == '\\') {
+                c = s.charAt(i++);
+                if (c == 'n') {
+                    c = '\n';
+                } else if (c == 'r') {
+                    c = '\r';
+                } else if (c == 't') {
+                    c = '\t';
+                } else if (c == 'f') {
+                    c = '\f';
+                } else if (c == '\b') {
+                    c = '\b';
+                } else if (c == '\"') {
+                    c = '\"';
+                } else if (c == '\'') {
+                    c = '\'';
+                } else if (c == '\\') {
+                    c = '\\';
+                }
+            }
+            sbuf.append(c);
+        }
+        return sbuf.toString();
+    }
+
+
+    /**
+     * Very similar to <code>System.getProperty</code> except
+     * that the {@link SecurityException} is hidden.
+     *
+     * @param key The key to search for.
+     * @param def The default value to return.
+     * @return the string value of the system property, or the default
+     *         value if there is no property with that key.
+     */
+    public static String getSystemProperty(String key, String def) {
+        try {
+            return System.getProperty(key, def);
+        } catch (Throwable e) { // MS-Java throws com.ms.security.SecurityExceptionEx
+            logger.debug("Was not allowed to read system property \"" + key + "\".");
+            return def;
+        }
+    }
+
+
+    public static Object instantiateByKey(Properties props, String key, Class superClass,
+                                   Object defaultValue) {
+
+        // Get the value of the property in string form
+        String className = findAndSubst(key, props);
+        if (className == null) {
+            logger.error("Could not find value for key " + key);
+            return defaultValue;
+        }
+        // Trim className to avoid trailing spaces that cause problems.
+        return OptionConverter.instantiateByClassName(className.trim(), superClass,
+            defaultValue);
+    }
+
+    /**
+     * If <code>value</code> is "true", then <code>true</code> is
+     * returned. If <code>value</code> is "false", then
+     * <code>true</code> is returned. Otherwise, <code>default</code> is
+     * returned.
+     * <p/>
+     * <p>Case of value is unimportant.
+     */
+    public static boolean toBoolean(String value, boolean dEfault) {
+        if (value == null) {
+            return dEfault;
+        }
+        String trimmedVal = value.trim();
+        if ("true".equalsIgnoreCase(trimmedVal)) {
+            return true;
+        }
+        if ("false".equalsIgnoreCase(trimmedVal)) {
+            return false;
+        }
+        return dEfault;
+    }
+
+    /**
+     * Convert the String value to an int.
+     * @param value The value as a String.
+     * @param dEfault The default value.
+     * @return The value as an int.
+     */
+    public static int toInt(String value, int dEfault) {
+        if (value != null) {
+            String s = value.trim();
+            try {
+                return Integer.valueOf(s);
+            }
+            catch (NumberFormatException e) {
+                logger.error("[" + s + "] is not in proper int form.");
+                e.printStackTrace();
+            }
+        }
+        return dEfault;
+    }
+
+    /**
+     *
+     * @param value The size of the file as a String.
+     * @param dEfault The default value.
+     * @return The size of the file as a long.
+     */
+    public static long toFileSize(String value, long dEfault) {
+        if (value == null) {
+            return dEfault;
+        }
+
+        String s = value.trim().toUpperCase();
+        long multiplier = 1;
+        int index;
+
+        if ((index = s.indexOf("KB")) != -1) {
+            multiplier = 1024;
+            s = s.substring(0, index);
+        } else if ((index = s.indexOf("MB")) != -1) {
+            multiplier = 1024 * 1024;
+            s = s.substring(0, index);
+        } else if ((index = s.indexOf("GB")) != -1) {
+            multiplier = 1024 * 1024 * 1024;
+            s = s.substring(0, index);
+        }
+        if (s != null) {
+            try {
+                return Long.valueOf(s) * multiplier;
+            }
+            catch (NumberFormatException e) {
+                logger.error("[" + s + "] is not in proper int form.");
+                logger.error("[" + value + "] not in expected format.", e);
+            }
+        }
+        return dEfault;
+    }
+
+    /**
+     * Find the value corresponding to <code>key</code> in
+     * <code>props</code>. Then perform variable substitution on the
+     * found value.
+     * @param key The key to locate.
+     * @param props The properties.
+     * @return The String after substitution.
+     */
+    public static String findAndSubst(String key, Properties props) {
+        String value = props.getProperty(key);
+        if (value == null) {
+            return null;
+        }
+
+        try {
+            return substVars(value, props);
+        } catch (IllegalArgumentException e) {
+            logger.error("Bad option value [" + value + "].", e);
+            return value;
+        }
+    }
+
+    /**
+     * Instantiate an object given a class name. Check that the
+     * <code>className</code> is a subclass of
+     * <code>superClass</code>. If that test fails or the object could
+     * not be instantiated, then <code>defaultValue</code> is returned.
+     *
+     * @param className    The fully qualified class name of the object to instantiate.
+     * @param superClass   The class to which the new object should belong.
+     * @param defaultValue The object to return in case of non-fulfillment
+     * @return The created object.
+     */
+    public static Object instantiateByClassName(String className, Class superClass,
+                                         Object defaultValue) {
+        if (className != null) {
+            try {
+                Class classObj = Loader.loadClass(className);
+                if (!superClass.isAssignableFrom(classObj)) {
+                    logger.error("A \"" + className + "\" object is not assignable to a \"" +
+                        superClass.getName() + "\" variable.");
+                    logger.error("The class \"" + superClass.getName() + "\" was loaded by ");
+                    logger.error("[" + superClass.getClassLoader() + "] whereas object of type ");
+                    logger.error("\"" + classObj.getName() + "\" was loaded by ["
+                        + classObj.getClassLoader() + "].");
+                    return defaultValue;
+                }
+                return classObj.newInstance();
+            } catch (ClassNotFoundException e) {
+                logger.error("Could not instantiate class [" + className + "].", e);
+            } catch (IllegalAccessException e) {
+                logger.error("Could not instantiate class [" + className + "].", e);
+            } catch (InstantiationException e) {
+                logger.error("Could not instantiate class [" + className + "].", e);
+            } catch (RuntimeException e) {
+                logger.error("Could not instantiate class [" + className + "].", e);
+            }
+        }
+        return defaultValue;
+    }
+
+
+    /**
+     * Perform variable substitution in string <code>val</code> from the
+     * values of keys found in the system propeties.
+     * <p/>
+     * <p>The variable substitution delimeters are <b>${</b> and <b>}</b>.
+     * <p/>
+     * <p>For example, if the System properties contains "key=value", then
+     * the call
+     * <pre>
+     * String s = OptionConverter.substituteVars("Value of key is ${key}.");
+     * </pre>
+     * <p/>
+     * will set the variable <code>s</code> to "Value of key is value.".
+     * <p/>
+     * <p>If no value could be found for the specified key, then the
+     * <code>props</code> parameter is searched, if the value could not
+     * be found there, then substitution defaults to the empty string.
+     * <p/>
+     * <p>For example, if system propeties contains no value for the key
+     * "inexistentKey", then the call
+     * <p/>
+     * <pre>
+     * String s = OptionConverter.subsVars("Value of inexistentKey is [${inexistentKey}]");
+     * </pre>
+     * will set <code>s</code> to "Value of inexistentKey is []"
+     * <p/>
+     * <p>An {@link java.lang.IllegalArgumentException} is thrown if
+     * <code>val</code> contains a start delimeter "${" which is not
+     * balanced by a stop delimeter "}". </p>
+     * <p/>
+     * <p><b>Author</b> Avy Sharell</a></p>
+     *
+     * @param val The string on which variable substitution is performed.
+     * @param props The properties to use for substitution.
+     * @return The String after substitution.
+     * @throws IllegalArgumentException if <code>val</code> is malformed.
+     */
+    public static String substVars(String val, Properties props) throws
+        IllegalArgumentException {
+
+        StringBuilder sbuf = new StringBuilder();
+
+        int i = 0;
+        int j, k;
+
+        while (true) {
+            j = val.indexOf(DELIM_START, i);
+            if (j == -1) {
+                // no more variables
+                if (i == 0) { // this is a simple string
+                    return val;
+                } else { // add the tail string which contails no variables and return the result.
+                    sbuf.append(val.substring(i, val.length()));
+                    return sbuf.toString();
+                }
+            } else {
+                sbuf.append(val.substring(i, j));
+                k = val.indexOf(DELIM_STOP, j);
+                if (k == -1) {
+                    throw new IllegalArgumentException('"' + val +
+                        "\" has no closing brace. Opening brace at position " + j
+                        + '.');
+                } else {
+                    j += DELIM_START_LEN;
+                    String key = val.substring(j, k);
+                    // first try in System properties
+                    String replacement = getSystemProperty(key, null);
+                    // then try props parameter
+                    if (replacement == null && props != null) {
+                        replacement = props.getProperty(key);
+                    }
+
+                    if (replacement != null) {
+                        // Do variable substitution on the replacement string
+                        // such that we can solve "Hello ${x2}" as "Hello p1"
+                        // the where the properties are
+                        // x1=p1
+                        // x2=${x1}
+                        String recursiveReplacement = substVars(replacement, props);
+                        sbuf.append(recursiveReplacement);
+                    }
+                    i = k + DELIM_STOP_LEN;
+                }
+            }
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/LayoutBase.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/LayoutBase.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/LayoutBase.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/LayoutBase.java Thu May 13 06:31:04 2010
@@ -0,0 +1,48 @@
+/*
+ * 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.layout;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+/**
+ *
+ */
+public abstract class LayoutBase implements Layout {
+
+    protected byte[] header;
+    protected byte[] footer;
+
+    protected static Logger logger = StatusLogger.getLogger();
+
+    public byte[] getHeader() {
+        return header;
+    }
+
+    public void setHeader(byte[] header) {
+        this.header = header;
+    }
+
+    public byte[] getFooter() {
+        return footer;
+    }
+
+    public void setFooter(byte[] footer) {
+        this.footer = footer;
+    }
+}

Added: 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=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java Thu May 13 06:31:04 2010
@@ -0,0 +1,495 @@
+/*
+ * 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.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.PluginFactory;
+import org.apache.logging.log4j.core.helpers.OptionConverter;
+import org.apache.logging.log4j.core.layout.pattern.PatternConverter;
+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
+ * is to {@link #format format} a {@link LogEvent} and return the results.
+ * The format of the result depends on the <em>conversion pattern</em>.
+ * <p>
+ * <p/>
+ * <p>The conversion pattern is closely related to the conversion
+ * pattern of the printf function in C. A conversion pattern is
+ * composed of literal text and format control expressions called
+ * <em>conversion specifiers</em>.
+ * <p/>
+ * <p><i>Note that you are free to insert any literal text within the
+ * conversion pattern.</i>
+ * </p>
+ * <p/>
+ * <p>Each conversion specifier starts with a percent sign (%) and is
+ * followed by optional <em>format modifiers</em> and a <em>conversion
+ * character</em>. The conversion character specifies the type of
+ * data, e.g. category, priority, date, thread name. The format
+ * modifiers control such things as field width, padding, left and
+ * right justification. The following is a simple example.
+ * <p/>
+ * <p>Let the conversion pattern be <b>"%-5p [%t]: %m%n"</b> and assume
+ * that the log4j environment was set to use a PatternLayout. Then the
+ * statements
+ * <pre>
+ * Logger logger = LoggerFactory().getLogger("MyLogger");
+ * logger.debug("Message 1");
+ * logger.warn("Message 2");
+ * </pre>
+ * would yield the output
+ * <pre>
+ * DEBUG [main]: Message 1
+ * WARN  [main]: Message 2
+ * </pre>
+ * <p/>
+ * <p>Note that there is no explicit separator between text and
+ * conversion specifiers. The pattern parser knows when it has reached
+ * the end of a conversion specifier when it reads a conversion
+ * character. In the example above the conversion specifier
+ * <b>%-5p</b> means the priority of the logging event should be left
+ * justified to a width of five characters.
+ * <p/>
+ * The recognized conversion characters are
+ * <p/>
+ * <p>
+ * <table border="1" CELLPADDING="8">
+ * <th>Conversion Character</th>
+ * <th>Effect</th>
+ * <p/>
+ * <tr>
+ * <td align=center><b>c</b></td>
+ * <p/>
+ * <td>Used to output the category of the logging event. The
+ * category conversion specifier can be optionally followed by
+ * <em>precision specifier</em>, that is a decimal constant in
+ * brackets.
+ * <p/>
+ * <p>If a precision specifier is given, then only the corresponding
+ * number of right most components of the category name will be
+ * printed. By default the category name is printed in full.
+ * <p/>
+ * <p>For example, for the category name "a.b.c" the pattern
+ * <b>%c{2}</b> will output "b.c".
+ * <p/>
+ * </td>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>C</b></td>
+ * <p/>
+ * <td>Used to output the fully qualified class name of the caller
+ * issuing the logging request. This conversion specifier
+ * can be optionally followed by <em>precision specifier</em>, that
+ * is a decimal constant in brackets.
+ * <p/>
+ * <p>If a precision specifier is given, then only the corresponding
+ * number of right most components of the class name will be
+ * printed. By default the class name is output in fully qualified form.
+ * <p/>
+ * <p>For example, for the class name "org.apache.xyz.SomeClass", the
+ * pattern <b>%C{1}</b> will output "SomeClass".
+ * <p/>
+ * <p><b>WARNING</b> Generating the caller class information is
+ * slow. Thus, it's use should be avoided unless execution speed is
+ * not an issue.
+ * <p/>
+ * </td>
+ * </tr>
+ * <p/>
+ * <tr> <td align=center><b>d</b></td> <td>Used to output the date of
+ * the logging event. The date conversion specifier may be
+ * followed by a set of braces containing a
+ * date and time pattern strings {@link java.text.SimpleDateFormat},
+ * <em>ABSOLUTE</em>, <em>DATE</em> or <em>ISO8601</em>
+ * and a set of braces containing a time zone id per
+ * {@link java.util.TimeZone#getTimeZone(String)}.
+ * For example, <b>%d{HH:mm:ss,SSS}</b>,
+ * <b>%d{dd&nbsp;MMM&nbsp;yyyy&nbsp;HH:mm:ss,SSS}</b>,
+ * <b>%d{DATE}</b> or <b>%d{HH:mm:ss}{GMT+0}</b>. If no date format specifier is given then
+ * ISO8601 format is assumed.
+ * </td>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>F</b></td>
+ * <p/>
+ * <td>Used to output the file name where the logging request was
+ * issued.
+ * <p/>
+ * <p><b>WARNING</b> Generating caller location information is
+ * extremely slow. Its use should be avoided unless execution speed
+ * is not an issue.
+ * <p/>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>l</b></td>
+ * <p/>
+ * <td>Used to output location information of the caller which generated
+ * the logging event.
+ * <p/>
+ * <p>The location information depends on the JVM implementation but
+ * usually consists of the fully qualified name of the calling
+ * method followed by the callers source the file name and line
+ * number between parentheses.
+ * <p/>
+ * </td>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>L</b></td>
+ * <p/>
+ * <td>Used to output the line number from where the logging request
+ * was issued.
+ * <p/>
+ * </tr>
+ * <p/>
+ * <p/>
+ * <tr>
+ * <td align=center><b>m</b></td>
+ * <td>Used to output the application supplied message associated with
+ * the logging event.</td>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>M</b></td>
+ * <p/>
+ * <td>Used to output the method name where the logging request was
+ * issued.
+ * <p/>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>n</b></td>
+ * <p/>
+ * <td>Outputs the platform dependent line separator character or
+ * characters.
+ * <p/>
+ * <p>This conversion character offers practically the same
+ * performance as using non-portable line separator strings such as
+ * "\n", or "\r\n". Thus, it is the preferred way of specifying a
+ * line separator.
+ * <p/>
+ * <p/>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>p</b></td>
+ * <td>Used to output the level of the logging event.</td>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <p/>
+ * <td align=center><b>r</b></td>
+ * <p/>
+ * <td>Used to output the number of milliseconds elapsed since the construction
+ * of the layout until the creation of the logging event.</td>
+ * </tr>
+ * <p/>
+ * <p/>
+ * <tr>
+ * <td align=center><b>t</b></td>
+ * <p/>
+ * <td>Used to output the name of the thread that generated the logging event.</td>
+ * <p/>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <p/>
+ * <td align=center><b>x</b></td>
+ * <p/>
+ * <td>Used to output the NDC (nested diagnostic context) associated
+ * with the thread that generated the logging event.
+ * </td>
+ * </tr>
+ * <p/>
+ * <p/>
+ * <tr>
+ * <td align=center><b>X</b></td>
+ * <p/>
+ * <td>
+ * <p/>
+ * <p>Used to output the MDC (mapped diagnostic context) associated
+ * with the thread that generated the logging event. The <b>X</b>
+ * conversion character can be followed by the key for the
+ * map placed between braces, as in <b>%X{clientNumber}</b> where
+ * <code>clientNumber</code> is the key. The value in the MDC
+ * corresponding to the key will be output. If no additional sub-option
+ * is specified, then the entire contents of the MDC key value pair set
+ * is output using a format {{key1,val1},{key2,val2}}</p>
+ * <p/>
+ * <p>See {@link MDC} class for more details.
+ * </p>
+ * <p/>
+ * </td>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>properties</b></td>
+ * <p/>
+ * <td>
+ * <p>Used to output the Properties associated with the logging event. The <b>properties</b>
+ * conversion word can be followed by the key for the
+ * map placed between braces, as in <b>%properties{application}</b> where
+ * <code>application</code> is the key. The value in the Properties bundle
+ * corresponding to the key will be output. If no additional sub-option
+ * is specified, then the entire contents of the Properties key value pair set
+ * is output using a format {{key1,val1},{key2,val2}}</p>
+ * </td>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <td align=center><b>throwable</b></td>
+ * <p/>
+ * <td>
+ * <p>Used to output the Throwable trace that has been bound to the LoggingEvent, by
+ * default this will output the full trace as one would normally find by a call to Throwable.printStackTrace().
+ * The throwable conversion word can be followed by an option in the form <b>%throwable{short}</b>
+ * which will only output the first line of the Throwable.</p>
+ * </td>
+ * </tr>
+ * <p/>
+ * <tr>
+ * <p/>
+ * <td align=center><b>%</b></td>
+ * <p/>
+ * <td>The sequence %% outputs a single percent sign.
+ * </td>
+ * </tr>
+ * <p/>
+ * </table>
+ * <p/>
+ * <p>By default the relevant information is output as is. However,
+ * with the aid of format modifiers it is possible to change the
+ * minimum field width, the maximum field width and justification.
+ * <p/>
+ * <p>The optional format modifier is placed between the percent sign
+ * and the conversion character.
+ * <p/>
+ * <p>The first optional format modifier is the <em>left justification
+ * flag</em> which is just the minus (-) character. Then comes the
+ * optional <em>minimum field width</em> modifier. This is a decimal
+ * constant that represents the minimum number of characters to
+ * output. If the data item requires fewer characters, it is padded on
+ * either the left or the right until the minimum width is
+ * reached. The default is to pad on the left (right justify) but you
+ * can specify right padding with the left justification flag. The
+ * padding character is space. If the data item is larger than the
+ * minimum field width, the field is expanded to accommodate the
+ * data. The value is never truncated.
+ * <p/>
+ * <p>This behavior can be changed using the <em>maximum field
+ * width</em> modifier which is designated by a period followed by a
+ * decimal constant. If the data item is longer than the maximum
+ * field, then the extra characters are removed from the
+ * <em>beginning</em> of the data item and not from the end. For
+ * example, it the maximum field width is eight and the data item is
+ * ten characters long, then the first two characters of the data item
+ * are dropped. This behavior deviates from the printf function in C
+ * where truncation is done from the end.
+ * <p/>
+ * <p>Below are various format modifier examples for the category
+ * conversion specifier.
+ * <p/>
+ * <p/>
+ * <TABLE BORDER=1 CELLPADDING=8>
+ * <th>Format modifier
+ * <th>left justify
+ * <th>minimum width
+ * <th>maximum width
+ * <th>comment
+ * <p/>
+ * <tr>
+ * <td align=center>%20c</td>
+ * <td align=center>false</td>
+ * <td align=center>20</td>
+ * <td align=center>none</td>
+ * <p/>
+ * <td>Left pad with spaces if the category name is less than 20
+ * characters long.
+ * <p/>
+ * <tr> <td align=center>%-20c</td> <td align=center>true</td> <td
+ * align=center>20</td> <td align=center>none</td> <td>Right pad with
+ * spaces if the category name is less than 20 characters long.
+ * <p/>
+ * <tr>
+ * <td align=center>%.30c</td>
+ * <td align=center>NA</td>
+ * <td align=center>none</td>
+ * <td align=center>30</td>
+ * <p/>
+ * <td>Truncate from the beginning if the category name is longer than 30
+ * characters.
+ * <p/>
+ * <tr>
+ * <td align=center>%20.30c</td>
+ * <td align=center>false</td>
+ * <td align=center>20</td>
+ * <td align=center>30</td>
+ * <p/>
+ * <td>Left pad with spaces if the category name is shorter than 20
+ * characters. However, if category name is longer than 30 characters,
+ * then truncate from the beginning.
+ * <p/>
+ * <tr>
+ * <td align=center>%-20.30c</td>
+ * <td align=center>true</td>
+ * <td align=center>20</td>
+ * <td align=center>30</td>
+ * <p/>
+ * <td>Right pad with spaces if the category name is shorter than 20
+ * characters. However, if category name is longer than 30 characters,
+ * then truncate from the beginning.
+ * <p/>
+ * </table>
+ * <p/>
+ * <p>Below are some examples of conversion patterns.
+ * <p/>
+ * <dl>
+ * <p/>
+ * <p><dt><b>%r [%t] %-5p %c %x - %m%n</b>
+ * <p><dd>This is essentially the TTCC layout.
+ * <p/>
+ * <p><dt><b>%-6r [%15.15t] %-5p %30.30c %x - %m%n</b>
+ * <p/>
+ * <p><dd>Similar to the TTCC layout except that the relative time is
+ * right padded if less than 6 digits, thread name is right padded if
+ * less than 15 characters and truncated if longer and the category
+ * name is left padded if shorter than 30 characters and truncated if
+ * longer.
+ * <p/>
+ * </dl>
+ * <p/>
+ * <p>The above text is largely inspired from Peter A. Darnell and
+ * Philip E. Margolis' highly recommended book "C -- a Software
+ * Engineering Approach", ISBN 0-387-97389-3.
+ */
+@Plugin(name="PatternLayout",type="Core")
+public class PatternLayout extends LayoutBase {
+    /**
+     * Default pattern string for log output. Currently set to the
+     * string <b>"%m%n"</b> which just prints the application supplied
+     * message.
+     */
+    public static final String DEFAULT_CONVERSION_PATTERN = "%m%n";
+
+    /**
+     * A conversion pattern equivalent to the TTCCCLayout.
+     * Current value is <b>%r [%t] %p %c %x - %m%n</b>.
+     */
+    public static final String TTCC_CONVERSION_PATTERN =
+        "%r [%t] %p %c %x - %m%n";
+
+    /**
+     * Initial converter for pattern.
+     */
+    private List<PatternConverter> converters;
+
+    private static final String KEY = "Converter";
+
+    /**
+     * Conversion pattern.
+     */
+    private String conversionPattern;
+
+    /**
+     * True if any element in pattern formats information from exceptions.
+     */
+    private boolean handlesExceptions;
+
+    /**
+     * Constructs a EnhancedPatternLayout using the DEFAULT_LAYOUT_PATTERN.
+     * <p/>
+     * The default pattern just produces the application supplied message.
+     */
+    public PatternLayout() {
+        this(DEFAULT_CONVERSION_PATTERN);
+    }
+
+    /**
+     * Constructs a EnhancedPatternLayout using the supplied conversion pattern.
+     *
+     * @param pattern conversion pattern.
+     */
+    public PatternLayout(final String pattern) {
+
+        this.conversionPattern = pattern;
+        PatternParser parser = createPatternParser();
+        converters = parser.parse((pattern == null) ? DEFAULT_CONVERSION_PATTERN : pattern);
+        handlesExceptions = parser.handlesExceptions();
+
+    }
+
+    /**
+     * Set the <b>ConversionPattern</b> option. This is the string which
+     * controls formatting and consists of a mix of literal content and
+     * conversion specifiers.
+     *
+     * @param conversionPattern conversion pattern.
+     */
+    public void setConversionPattern(final String conversionPattern) {
+        String pattern = OptionConverter.convertSpecialChars(conversionPattern);
+        if (pattern == null) {
+            return;
+        }
+        PatternParser parser = createPatternParser();
+        converters = parser.parse(pattern);
+        handlesExceptions = parser.handlesExceptions();
+    }
+
+    /**
+     * Formats a logging event to a writer.
+     *
+     * @param event logging event to be formatted.
+     */
+    public byte[] format(final LogEvent event) {
+        StringBuilder buf = new StringBuilder();
+        for (PatternConverter c : converters) {
+            c.format(event, buf);
+        }
+        return buf.toString().getBytes();
+    }
+
+    private PatternParser createPatternParser() {
+
+        return new PatternParser(KEY);
+    }
+
+    @PluginFactory
+    public static PatternLayout createLayout(Node node) {
+        String pattern = null;
+        for (Map.Entry<String, String> entry : node.getAttributes().entrySet()) {
+            String name = entry.getKey().toLowerCase();
+            if (name.equals("pattern")) {
+                pattern = entry.getValue();
+            }
+        }
+        if (pattern != null) {
+            return new PatternLayout(pattern);
+        }
+        logger.error("No pattern specified for PatternLayout");
+        return null;
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/CachedDateFormat.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/pattern/CachedDateFormat.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/CachedDateFormat.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/CachedDateFormat.java Thu May 13 06:31:04 2010
@@ -0,0 +1,371 @@
+/*
+ * 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.layout.pattern;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Date;
+import java.util.TimeZone;
+
+
+/**
+ * CachedDateFormat optimizes the performance of a wrapped
+ * DateFormat.  The implementation is not thread-safe.
+ * If the millisecond pattern is not recognized,
+ * the class will only use the cache if the
+ * same value is requested.
+ */
+final class CachedDateFormat extends DateFormat {
+    /**
+     * Constant used to represent that there was no change
+     * observed when changing the millisecond count.
+     */
+    public static final int NO_MILLISECONDS = -2;
+
+    /**
+     * Supported digit set.  If the wrapped DateFormat uses
+     * a different unit set, the millisecond pattern
+     * will not be recognized and duplicate requests
+     * will use the cache.
+     */
+    private static final String DIGITS = "0123456789";
+
+    /**
+     * Constant used to represent that there was an
+     * observed change, but was an expected change.
+     */
+    public static final int UNRECOGNIZED_MILLISECONDS = -1;
+
+    /**
+     * First magic number used to detect the millisecond position.
+     */
+    private static final int MAGIC1 = 654;
+
+    /**
+     * Expected representation of first magic number.
+     */
+    private static final String MAGICSTRING1 = "654";
+
+    /**
+     * Second magic number used to detect the millisecond position.
+     */
+    private static final int MAGIC2 = 987;
+
+    /**
+     * Expected representation of second magic number.
+     */
+    private static final String MAGICSTRING2 = "987";
+
+    /**
+     * Expected representation of 0 milliseconds.
+     */
+    private static final String ZERO_STRING = "000";
+
+    /**
+     * Wrapped formatter.
+     */
+    private final DateFormat formatter;
+
+    /**
+     * Index of initial digit of millisecond pattern or
+     * UNRECOGNIZED_MILLISECONDS or NO_MILLISECONDS.
+     */
+    private int millisecondStart;
+
+    /**
+     * Integral second preceding the previous convered Date.
+     */
+    private long slotBegin;
+
+    /**
+     * Cache of previous conversion.
+     */
+    private StringBuffer cache = new StringBuffer(50);
+
+    /**
+     * Maximum validity period for the cache.
+     * Typically 1, use cache for duplicate requests only, or
+     * 1000, use cache for requests within the same integral second.
+     */
+    private final int expiration;
+
+    /**
+     * Date requested in previous conversion.
+     */
+    private long previousTime;
+
+    /**
+     * Scratch date object used to minimize date object creation.
+     */
+    private final Date tmpDate = new Date(0);
+
+    /**
+     * Creates a new CachedDateFormat object.
+     *
+     * @param dateFormat Date format, may not be null.
+     * @param expiration maximum cached range in milliseconds.
+     *                   If the dateFormat is known to be incompatible with the
+     *                   caching algorithm, use a value of 0 to totally disable
+     *                   caching or 1 to only use cache for duplicate requests.
+     */
+    public CachedDateFormat(final DateFormat dateFormat, final int expiration) {
+        if (dateFormat == null) {
+            throw new IllegalArgumentException("dateFormat cannot be null");
+        }
+
+        if (expiration < 0) {
+            throw new IllegalArgumentException("expiration must be non-negative");
+        }
+
+        formatter = dateFormat;
+        this.expiration = expiration;
+        millisecondStart = 0;
+
+        //
+        //   set the previousTime so the cache will be invalid
+        //        for the next request.
+        previousTime = Long.MIN_VALUE;
+        slotBegin = Long.MIN_VALUE;
+    }
+
+    /**
+     * Finds start of millisecond field in formatted time.
+     *
+     * @param time      long time, must be integral number of seconds
+     * @param formatted String corresponding formatted string
+     * @param formatter DateFormat date format
+     * @return int position in string of first digit of milliseconds,
+     *         -1 indicates no millisecond field, -2 indicates unrecognized
+     *         field (likely RelativeTimeDateFormat)
+     */
+    public static int findMillisecondStart(final long time, final String formatted, final DateFormat formatter) {
+        long slotBegin = (time / 1000) * 1000;
+
+        if (slotBegin > time) {
+            slotBegin -= 1000;
+        }
+
+        int millis = (int) (time - slotBegin);
+
+        int magic = MAGIC1;
+        String magicString = MAGICSTRING1;
+
+        if (millis == MAGIC1) {
+            magic = MAGIC2;
+            magicString = MAGICSTRING2;
+        }
+
+        String plusMagic = formatter.format(new Date(slotBegin + magic));
+
+        /**
+         *   If the string lengths differ then
+         *      we can't use the cache except for duplicate requests.
+         */
+        if (plusMagic.length() != formatted.length()) {
+            return UNRECOGNIZED_MILLISECONDS;
+        } else {
+            // find first difference between values
+            for (int i = 0; i < formatted.length(); i++) {
+                if (formatted.charAt(i) != plusMagic.charAt(i)) {
+                    //
+                    //   determine the expected digits for the base time
+                    StringBuffer formattedMillis = new StringBuffer("ABC");
+                    millisecondFormat(millis, formattedMillis, 0);
+
+                    String plusZero = formatter.format(new Date(slotBegin));
+
+                    //   If the next 3 characters match the magic
+                    //      string and the expected string
+                    if (
+                        (plusZero.length() == formatted.length())
+                            && magicString.regionMatches(
+                            0, plusMagic, i, magicString.length())
+                            && formattedMillis.toString().regionMatches(
+                            0, formatted, i, magicString.length())
+                            && ZERO_STRING.regionMatches(
+                            0, plusZero, i, ZERO_STRING.length())) {
+                        return i;
+                    } else {
+                        return UNRECOGNIZED_MILLISECONDS;
+                    }
+                }
+            }
+        }
+
+        return NO_MILLISECONDS;
+    }
+
+    /**
+     * Formats a Date into a date/time string.
+     *
+     * @param date          the date to format.
+     * @param sbuf          the string buffer to write to.
+     * @param fieldPosition remains untouched.
+     * @return the formatted time string.
+     */
+    public StringBuffer format(Date date, StringBuffer sbuf, FieldPosition fieldPosition) {
+        format(date.getTime(), sbuf);
+
+        return sbuf;
+    }
+
+    /**
+     * Formats a millisecond count into a date/time string.
+     *
+     * @param now Number of milliseconds after midnight 1 Jan 1970 GMT.
+     * @param buf the string buffer to write to.
+     * @return the formatted time string.
+     */
+    public StringBuffer format(long now, StringBuffer buf) {
+        //
+        // If the current requested time is identical to the previously
+        //     requested time, then append the cache contents.
+        //
+        if (now == previousTime) {
+            buf.append(cache);
+
+            return buf;
+        }
+
+        //
+        //   If millisecond pattern was not unrecognized
+        //     (that is if it was found or milliseconds did not appear)
+        //
+        if (millisecondStart != UNRECOGNIZED_MILLISECONDS &&
+            //    Check if the cache is still valid.
+            //    If the requested time is within the same integral second
+            //       as the last request and a shorter expiration was not requested.
+            (now < (slotBegin + expiration)) && (now >= slotBegin)
+            && (now < (slotBegin + 1000L))) {
+            //
+            //    if there was a millisecond field then update it
+            //
+            if (millisecondStart >= 0) {
+                millisecondFormat((int) (now - slotBegin), cache, millisecondStart);
+            }
+
+            //
+            //   update the previously requested time
+            //      (the slot begin should be unchanged)
+            previousTime = now;
+            buf.append(cache);
+
+            return buf;
+        }
+
+        //
+        //  could not use previous value.
+        //    Call underlying formatter to format date.
+        cache.setLength(0);
+        tmpDate.setTime(now);
+        cache.append(formatter.format(tmpDate));
+        buf.append(cache);
+        previousTime = now;
+        slotBegin = (previousTime / 1000) * 1000;
+
+        if (slotBegin > previousTime) {
+            slotBegin -= 1000;
+        }
+
+        //
+        //    if the milliseconds field was previous found
+        //       then reevaluate in case it moved.
+        //
+        if (millisecondStart >= 0) {
+            millisecondStart =
+                findMillisecondStart(now, cache.toString(), formatter);
+        }
+
+        return buf;
+    }
+
+    /**
+     * Formats a count of milliseconds (0-999) into a numeric representation.
+     *
+     * @param millis Millisecond coun between 0 and 999.
+     * @param buf    String buffer, may not be null.
+     * @param offset Starting position in buffer, the length of the
+     *               buffer must be at least offset + 3.
+     */
+    private static void millisecondFormat(
+        final int millis, final StringBuffer buf, final int offset) {
+        buf.setCharAt(offset, DIGITS.charAt(millis / 100));
+        buf.setCharAt(offset + 1, DIGITS.charAt((millis / 10) % 10));
+        buf.setCharAt(offset + 2, DIGITS.charAt(millis % 10));
+    }
+
+    /**
+     * Set timezone.
+     * <p/>
+     * Setting the timezone using getCalendar().setTimeZone()
+     * will likely cause caching to misbehave.
+     *
+     * @param timeZone TimeZone new timezone
+     */
+    public void setTimeZone(final TimeZone timeZone) {
+        formatter.setTimeZone(timeZone);
+        previousTime = Long.MIN_VALUE;
+        slotBegin = Long.MIN_VALUE;
+    }
+
+    /**
+     * This method is delegated to the formatter which most
+     * likely returns null.
+     *
+     * @param s   string representation of date.
+     * @param pos field position, unused.
+     * @return parsed date, likely null.
+     */
+    public Date parse(String s, ParsePosition pos) {
+        return formatter.parse(s, pos);
+    }
+
+    /**
+     * Gets number formatter.
+     *
+     * @return NumberFormat number formatter
+     */
+    public NumberFormat getNumberFormat() {
+        return formatter.getNumberFormat();
+    }
+
+    /**
+     * Gets maximum cache validity for the specified SimpleDateTime
+     * conversion pattern.
+     *
+     * @param pattern conversion pattern, may not be null.
+     * @return Duration in milliseconds from an integral second
+     *         that the cache will return consistent results.
+     */
+    public static int getMaximumCacheValidity(final String pattern) {
+        //
+        //   If there are more "S" in the pattern than just one "SSS" then
+        //      (for example, "HH:mm:ss,SSS SSS"), then set the expiration to
+        //      one millisecond which should only perform duplicate request caching.
+        //
+        int firstS = pattern.indexOf('S');
+
+        if ((firstS >= 0) && (firstS != pattern.lastIndexOf("SSS"))) {
+            return 1;
+        }
+
+        return 1000;
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/ClassNamePatternConverter.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/pattern/ClassNamePatternConverter.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/ClassNamePatternConverter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/ClassNamePatternConverter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,72 @@
+/*
+ * 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.layout.pattern;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+
+/**
+ * Formats the class name of the site of the logging request.
+ */
+@Plugin(name="ClassNamePatternConverter", type="Converter")
+@ConverterKeys({"C", "class"})
+public final class ClassNamePatternConverter extends NamePatternConverter {
+
+    private static final String NA = "?";
+    /**
+     * Private constructor.
+     *
+     * @param options options, may be null.
+     */
+    private ClassNamePatternConverter(
+        final String[] options) {
+        super("Class Name", "class name", options);
+    }
+
+    /**
+     * Gets an instance of ClassNamePatternConverter.
+     *
+     * @param options options, may be null.
+     * @return instance of pattern converter.
+     */
+    public static ClassNamePatternConverter newInstance(
+        final String[] options) {
+        return new ClassNamePatternConverter(options);
+    }
+
+    /**
+     * Format a logging event.
+     *
+     * @param event      event to format.
+     * @param toAppendTo string buffer to which class name will be appended.
+     */
+    public void format(final LogEvent event, final StringBuilder toAppendTo) {
+        final int initialLength = toAppendTo.length();
+
+        StackTraceElement element = event.getSource();
+
+        if (element == null) {
+            toAppendTo.append(NA);
+        } else {
+            toAppendTo.append(element.getClassName());
+        }
+
+        abbreviate(initialLength, toAppendTo);
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/ConverterKeys.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/pattern/ConverterKeys.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/ConverterKeys.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/ConverterKeys.java Thu May 13 06:31:04 2010
@@ -0,0 +1,15 @@
+package org.apache.logging.log4j.core.layout.pattern;
+
+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.TYPE)
+public @interface ConverterKeys {
+    public String[] value();
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/DatePatternConverter.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/pattern/DatePatternConverter.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/DatePatternConverter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/DatePatternConverter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,163 @@
+/*
+ * 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.layout.pattern;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+
+/**
+ * Convert and format the event's date in a StringBuffer.
+ */
+@Plugin(name="DatePatternConverter", type="Converter")
+@ConverterKeys({"d", "date"})
+public final class DatePatternConverter extends LogEventPatternConverter {
+    /**
+     * ABSOLUTE string literal.
+     */
+    private static final String ABSOLUTE_FORMAT = "ABSOLUTE";
+    /**
+     * SimpleTimePattern for ABSOLUTE.
+     */
+    private static final String ABSOLUTE_TIME_PATTERN = "HH:mm:ss,SSS";
+
+
+    /**
+     * DATE string literal.
+     */
+    private static final String DATE_AND_TIME_FORMAT = "DATE";
+    /**
+     * SimpleTimePattern for DATE.
+     */
+    private static final String DATE_AND_TIME_PATTERN = "dd MMM yyyy HH:mm:ss,SSS";
+
+    /**
+     * ISO8601 string literal.
+     */
+    private static final String ISO8601_FORMAT = "ISO8601";
+    /**
+     * SimpleTimePattern for ISO8601.
+     */
+    private static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
+    /**
+     * Date format.
+     */
+    private String cachedDate;
+
+    private long lastTimestamp;
+
+    private SimpleDateFormat simpleFormat;
+
+    /**
+     * Private constructor.
+     *
+     * @param options options, may be null.
+     */
+    private DatePatternConverter(final String[] options) {
+        super("Date", "date");
+
+        String patternOption;
+
+        if ((options == null) || (options.length == 0)) {
+            // the branch could be optimized, but here we are making explicit
+            // that null values for patternOption are allowed.
+            patternOption = null;
+        } else {
+            patternOption = options[0];
+        }
+
+        String pattern;
+
+        if (patternOption == null || patternOption.equalsIgnoreCase(ISO8601_FORMAT)) {
+            pattern = ISO8601_PATTERN;
+        } else if (patternOption.equalsIgnoreCase(ABSOLUTE_FORMAT)) {
+            pattern = ABSOLUTE_TIME_PATTERN;
+        } else if (patternOption.equalsIgnoreCase(DATE_AND_TIME_FORMAT)) {
+            pattern = DATE_AND_TIME_PATTERN;
+        } else {
+            pattern = patternOption;
+        }
+
+        try {
+            simpleFormat = new SimpleDateFormat(pattern);
+        } catch (IllegalArgumentException e) {
+            logger.warn("Could not instantiate SimpleDateFormat with pattern " + patternOption, e);
+
+            // default to the ISO8601 format
+            simpleFormat = new SimpleDateFormat(ISO8601_PATTERN);
+        }
+
+        // if the option list contains a TZ option, then set it.
+        if ((options != null) && (options.length > 1)) {
+            TimeZone tz = TimeZone.getTimeZone(options[1]);
+            simpleFormat.setTimeZone(tz);
+        }
+    }
+
+    /**
+     * Obtains an instance of pattern converter.
+     *
+     * @param options options, may be null.
+     * @return instance of pattern converter.
+     */
+    public static DatePatternConverter newInstance(final String[] options) {
+        return new DatePatternConverter(options);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void format(final LogEvent event, final StringBuilder output) {
+        long timestamp = event.getMillis();
+
+        synchronized (this) {
+            if (timestamp != lastTimestamp) {
+                lastTimestamp = timestamp;
+                cachedDate = simpleFormat.format(timestamp);
+            }
+        }
+        output.append(cachedDate);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void format(final Object obj, final StringBuilder output) {
+        if (obj instanceof Date) {
+            format((Date) obj, output);
+        }
+
+        super.format(obj, output);
+    }
+
+    /**
+     * Append formatted date to string buffer.
+     *
+     * @param date       date
+     * @param toAppendTo buffer to which formatted date is appended.
+     */
+    public void format(final Date date, final StringBuilder toAppendTo) {
+        synchronized (this) {
+            toAppendTo.append(simpleFormat.format(date.getTime()));
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FileDatePatternConverter.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/pattern/FileDatePatternConverter.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FileDatePatternConverter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FileDatePatternConverter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,53 @@
+/*
+ * 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.layout.pattern;
+
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+/**
+ * Formats an date by delegating to DatePatternConverter.  The default
+ * date pattern for a %d specifier in a file name is different than
+ * the %d pattern in pattern layout.
+ */
+@Plugin(name="FileDatePatternConverter", type="FileConverter")
+@ConverterKeys({"d", "date"})
+public final class FileDatePatternConverter {
+    /**
+     * Private constructor.
+     */
+    private FileDatePatternConverter() {
+    }
+
+    /**
+     * Obtains an instance of pattern converter.
+     *
+     * @param options options, may be null.
+     * @return instance of pattern converter.
+     */
+    public static PatternConverter newInstance(
+        final String[] options) {
+        if ((options == null) || (options.length == 0)) {
+            return DatePatternConverter.newInstance(
+                new String[]{
+                    "yyyy-MM-dd"
+                });
+        }
+
+        return DatePatternConverter.newInstance(options);
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FileLocationPatternConverter.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/pattern/FileLocationPatternConverter.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FileLocationPatternConverter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FileLocationPatternConverter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,64 @@
+/*
+ * 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.layout.pattern;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+
+/**
+ * Return the event's line location information in a StringBuffer.
+ */
+@Plugin(name="FileLocationPatternConverter", type="Converter")
+@ConverterKeys({"F", "file"})
+public final class FileLocationPatternConverter extends LogEventPatternConverter {
+    /**
+     * Singleton.
+     */
+    private static final FileLocationPatternConverter INSTANCE =
+        new FileLocationPatternConverter();
+
+    /**
+     * Private constructor.
+     */
+    private FileLocationPatternConverter() {
+        super("File Location", "file");
+    }
+
+    /**
+     * Obtains an instance of pattern converter.
+     *
+     * @param options options, may be null.
+     * @return instance of pattern converter.
+     */
+    public static FileLocationPatternConverter newInstance(
+        final String[] options) {
+        return INSTANCE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void format(final LogEvent event, final StringBuilder output) {
+        StackTraceElement element = event.getSource();
+
+        if (element != null) {
+            output.append(element.getFileName());
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FormattingInfo.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/pattern/FormattingInfo.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FormattingInfo.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FormattingInfo.java Thu May 13 06:31:04 2010
@@ -0,0 +1,132 @@
+/*
+ * 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.layout.pattern;
+
+
+/**
+ * Modifies the output of a pattern converter for a specified minimum
+ * and maximum width and alignment.
+ */
+public final class FormattingInfo {
+    /**
+     * Array of spaces.
+     */
+    private static final char[] SPACES =
+        new char[]{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
+
+    /**
+     * Default instance.
+     */
+    private static final FormattingInfo DEFAULT =
+        new FormattingInfo(false, 0, Integer.MAX_VALUE);
+
+    /**
+     * Minimum length.
+     */
+    private final int minLength;
+
+    /**
+     * Maximum length.
+     */
+    private final int maxLength;
+
+    /**
+     * Alignment.
+     */
+    private final boolean leftAlign;
+
+    /**
+     * Creates new instance.
+     *
+     * @param leftAlign left align if true.
+     * @param minLength minimum length.
+     * @param maxLength maximum length.
+     */
+    public FormattingInfo(final boolean leftAlign, final int minLength, final int maxLength) {
+        this.leftAlign = leftAlign;
+        this.minLength = minLength;
+        this.maxLength = maxLength;
+    }
+
+    /**
+     * Gets default instance.
+     *
+     * @return default instance.
+     */
+    public static FormattingInfo getDefault() {
+        return DEFAULT;
+    }
+
+    /**
+     * Determine if left aligned.
+     *
+     * @return true if left aligned.
+     */
+    public boolean isLeftAligned() {
+        return leftAlign;
+    }
+
+    /**
+     * Get minimum length.
+     *
+     * @return minimum length.
+     */
+    public int getMinLength() {
+        return minLength;
+    }
+
+    /**
+     * Get maximum length.
+     *
+     * @return maximum length.
+     */
+    public int getMaxLength() {
+        return maxLength;
+    }
+
+    /**
+     * Adjust the content of the buffer based on the specified lengths and alignment.
+     *
+     * @param fieldStart start of field in buffer.
+     * @param buffer     buffer to be modified.
+     */
+    public void format(final int fieldStart, final StringBuilder buffer) {
+        final int rawLength = buffer.length() - fieldStart;
+
+        if (rawLength > maxLength) {
+            buffer.delete(fieldStart, buffer.length() - maxLength);
+        } else if (rawLength < minLength) {
+            if (leftAlign) {
+                final int fieldEnd = buffer.length();
+                buffer.setLength(fieldStart + minLength);
+
+                for (int i = fieldEnd; i < buffer.length(); i++) {
+                    buffer.setCharAt(i, ' ');
+                }
+            } else {
+                int padLength = minLength - rawLength;
+
+                for (; padLength > 8; padLength -= 8) {
+                    buffer.insert(fieldStart, SPACES);
+                }
+
+                buffer.insert(fieldStart, SPACES, 0, padLength);
+            }
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FullLocationPatternConverter.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/pattern/FullLocationPatternConverter.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FullLocationPatternConverter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/FullLocationPatternConverter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,64 @@
+/*
+ * 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.layout.pattern;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+
+/**
+ * Format the event's line location information.
+ */
+@Plugin(name="FullLocationPatternConverter", type="Converter")
+@ConverterKeys({"l", "location"})
+public final class FullLocationPatternConverter extends LogEventPatternConverter {
+    /**
+     * Singleton.
+     */
+    private static final FullLocationPatternConverter INSTANCE =
+        new FullLocationPatternConverter();
+
+    /**
+     * Private constructor.
+     */
+    private FullLocationPatternConverter() {
+        super("Full Location", "fullLocation");
+    }
+
+    /**
+     * Obtains an instance of pattern converter.
+     *
+     * @param options options, may be null.
+     * @return instance of pattern converter.
+     */
+    public static FullLocationPatternConverter newInstance(
+        final String[] options) {
+        return INSTANCE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void format(final LogEvent event, final StringBuilder output) {
+        StackTraceElement element = event.getSource();
+
+        if (element != null) {
+            output.append(element.toString());
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/IntegerPatternConverter.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/pattern/IntegerPatternConverter.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/IntegerPatternConverter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/IntegerPatternConverter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,67 @@
+/*
+ * 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.layout.pattern;
+
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+import java.util.Date;
+
+
+/**
+ * Formats an integer.
+ */
+@Plugin(name="IntegerPatternConverter", type="FileConverter")
+@ConverterKeys({"i", "index"})
+public final class IntegerPatternConverter extends PatternConverter {
+    /**
+     * Singleton.
+     */
+    private static final IntegerPatternConverter INSTANCE =
+        new IntegerPatternConverter();
+
+    /**
+     * Private constructor.
+     */
+    private IntegerPatternConverter() {
+        super("Integer", "integer");
+    }
+
+    /**
+     * Obtains an instance of pattern converter.
+     *
+     * @param options options, may be null.
+     * @return instance of pattern converter.
+     */
+    public static IntegerPatternConverter newInstance(
+        final String[] options) {
+        return INSTANCE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void format(Object obj, final StringBuilder toAppendTo) {
+        if (obj instanceof Integer) {
+            toAppendTo.append(obj.toString());
+        }
+
+        if (obj instanceof Date) {
+            toAppendTo.append(Long.toString(((Date) obj).getTime()));
+        }
+    }
+}

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/LevelPatternConverter.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/pattern/LevelPatternConverter.java?rev=943816&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/LevelPatternConverter.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/LevelPatternConverter.java Thu May 13 06:31:04 2010
@@ -0,0 +1,95 @@
+/*
+ * 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.layout.pattern;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+
+
+/**
+ * Return the event's level in a StringBuffer.
+ */
+@Plugin(name = "LevelPatternConverter", type = "Converter")
+@ConverterKeys({"p", "level"})
+public final class LevelPatternConverter extends LogEventPatternConverter {
+    /**
+     * Singleton.
+     */
+    private static final LevelPatternConverter INSTANCE =
+        new LevelPatternConverter();
+
+    /**
+     * Private constructor.
+     */
+    private LevelPatternConverter() {
+        super("Level", "level");
+    }
+
+    /**
+     * Obtains an instance of pattern converter.
+     *
+     * @param options options, may be null.
+     * @return instance of pattern converter.
+     */
+    public static LevelPatternConverter newInstance(
+        final String[] options) {
+        return INSTANCE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void format(final LogEvent event, final StringBuilder output) {
+        output.append(event.getLevel().toString());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getStyleClass(Object e) {
+        if (e instanceof LogEvent) {
+            Level level = ((LogEvent) e).getLevel();
+
+            switch (level) {
+                case TRACE:
+                    return "level trace";
+
+                case DEBUG:
+                    return "level debug";
+
+                case INFO:
+                    return "level info";
+
+                case WARN:
+                    return "level warn";
+
+                case ERROR:
+                    return "level error";
+
+                case FATAL:
+                    return "level fatal";
+
+                default:
+                    return "level " + ((LogEvent) e).getLevel().toString();
+            }
+        }
+
+        return "level";
+    }
+}



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


Mime
View raw message