logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rgo...@apache.org
Subject svn commit: r1463226 - in /logging/log4j/log4j2/trunk: core/src/main/java/org/apache/logging/log4j/core/impl/ core/src/main/java/org/apache/logging/log4j/core/pattern/ core/src/test/java/org/apache/logging/log4j/core/impl/ core/src/test/java/org/apache...
Date Mon, 01 Apr 2013 17:52:40 GMT
Author: rgoers
Date: Mon Apr  1 17:52:39 2013
New Revision: 1463226

URL: http://svn.apache.org/r1463226
Log:
LOG4J2-160 - Move Throwable pattern converter options processing to ThrowableFormatOptions
class.

Added:
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
    logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml
Modified:
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
    logging/log4j/log4j2/trunk/src/changes/changes.xml

Added: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java?rev=1463226&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
(added)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
Mon Apr  1 17:52:39 2013
@@ -0,0 +1,227 @@
+/*
+ * 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.impl;
+
+import org.apache.logging.log4j.core.helpers.Constants;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * Contains options which control how a {@code throwable} pattern is formatted.
+ */
+public final class ThrowableFormatOptions {
+
+    /**
+     * Default instance of {@code ThrowableFormatOptions}.
+     */
+    protected static final ThrowableFormatOptions DEFAULT = new ThrowableFormatOptions();
+
+    /**
+     * Format the whole stack trace.
+     */
+    private static final String FULL = "full";
+
+    /**
+     * Do not format the exception.
+     */
+    private static final String NONE = "none";
+
+    /**
+     * Format only the first line of the throwable.
+     */
+    private static final String SHORT = "short";
+
+    /**
+     * The number of lines to write.
+     */
+    private final int lines;
+
+    /**
+     * The stack trace separator.
+     */
+    private final String separator;
+
+    /**
+     * The list of packages to filter.
+     */
+    private final List<String> packages;
+
+    /**
+     * Construct the options for printing stack trace.
+     * @param lines The number of lines.
+     * @param separator The stack trace separator.
+     * @param packages The packages to filter.
+     */
+    protected ThrowableFormatOptions(final Integer lines, final String separator, final List<String>
packages) {
+        this.lines = lines == null ? Integer.MAX_VALUE : lines;
+        this.separator = separator == null ? Constants.LINE_SEP : separator;
+        this.packages = packages;
+    }
+
+    /**
+     * Construct the options for printing stack trace.
+     * @param packages The packages to filter.
+     */
+    protected ThrowableFormatOptions(final List<String> packages) {
+        this(null, null, packages);
+    }
+
+    /**
+     * Construct the options for printing stack trace.
+     */
+    protected ThrowableFormatOptions() {
+        this(null, null, null);
+    }
+
+    /**
+     * Returns the number of lines to write.
+     * @return The number of lines to write.
+     */
+    public int getLines() {
+        return this.lines;
+    }
+
+    /**
+     * Returns the stack trace separator.
+     * @return The stack trace separator.
+     */
+    public String getSeparator() {
+        return this.separator;
+    }
+
+    /**
+     * Returns the list of packages to filter.
+     * @return The list of packages to filter.
+     */
+    public List<String> getPackages() {
+        return this.packages;
+    }
+
+    /**
+     * Determines if all lines should be printed.
+     * @return true for all lines, false otherwise.
+     */
+    public boolean allLines() {
+        return this.lines == Integer.MAX_VALUE;
+    }
+
+    /**
+     * Determines if any lines should be printed.
+     * @return true for any lines, false otherwise.
+     */
+    public boolean anyLines() {
+        return this.lines > 0;
+    }
+
+    /**
+     * Returns the minimum between the lines and the max lines.
+     * @param maxLines The maximum number of lines.
+     * @return The number of lines to print.
+     */
+    public int minLines(final int maxLines) {
+        return this.lines > maxLines ? maxLines : this.lines;
+    }
+
+    /**
+     * Determines if there are any packages to filter.
+     * @return true if there are packages, false otherwise.
+     */
+    public boolean hasPackages() {
+        return this.packages != null && !this.packages.isEmpty();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("{").append(allLines() ? FULL : this.lines == 2 ? SHORT : anyLines() ? String.valueOf(this.lines)
: NONE).append("}");
+        s.append("{separator(").append(this.separator).append(")}");
+        if (hasPackages()) {
+            s.append("{filters(");
+            for (String p : this.packages) {
+                s.append(p).append(",");
+            }
+            s.deleteCharAt(s.length() - 1);
+            s.append(")}");
+        }
+        return s.toString();
+    }
+
+    /**
+     * Create a new instance based on the array of options.
+     * @param options The array of options.
+     */
+    public static ThrowableFormatOptions newInstance(String[] options) {
+        if (options == null || options.length == 0) {
+            return DEFAULT;
+        } else {
+            // NOTE: The following code is present for backward compatibility
+            // and was copied from Extended/RootThrowablePatternConverter.
+            // This supports a single option with the format:
+            //     %xEx{["none"|"short"|"full"|depth],[filters(packages)}
+            // However, the convention for multiple options should be:
+            //     %xEx{["none"|"short"|"full"|depth]}[{filters(packages)}]
+            if (options.length == 1 && options[0] != null && options[0].length()
> 0) {
+                final String[] opts = options[0].split(",", 2);
+                final String first = opts[0].trim();
+                final Scanner scanner = new Scanner(first);
+                if (opts.length > 1 && (first.equalsIgnoreCase(FULL) || first.equalsIgnoreCase(SHORT)
|| first.equalsIgnoreCase(NONE) || scanner.hasNextInt())) {
+                    options = new String[]{first, opts[1].trim()};
+                }
+            }
+
+            int lines = DEFAULT.lines;
+            String separator = DEFAULT.separator;
+            List<String> packages = DEFAULT.packages;
+            for (int i = 0; i < options.length; i++) {
+                if (options[i] != null) {
+                    final String option = options[i].trim();
+                    if (option.length() == 0) {
+                        // continue;
+                    } else if (option.startsWith("separator(") && option.endsWith(")"))
{
+                        separator = option.substring("separator(".length(), option.length()
- 1);
+                    } else if (option.startsWith("filters(") && option.endsWith(")"))
{
+                        final String filterStr = option.substring("filters(".length(), option.length()
- 1);
+                        if (filterStr.length() > 0) {
+                            final String[] array = filterStr.split(",");
+                            if (array.length > 0) {
+                                packages = new ArrayList<String>(array.length);
+                                for (String token : array) {
+                                    token = token.trim();
+                                    if (token.length() > 0) {
+                                        packages.add(token);
+                                    }
+                                }
+                            }
+                        }
+                    } else if (option.equalsIgnoreCase(NONE)) {
+                        lines = 0;
+                    } else if (option.equalsIgnoreCase(SHORT)) {
+                        lines = 2;
+                    } else if (!option.equalsIgnoreCase(FULL)) {
+                        lines = Integer.parseInt(option);
+                    }
+                }
+            }
+            return new ThrowableFormatOptions(lines, separator, packages);
+        }
+    }
+}

Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java?rev=1463226&r1=1463225&r2=1463226&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
(original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
Mon Apr  1 17:52:39 2013
@@ -18,12 +18,9 @@ package org.apache.logging.log4j.core.pa
 
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.helpers.Constants;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-
 /**
  * Outputs the Throwable portion of the LoggingEvent as a full stacktrace
  * unless this converter's option is 'short', where it just outputs the first line of the
trace, or if
@@ -36,10 +33,6 @@ import java.util.Scanner;
 @ConverterKeys({"xEx", "xThrowable", "xException" })
 public final class ExtendedThrowablePatternConverter extends ThrowablePatternConverter {
 
-    private static final String FILTERS = "filters(";
-
-    private final List<String> packages;
-
     /**
      * Private constructor.
      *
@@ -47,20 +40,6 @@ public final class ExtendedThrowablePatt
      */
     private ExtendedThrowablePatternConverter(final String[] options) {
         super("ExtendedThrowable", "throwable", options);
-        List<String> tempPackages = null;
-        if (options != null && options.length > 1) {
-            if (options[1].startsWith(FILTERS) && options[1].endsWith(")")) {
-                final String filterStr = options[1].substring(FILTERS.length(), options[1].length()
- 1);
-                final String[] array = filterStr.split(",");
-                if (array.length > 0) {
-                    tempPackages = new ArrayList<String>(array.length);
-                    for (final String token : array) {
-                        tempPackages.add(token.trim());
-                    }
-                }
-            }
-        }
-        packages = tempPackages;
     }
 
     /**
@@ -71,23 +50,7 @@ public final class ExtendedThrowablePatt
      * @return instance of class.
      */
     public static ExtendedThrowablePatternConverter newInstance(final String[] options) {
-        String type = null;
-        String[] array = options;
-        if (options != null && options.length == 1 && options[0].length()
> 0) {
-            final String[] opts = options[0].split(",", 2);
-            final String first = opts[0].trim();
-            String filter;
-            final Scanner scanner = new Scanner(first);
-            if (first.equalsIgnoreCase(FULL) || first.equalsIgnoreCase(SHORT) || scanner.hasNextInt())
{
-                type = first;
-                filter = opts[1].trim();
-            } else {
-                filter = options[0].trim();
-            }
-            array = new String[] {type, filter};
-        }
-
-        return new ExtendedThrowablePatternConverter(array);
+        return new ExtendedThrowablePatternConverter(options);
     }
 
     /**
@@ -96,23 +59,26 @@ public final class ExtendedThrowablePatt
     @Override
     public void format(final LogEvent event, final StringBuilder toAppendTo) {
         final Throwable throwable = event.getThrown();
-        if (throwable != null && lines > 0) {
+        if (throwable != null && options.anyLines()) {
             if (!(throwable instanceof ThrowableProxy)) {
                 super.format(event, toAppendTo);
                 return;
             }
             final ThrowableProxy t = (ThrowableProxy) throwable;
-            final String trace = t.getExtendedStackTrace(packages);
+            final String trace = t.getExtendedStackTrace(options.getPackages());
             final int len = toAppendTo.length();
             if (len > 0 && !Character.isWhitespace(toAppendTo.charAt(len - 1)))
{
                 toAppendTo.append(" ");
             }
-            if (lines != Integer.MAX_VALUE) {
+            if (!options.allLines() || !Constants.LINE_SEP.equals(options.getSeparator()))
{
                 final StringBuilder sb = new StringBuilder();
-                final String[] array = trace.split("\n");
-                final int limit = lines > array.length ? array.length : lines;
-                for (int i = 0; i < limit; ++i) {
-                    sb.append(array[i]).append("\n");
+                final String[] array = trace.split(Constants.LINE_SEP);
+                final int limit = options.minLines(array.length) - 1;
+                for (int i = 0; i <= limit; ++i) {
+                    sb.append(array[i]);
+                    if (i < limit) {
+                        sb.append(options.getSeparator());
+                    }
                 }
                 toAppendTo.append(sb.toString());
 

Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java?rev=1463226&r1=1463225&r2=1463226&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
(original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
Mon Apr  1 17:52:39 2013
@@ -18,13 +18,9 @@ package org.apache.logging.log4j.core.pa
 
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.helpers.Constants;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-
-
 /**
  * Outputs the Throwable portion of the LoggingEvent as a full stacktrace
  * unless this converter's option is 'short', where it just outputs the first line of the
trace, or if
@@ -37,10 +33,6 @@ import java.util.Scanner;
 @ConverterKeys({"rEx", "rThrowable", "rException" })
 public final class RootThrowablePatternConverter extends ThrowablePatternConverter {
 
-    private static final String FILTERS = "filters(";
-
-    private final List<String> packages;
-
     /**
      * Private constructor.
      *
@@ -48,20 +40,6 @@ public final class RootThrowablePatternC
      */
     private RootThrowablePatternConverter(final String[] options) {
         super("RootThrowable", "throwable", options);
-        List<String> tempPackages = null;
-        if (options != null && options.length > 1) {
-            if (options[1].startsWith(FILTERS) && options[1].endsWith(")")) {
-                final String filterStr = options[1].substring(FILTERS.length(), options[1].length()
- 1);
-                final String[] array = filterStr.split(",");
-                if (array.length > 0) {
-                    tempPackages = new ArrayList<String>(array.length);
-                    for (final String token : array) {
-                        tempPackages.add(token.trim());
-                    }
-                }
-            }
-        }
-        packages = tempPackages;
     }
 
     /**
@@ -72,23 +50,7 @@ public final class RootThrowablePatternC
      * @return instance of class.
      */
     public static RootThrowablePatternConverter newInstance(final String[] options) {
-        String type = null;
-        String[] array = options;
-        if (options != null && options.length == 1 && options[0].length()
> 0) {
-            final String[] opts = options[0].split(",", 2);
-            final String first = opts[0].trim();
-            String filter;
-            final Scanner scanner = new Scanner(first);
-            if (first.equalsIgnoreCase(FULL) || first.equalsIgnoreCase(SHORT) || scanner.hasNextInt())
{
-                type = first;
-                filter = opts[1].trim();
-            } else {
-                filter = options[0].trim();
-            }
-            array = new String[] {type, filter};
-        }
-
-        return new RootThrowablePatternConverter(array);
+        return new RootThrowablePatternConverter(options);
     }
 
     /**
@@ -97,23 +59,26 @@ public final class RootThrowablePatternC
     @Override
     public void format(final LogEvent event, final StringBuilder toAppendTo) {
         final Throwable throwable = event.getThrown();
-        if (throwable != null && lines > 0) {
+        if (throwable != null && options.anyLines()) {
             if (!(throwable instanceof ThrowableProxy)) {
                 super.format(event, toAppendTo);
                 return;
             }
             final ThrowableProxy t = (ThrowableProxy) throwable;
-            final String trace = t.getRootCauseStackTrace(packages);
+            final String trace = t.getRootCauseStackTrace(options.getPackages());
             final int len = toAppendTo.length();
             if (len > 0 && !Character.isWhitespace(toAppendTo.charAt(len - 1)))
{
                 toAppendTo.append(" ");
             }
-            if (lines != Integer.MAX_VALUE) {
+            if (!options.allLines() || !Constants.LINE_SEP.equals(options.getSeparator()))
{
                 final StringBuilder sb = new StringBuilder();
-                final String[] array = trace.split("\n");
-                final int limit = lines > array.length ? array.length : lines;
-                for (int i = 0; i < limit; ++i) {
-                    sb.append(array[i]).append("\n");
+                final String[] array = trace.split(Constants.LINE_SEP);
+                final int limit = options.minLines(array.length) - 1;
+                for (int i = 0; i <= limit; ++i) {
+                    sb.append(array[i]);
+                    if (i < limit) {
+                        sb.append(options.getSeparator());
+                    }
                 }
                 toAppendTo.append(sb.toString());
 

Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java?rev=1463226&r1=1463225&r2=1463226&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
(original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
Mon Apr  1 17:52:39 2013
@@ -18,6 +18,8 @@ package org.apache.logging.log4j.core.pa
 
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.helpers.Constants;
+import org.apache.logging.log4j.core.impl.ThrowableFormatOptions;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -33,28 +35,9 @@ import java.io.StringWriter;
 public class ThrowablePatternConverter extends LogEventPatternConverter {
 
     /**
-     * Do not format the exception.
-     */
-    protected static final String NONE = "none";
-    /**
-     * Format the whole stack trace.
-     */
-    protected static final String FULL = "full";
-    /**
-     * Format only the first line of the throwable.
-     */
-    protected static final String SHORT = "short";
-    /**
-     * If "short", only first line of throwable report will be formatted.<br>
-     * If "full", the whole stack trace will be formatted.<br>
-     * If "numeric" the output will be limited to the specified number of lines.
-     */
-    protected final String option;
-
-    /**
      * The number of lines to write.
      */
-    protected final int lines;
+    protected final ThrowableFormatOptions options;
 
     /**
      * Constructor.
@@ -64,22 +47,7 @@ public class ThrowablePatternConverter e
      */
     protected ThrowablePatternConverter(final String name, final String style, final String[]
options) {
         super(name, style);
-        int count = Integer.MAX_VALUE;
-        if (options != null && options.length > 0) {
-            option = options[0];
-            if (option == null) {
-            } else if (option.equalsIgnoreCase(NONE)) {
-                count = 0;
-            } else if (option.equalsIgnoreCase(SHORT)) {
-                count = 2;
-            } else if (!option.equalsIgnoreCase(FULL)) {
-                count = Integer.parseInt(option);
-            }
-
-        } else {
-            option = null;
-        }
-        lines = count;
+        this.options = ThrowableFormatOptions.newInstance(options);
     }
 
     /**
@@ -100,19 +68,22 @@ public class ThrowablePatternConverter e
     public void format(final LogEvent event, final StringBuilder toAppendTo) {
         final Throwable t = event.getThrown();
 
-        if (t != null && lines > 0) {
+        if (t != null && options.anyLines()) {
             final StringWriter w = new StringWriter();
             t.printStackTrace(new PrintWriter(w));
             final int len = toAppendTo.length();
             if (len > 0 && !Character.isWhitespace(toAppendTo.charAt(len - 1)))
{
                 toAppendTo.append(" ");
             }
-            if (lines != Integer.MAX_VALUE) {
+            if (!options.allLines() || !Constants.LINE_SEP.equals(options.getSeparator()))
{
                 final StringBuilder sb = new StringBuilder();
-                final String[] array = w.toString().split("\n");
-                final int limit = lines > array.length ? array.length : lines;
-                for (int i = 0; i < limit; ++i) {
-                    sb.append(array[i]).append("\n");
+                final String[] array = w.toString().split(Constants.LINE_SEP);
+                final int limit = options.minLines(array.length) - 1;
+                for (int i = 0; i <= limit; ++i) {
+                    sb.append(array[i]);
+                    if (i < limit) {
+                        sb.append(options.getSeparator());
+                    }
                 }
                 toAppendTo.append(sb.toString());
 

Added: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java?rev=1463226&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
(added)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
Mon Apr  1 17:52:39 2013
@@ -0,0 +1,334 @@
+/*
+ * 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.impl;
+
+import org.apache.logging.log4j.core.helpers.Constants;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Unit tests for {@code ThrowableFormatOptions}.
+ */
+public final class ThrowableFormatOptionsTest {
+
+    /**
+     * Runs a given test comparing against the expected values.
+     * @param options The list of options to parse.
+     * @param expectedLines The expected lines.
+     * @param expectedPackages The expected package filters.
+     * @param expectedSeparator The expected seperator.
+     */
+    private static void test(final String[] options, final int expectedLines, final String
expectedSeparator, final List<String> expectedPackages) {
+        final ThrowableFormatOptions o = ThrowableFormatOptions.newInstance(options);
+        assertEquals("getLines", expectedLines, o.getLines());
+        assertEquals("getSeparator", expectedSeparator, o.getSeparator());
+        assertEquals("getPackages", expectedPackages, o.getPackages());
+        assertEquals("allLines", expectedLines == Integer.MAX_VALUE, o.allLines());
+        assertEquals("anyLines", expectedLines != 0, o.anyLines());
+        assertEquals("minLines", 0, o.minLines(0));
+        assertEquals("minLines", expectedLines, o.minLines(Integer.MAX_VALUE));
+        assertEquals("hasPackages", expectedPackages != null && !expectedPackages.isEmpty(),
o.hasPackages());
+        assertNotNull("toString", o.toString());
+    }
+
+    /**
+     * Test {@code %throwable } with null options.
+     */
+    @Test
+    public void testNull() {
+        test(null, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable }
+     */
+    @Test
+    public void testEmpty() {
+        test(new String[]{}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{} } with null option value.
+     */
+    @Test
+    public void testOneNullElement() {
+        test(new String[]{null}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{} }
+     */
+    @Test
+    public void testOneEmptyElement() {
+        test(new String[]{""}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{full} }
+     */
+    @Test
+    public void testFull() {
+        test(new String[]{"full"}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{none} }
+     */
+    @Test
+    public void testNone() {
+        test(new String[]{"none"}, 0, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{short} }
+     */
+    @Test
+    public void testShort() {
+        test(new String[]{"short"}, 2, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{10} }
+     */
+    @Test
+    public void testDepth() {
+        test(new String[]{"10"}, 10, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{separator(|)} }
+     */
+    @Test
+    public void testSeparator() {
+        test(new String[]{"separator(|)"}, Integer.MAX_VALUE, "|", null);
+    }
+
+    /**
+     * Test {@code %throwable{separator()} }
+     */
+    @Test
+    public void testSeparatorAsEmpty() {
+        test(new String[]{"separator()"}, Integer.MAX_VALUE, "", null);
+    }
+
+    /**
+     * Test {@code %throwable{separator(\n)} }
+     */
+    @Test
+    public void testSeparatorAsDefaultLineSeparator() {
+        test(new String[]{"separator(\n)"}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{separator(|)} }
+     */
+    @Test
+    public void testSeparatorAsMultipleCharacters() {
+        test(new String[]{"separator( | )"}, Integer.MAX_VALUE, " | ", null);
+    }
+
+    /**
+     * Test {@code %throwable{full}{separator(|)} }
+     */
+    @Test
+    public void testFullAndSeparator() {
+        test(new String[]{"full","separator(|)"}, Integer.MAX_VALUE, "|", null);
+    }
+
+    /**
+     * Test {@code %throwable{none}{separator(|)} }
+     */
+    @Test
+    public void testNoneAndSeparator() {
+        test(new String[]{"none","separator(|)"}, 0, "|", null);
+    }
+
+    /**
+     * Test {@code %throwable{short}{separator(|)} }
+     */
+    @Test
+    public void testShortAndSeparator() {
+        test(new String[]{"short","separator(|)"}, 2, "|", null);
+    }
+
+    /**
+     * Test {@code %throwable{10}{separator(|)} }
+     */
+    @Test
+    public void testDepthAndSeparator() {
+        test(new String[]{"10","separator(|)"}, 10, "|", null);
+    }
+
+    /**
+     * Test {@code %throwable{filters(packages)} }
+     */
+    @Test
+    public void testFilters() {
+        test(new String[]{"filters(packages)"}, Integer.MAX_VALUE, Constants.LINE_SEP, Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{filters()} }
+     */
+    @Test
+    public void testFiltersAsEmpty() {
+        test(new String[]{"filters()"}, Integer.MAX_VALUE, Constants.LINE_SEP, null);
+    }
+
+    /**
+     * Test {@code %throwable{filters(package1,package2)} }
+     */
+    @Test
+    public void testFiltersAsMultiplePackages() {
+        test(new String[]{"filters(package1,package2)"}, Integer.MAX_VALUE, Constants.LINE_SEP,
Arrays.asList("package1","package2"));
+    }
+
+    /**
+     * Test {@code %throwable{full}{filters(packages)} }
+     */
+    @Test
+    public void testFullAndFilters() {
+        test(new String[]{"full","filters(packages)"}, Integer.MAX_VALUE, Constants.LINE_SEP,
Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{none}{filters(packages)} }
+     */
+    @Test
+    public void testNoneAndFilters() {
+        test(new String[]{"none","filters(packages)"}, 0, Constants.LINE_SEP, Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{short}{filters(packages)} }
+     */
+    @Test
+    public void testShortAndFilters() {
+        test(new String[]{"short","filters(packages)"}, 2, Constants.LINE_SEP, Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{10}{filters(packages)} }
+     */
+    @Test
+    public void testDepthAndFilters() {
+        test(new String[]{"10","filters(packages)"}, 10, Constants.LINE_SEP, Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{full}{separator(|)}{filters(packages)} }
+     */
+    @Test
+    public void testFullAndSeparatorAndFilters() {
+        test(new String[]{"full","separator(|)","filters(packages)"}, Integer.MAX_VALUE,
"|", Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{none}{separator(|)}{filters(packages)} }
+     */
+    @Test
+    public void testNoneAndSeparatorAndFilters() {
+        test(new String[]{"none","separator(|)","filters(packages)"}, 0, "|", Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{short}{separator(|)}{filters(packages)} }
+     */
+    @Test
+    public void testShortAndSeparatorAndFilters() {
+        test(new String[]{"short","separator(|)","filters(packages)"}, 2, "|", Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{10}{separator(|)}{filters(packages)} }
+     */
+    @Test
+    public void testDepthAndSeparatorAndFilters() {
+        test(new String[]{"10","separator(|)","filters(packages)"}, 10, "|", Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{full,filters(packages)} }
+     */
+    @Test
+    public void testSingleOptionFullAndFilters() {
+        test(new String[]{"full,filters(packages)"}, Integer.MAX_VALUE, Constants.LINE_SEP,
Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{none,filters(packages)} }
+     */
+    @Test
+    public void testSingleOptionNoneAndFilters() {
+        test(new String[]{"none,filters(packages)"}, 0, Constants.LINE_SEP, Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{short,filters(packages)} }
+     */
+    @Test
+    public void testSingleOptionShortAndFilters() {
+        test(new String[]{"short,filters(packages)"}, 2, Constants.LINE_SEP, Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{none,filters(packages)} }
+     */
+    @Test
+    public void testSingleOptionDepthAndFilters() {
+        test(new String[]{"10,filters(packages)"}, 10, Constants.LINE_SEP, Arrays.asList("packages"));
+    }
+
+    /**
+     * Test {@code %throwable{full,filters(package1,package2)} }
+     */
+    @Test
+    public void testSingleOptionFullAndMultipleFilters() {
+        test(new String[]{"full,filters(package1,package2)"}, Integer.MAX_VALUE, Constants.LINE_SEP,
Arrays.asList("package1","package2"));
+    }
+
+    /**
+     * Test {@code %throwable{none,filters(package1,package2)} }
+     */
+    @Test
+    public void testSingleOptionNoneAndMultipleFilters() {
+        test(new String[]{"none,filters(package1,package2)"}, 0, Constants.LINE_SEP, Arrays.asList("package1","package2"));
+    }
+
+    /**
+     * Test {@code %throwable{short,filters(package1,package2)} }
+     */
+    @Test
+    public void testSingleOptionShortAndMultipleFilters() {
+        test(new String[]{"short,filters(package1,package2)"}, 2, Constants.LINE_SEP, Arrays.asList("package1","package2"));
+    }
+
+    /**
+     * Test {@code %throwable{none,filters(package1,package2)} }
+     */
+    @Test
+    public void testSingleOptionDepthAndMultipleFilters() {
+        test(new String[]{"10,filters(package1,package2)"}, 10, Constants.LINE_SEP, Arrays.asList("package1","package2"));
+    }
+}

Added: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java?rev=1463226&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
(added)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
Mon Apr  1 17:52:39 2013
@@ -0,0 +1,76 @@
+/*
+ * 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.pattern;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.XMLConfigurationFactory;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests for {@code throwable} pattern.
+ */
+public class ThrowableTest {
+    private static final String CONFIG = "log4j-throwable.xml";
+    private static Configuration config;
+    private static ListAppender app;
+    private static LoggerContext ctx;
+
+    @BeforeClass
+    public static void setupClass() {
+        System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
+        ctx = (LoggerContext) LogManager.getContext(false);
+        config = ctx.getConfiguration();
+        for (final Map.Entry<String, Appender<?>> entry : config.getAppenders().entrySet())
{
+            if (entry.getKey().equals("List")) {
+                app = (ListAppender) entry.getValue();
+            }
+        }
+    }
+
+    @AfterClass
+    public static void cleanupClass() {
+        System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
+        ctx.reconfigure();
+        StatusLogger.getLogger().reset();
+    }
+
+    org.apache.logging.log4j.Logger logger = LogManager.getLogger("LoggerTest");
+
+    @Test
+    public void testException() {
+        final Throwable cause = new NullPointerException("null pointer");
+        final Throwable parent = new IllegalArgumentException("IllegalArgument", cause);
+        logger.error("Exception", parent);
+        final List<String> msgs = app.getMessages();
+        assertNotNull(msgs);
+        assertTrue("Incorrect number of messages. Should be 1 is " + msgs.size(), msgs.size()
== 1);
+        assertFalse("No suppressed lines", msgs.get(0).contains("suppressed"));
+        app.clear();
+    }
+}

Added: logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml?rev=1463226&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml (added)
+++ logging/log4j/log4j2/trunk/core/src/test/resources/log4j-throwable.xml Mon Apr  1 17:52:39
2013
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<configuration status="warn" name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+  <properties>
+    <property name="filters">org.junit,org.apache.maven,sun.reflect,java.lang.reflect</property>
+  </properties>
+  <ThresholdFilter level="debug"/>
+
+  <appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%ex{full}{separator( | )}%n"/>
+    </Console>
+    <List name="List">
+      <PatternLayout pattern="%m%ex{separator( | )}%n"/>
+    </List>
+  </appenders>
+
+  <loggers>
+    <root level="error">
+      <appender-ref ref="List"/>
+    </root>
+  </loggers>
+
+</configuration>

Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1463226&r1=1463225&r2=1463226&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Mon Apr  1 17:52:39 2013
@@ -23,6 +23,9 @@
 
   <body>
     <release version="2.0-beta5" date="@TBD@" description="Bug fixes and enhancements">
+      <action issue="LOG4J2-160" dev="rgoers" type="update" due-to="Joanne Polsky">
+        Move Throwable pattern converter options processing to ThrowableFormatOptions class.
+      </action>
       <action issue="LOG4J2-157" dev="rgoers" type="update" due-to="Remko Popma">
         Allowed Loggers access to the properties in the LoggerConfig.
       </action>



Mime
View raw message