- add support for array values in parameters

  For example, 
  
  log.debug("a:{},i:{}", "A", new int[] {1, 2}});
  will print as "a:A,i:[1, 2]" instead of "a:A,i:[I@6ca1c" as previously
  
  log.debug("a:{},b:{},i:{},", new Object[] {"A", "B", new int[] {1, 2}});
  will print as "a:A,b:B,i:[1, 2]" instead of "a:A,b:B,i:[I@90c78" as previously

  This enhancement was proposed by "lizongbo"
diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java b/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java
index 8bd218e..b4f95f3 100644
--- a/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java
+++ b/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java
@@ -24,12 +24,20 @@
 

 package org.slf4j.helpers;

 

+import java.util.Arrays;

+

+// contributors: lizongbo

+

 /**

  * Formats messages according to very simple substitution rules. Substitutions

  * can be made 1, 2 or more arguments.

  * <p>

  * For example,

- * <pre>MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;);</pre>

+ * 

+ * <pre>

+ * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;);

+ * </pre>

+ * 

  * will return the string "Hi there.".

  * <p>

  * The {} pair is called the <em>formatting anchor</em>. It serves to

@@ -40,14 +48,22 @@
  * pattern itself but do not want them to be interpreted as a formatting

  * anchors, you can escape the '{' character with '\', that is the backslash

  * character. Only the '{' character should be escaped. There is no need to

- * escape the '}' character. For example, 

- * <pre>MessageFormatter.format(&quot;Set \\{1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);</pre>

- * will return the string "Set {1,2,3} is not equal to 1,2.". 

+ * escape the '}' character. For example,

+ * 

+ * <pre>

+ * MessageFormatter.format(&quot;Set \\{1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);

+ * </pre>

+ * 

+ * will return the string "Set {1,2,3} is not equal to 1,2.".

  * 

  * <p>

- * The escaping behavior just described can be overridden by 

- * escaping the escape character '\'. Calling

- * <pre>MessageFormatter.format(&quot;File name is C:\\\\{}.&quot;, &quot;file.zip&quot;);</pre>

+ * The escaping behavior just described can be overridden by escaping the escape

+ * character '\'. Calling

+ * 

+ * <pre>

+ * MessageFormatter.format(&quot;File name is C:\\\\{}.&quot;, &quot;file.zip&quot;);

+ * </pre>

+ * 

  * will return the string "File name is C:\file.zip".

  * 

  * <p>

@@ -60,7 +76,7 @@
   static final char DELIM_START = '{';

   static final char DELIM_STOP = '}';

   private static final char ESCAPE_CHAR = '\\';

-  

+

   /**

    * Performs single argument substitution for the 'messagePattern' passed as

    * parameter.

@@ -75,9 +91,10 @@
    * <p>

    * 

    * @param messagePattern

-   *          The message pattern which will be parsed and formatted

+   *                The message pattern which will be parsed and formatted

    * @param argument

-   *          The argument to be substituted in place of the formatting anchor

+   *                The argument to be substituted in place of the formatting

+   *                anchor

    * @return The formatted message

    */

   public static String format(String messagePattern, Object arg) {

@@ -98,13 +115,13 @@
    * will return the string "Hi Alice. My name is Bob.".

    * 

    * @param messagePattern

-   *          The message pattern which will be parsed and formatted

+   *                The message pattern which will be parsed and formatted

    * @param arg1

-   *          The argument to be substituted in place of the first formatting

-   *          anchor

+   *                The argument to be substituted in place of the first

+   *                formatting anchor

    * @param arg2

-   *          The argument to be substituted in place of the second formatting

-   *          anchor

+   *                The argument to be substituted in place of the second

+   *                formatting anchor

    * @return The formatted message

    */

   public static String format(String messagePattern, Object arg1, Object arg2) {

@@ -117,10 +134,10 @@
    * arguments can be passed in an array.

    * 

    * @param messagePattern

-   *          The message pattern which will be parsed and formatted

+   *                The message pattern which will be parsed and formatted

    * @param argArray

-   *          An array of arguments to be substituted in place of formatting

-   *          anchors

+   *                An array of arguments to be substituted in place of

+   *                formatting anchors

    * @return The formatted message

    */

   public static String arrayFormat(String messagePattern, Object[] argArray) {

@@ -131,10 +148,10 @@
     int len = messagePattern.length();

     int j = messagePattern.indexOf(DELIM_START);

 

-    if(argArray == null) {

+    if (argArray == null) {

       return messagePattern;

     }

-    

+

     StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);

 

     for (int L = 0; L < argArray.length; L++) {

@@ -154,7 +171,7 @@
         char delimStop = messagePattern.charAt(j + 1);

 

         if (isEscapedDelimeter(messagePattern, j)) {

-          if(!isDoubleEscaped(messagePattern, j)) {

+          if (!isDoubleEscaped(messagePattern, j)) {

             L--; // DELIM_START was escaped, thus should not be incremented

             sbuf.append(messagePattern.substring(i, j - 1));

             sbuf.append(DELIM_START);

@@ -163,8 +180,9 @@
             // The escape character preceding the delemiter start is

             // itself escaped: "abc x:\\{}"

             // we have to consume one backward slash

-            sbuf.append(messagePattern.substring(i, j-1));

-            sbuf.append(argArray[L]);

+            sbuf.append(messagePattern.substring(i, j - 1));

+            appendParameter(sbuf, argArray[L]);

+            // sbuf.append(argArray[L]);

             i = j + 2;

           }

         } else if ((delimStop != DELIM_STOP)) {

@@ -174,7 +192,7 @@
         } else {

           // normal case

           sbuf.append(messagePattern.substring(i, j));

-          sbuf.append(argArray[L]);

+          appendParameter(sbuf, argArray[L]);

           i = j + 2;

         }

       }

@@ -206,4 +224,31 @@
       return false;

     }

   }

+

+  // special treatment of array values was suggested by 'lizongbo'

+  private static void appendParameter(StringBuffer sbuf, Object o) {

+    if (o != null && o.getClass().isArray()) {

+      // check for primitive arrays because they unfortunately 

+      // cannot be cast to Object[]

+      if (o instanceof boolean[]) {

+        sbuf.append(Arrays.toString((boolean[]) o));

+      } else if (o instanceof byte[]) {

+        sbuf.append(Arrays.toString((byte[]) o));

+      } else if (o instanceof char[]) {

+        sbuf.append(Arrays.toString((char[]) o));

+      } else if (o instanceof short[]) {

+        sbuf.append(Arrays.toString((short[]) o));

+      } else if (o instanceof int[]) {

+        sbuf.append(Arrays.toString((int[]) o));

+      } else if (o instanceof long[]) {

+        sbuf.append(Arrays.toString((long[]) o));

+      } else if (o instanceof float[]) {

+        sbuf.append(Arrays.toString((float[]) o));

+      } else {

+        sbuf.append(Arrays.toString((Object[]) o));

+      }

+    } else {

+      sbuf.append(o);

+    }

+  }

 }

diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java b/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java
index f1f205b..18a52e8 100644
--- a/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java
+++ b/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java
@@ -33,56 +33,59 @@
 

 package org.slf4j.helpers;

 

+import java.util.Arrays;

+

 import org.slf4j.helpers.MessageFormatter;

 

 import junit.framework.TestCase;

 

-

 /**

  * @author Ceki Gulcu

- *

+ * 

  */

 public class MessageFormatterTest extends TestCase {

-  

+

   Integer i1 = new Integer(1);

   Integer i2 = new Integer(2);

   Integer i3 = new Integer(3);

-  

+

   public void testNull() {

     String result;

     result = MessageFormatter.format(null, i1);

     assertEquals(null, result);

   }

-  

+

   public void testNullParam() {

     String result;

-    

+

     result = MessageFormatter.format("Value is {}.", null);

     assertEquals("Value is null.", result);

-    

+

     result = MessageFormatter.format("Val1 is {}, val2 is {}.", null, null);

     assertEquals("Val1 is null, val2 is null.", result);

-    

+

     result = MessageFormatter.format("Val1 is {}, val2 is {}.", i1, null);

     assertEquals("Val1 is 1, val2 is null.", result);

-    

+

     result = MessageFormatter.format("Val1 is {}, val2 is {}.", null, i2);

     assertEquals("Val1 is null, val2 is 2.", result);

- 

-    result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", new Integer[]{null, null, null});

+

+    result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}",

+        new Integer[] { null, null, null });

     assertEquals("Val1 is null, val2 is null, val3 is null", result);

-    

-    result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", new Integer[]{null, i2, i3});

+

+    result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}",

+        new Integer[] { null, i2, i3 });

     assertEquals("Val1 is null, val2 is 2, val3 is 3", result);

-    

-    result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", new Integer[]{null, null, i3});

+

+    result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}",

+        new Integer[] { null, null, i3 });

     assertEquals("Val1 is null, val2 is null, val3 is 3", result);

   }

-  

-  

+

   public void testOneParameter() {

     String result;

-    

+

     result = MessageFormatter.format("Value is {}.", i3);

     assertEquals("Value is 3.", result);

 

@@ -94,13 +97,13 @@
 

     result = MessageFormatter.format("No subst", i3);

     assertEquals("No subst", result);

-    

+

     result = MessageFormatter.format("Incorrect {subst", i3);

     assertEquals("Incorrect {subst", result);

-    

+

     result = MessageFormatter.format("Value is \\{bla} {}", i3);

     assertEquals("Value is {bla} 3", result);

-    

+

     result = MessageFormatter.format("Escaped \\{} subst", i3);

     assertEquals("Escaped {} subst", result);

 

@@ -109,51 +112,52 @@
 

     result = MessageFormatter.format("\\{}Escaped", i3);

     assertEquals("{}Escaped", result);

-    

+

     result = MessageFormatter.format("File name is \\{{}}.", "App folder.zip");

     assertEquals("File name is {App folder.zip}.", result);

-    

+

     // escaping the escape character

-    result = MessageFormatter.format("File name is C:\\\\{}.", "App folder.zip");

+    result = MessageFormatter

+        .format("File name is C:\\\\{}.", "App folder.zip");

     assertEquals("File name is C:\\App folder.zip.", result);

   }

-  

+

   public void testTwoParameters() {

     String result;

 

-    

     result = MessageFormatter.format("Value {} is smaller than {}.", i1, i2);

     assertEquals("Value 1 is smaller than 2.", result);

-    

+

     result = MessageFormatter.format("Value {} is smaller than {}", i1, i2);

     assertEquals("Value 1 is smaller than 2", result);

-    

+

     result = MessageFormatter.format("{}{}", i1, i2);

     assertEquals("12", result);

-    

+

     result = MessageFormatter.format("Val1={}, Val2={", i1, i2);

     assertEquals("Val1=1, Val2={", result);

 

     result = MessageFormatter.format("Value {} is smaller than \\{}", i1, i2);

     assertEquals("Value 1 is smaller than {}", result);

-    

-    result = MessageFormatter.format("Value {} is smaller than \\{} tail", i1, i2);

-    assertEquals("Value 1 is smaller than {} tail", result);    

+

+    result = MessageFormatter.format("Value {} is smaller than \\{} tail", i1,

+        i2);

+    assertEquals("Value 1 is smaller than {} tail", result);

 

     result = MessageFormatter.format("Value {} is smaller than \\{", i1, i2);

-    assertEquals("Value 1 is smaller than \\{", result);  

-    

-    result = MessageFormatter.format("Value {} is smaller than \\{tail", i1, i2);

-    assertEquals("Value 1 is smaller than {tail", result);  

-  

-    

+    assertEquals("Value 1 is smaller than \\{", result);

+

+    result = MessageFormatter

+        .format("Value {} is smaller than \\{tail", i1, i2);

+    assertEquals("Value 1 is smaller than {tail", result);

+

     result = MessageFormatter.format("Value \\{} is smaller than {}", i1, i2);

-    assertEquals("Value {} is smaller than 1", result);    

+    assertEquals("Value {} is smaller than 1", result);

   }

-  

+

   public void testNullArray() {

     String result;

-    

+

     String msg0 = "msg0";

     String msg1 = "msg1 {}";

     String msg2 = "msg2 {} {}";

@@ -163,44 +167,69 @@
 

     result = MessageFormatter.arrayFormat(msg0, args);

     assertEquals(msg0, result);

-    

+

     result = MessageFormatter.arrayFormat(msg1, args);

     assertEquals(msg1, result);

-    

+

     result = MessageFormatter.arrayFormat(msg2, args);

     assertEquals(msg2, result);

-    

+

     result = MessageFormatter.arrayFormat(msg3, args);

     assertEquals(msg3, result);

   }

-  public void testArray() {

+

+  // tests the case when the parameters are supplied in a single array

+  public void testArrayFormat() {

     String result;

 

-    Integer[] ia = new Integer[] {i1, i2, i3};

+    Integer[] ia = new Integer[] { i1, i2, i3 };

 

-    result = MessageFormatter.arrayFormat("Value {} is smaller than {} and {}.", ia);

+    result = MessageFormatter.arrayFormat(

+        "Value {} is smaller than {} and {}.", ia);

     assertEquals("Value 1 is smaller than 2 and 3.", result);

-    

+

     result = MessageFormatter.arrayFormat("{}{}{}", ia);

     assertEquals("123", result);

-    

+

     result = MessageFormatter.arrayFormat("Value {} is smaller than {}.", ia);

     assertEquals("Value 1 is smaller than 2.", result);

-    

+

     result = MessageFormatter.arrayFormat("Value {} is smaller than {}", ia);

     assertEquals("Value 1 is smaller than 2", result);

-   

+

     result = MessageFormatter.arrayFormat("Val={}, {, Val={}", ia);

     assertEquals("Val=1, {, Val={}", result);

-   

+

     result = MessageFormatter.arrayFormat("Val={}, \\{, Val={}", ia);

     assertEquals("Val=1, {, Val=2", result);

-   

-    

+

     result = MessageFormatter.arrayFormat("Val1={}, Val2={", ia);

     assertEquals("Val1=1, Val2={", result);

-    

+  }

 

+  public void testArrayValues() {

+

+    String result;

+

+    Integer p0 = i1;

+    Integer[] p1 = new Integer[] { i2, i3 };

+

+    System.out.println("[" + Arrays.toString(new int[] { 1, 2 }) + "]");

+

+    result = MessageFormatter.format("{}{}", p0, p1);

+    assertEquals(p0 + Arrays.toString(p1), result);

+

+    {

+      Object[] pa = new Object[] { "a", p1 };

+      result = MessageFormatter.arrayFormat("{}{}", pa);

+      assertEquals("a" + Arrays.toString(p1), result);

+    }

+

+    {

+      Object[] pa = new Object[] { "a", new int[] { 1, 2 } };

+      result = MessageFormatter.arrayFormat("{}{}", pa);

+      assertEquals("a" + Arrays.toString(new int[] { 1, 2 }), result);

+    }

   }

 

 }