Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* ************************************************************************
  #
  #  DivConq
  #
  #  http://divconq.com/
  #
  #  Copyright:
  #    Copyright 2014 eTimeline, LLC. All rights reserved.
  #
 #  License:
 #    See the license.txt file in the project's top-level directory for details.
 #
 #  Authors:
 #    * Andy White
 #
 ************************************************************************ */
 package divconq.log.slf4j;
 
 import java.util.Map;
 
 // contributors: lizongbo: proposed special treatment of array parameter values
 // Joern Huxhorn: pointed out double[] omission, suggested deep array copy
 
Formats messages according to very simple substitution rules. Substitutions can be made 1, 2 or more arguments. For example,
 MessageFormatter.format("Hi {}.", "there")
 
will return the string "Hi there.". The {} pair is called the formatting anchor. It serves to designate the location where arguments need to be substituted within the message pattern. In case your message contains the '{' or the '}' character, you do not have to do anything special unless the '}' character immediately follows '{'. For example,
 MessageFormatter.format("Set {1,2,3} is not equal to {}.", "1,2");
 
will return the string "Set {1,2,3} is not equal to 1,2.". If for whatever reason you need to place the string "{}" in the message without its formatting anchor meaning, then you need to 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,
 MessageFormatter.format("Set \\{} is not equal to {}.", "1,2");
 
will return the string "Set {} is not equal to 1,2.". The escaping behavior just described can be overridden by escaping the escape character '\'. Calling
 MessageFormatter.format("File name is C:\\\\{}.", "file.zip");
 
will return the string "File name is C:\file.zip". The formatting conventions are different than those of java.text.MessageFormat which ships with the Java platform. This is justified by the fact that SLF4J's implementation is 10 times faster than that of java.text.MessageFormat. This local performance difference is both measurable and significant in the larger context of the complete logging processing chain. See also format(java.lang.String,java.lang.Object), format(java.lang.String,java.lang.Object,java.lang.Object) and arrayFormat(java.lang.String,java.lang.Object[]) methods for more details.
 
 public class MessageFormatter {
     static final char DELIM_START = '{';
     static final char DELIM_STOP = '}';
     static final String DELIM_STR = "{}";
     private static final char ESCAPE_CHAR = '\\';

    
Performs single argument substitution for the 'messagePattern' passed as parameter. For example,
 MessageFormatter.format("Hi {}.", "there");
 
will return the string "Hi there.".

Parameters:
messagePattern The message pattern which will be parsed and formatted
arg The argument to be substituted in place of the formatting anchor
Returns:
The formatted message
    static public FormattingTuple format(String messagePatternObject arg) {
        return arrayFormat(messagePatternnew Object[]{arg});
    }

    
Performs a two argument substitution for the 'messagePattern' passed as parameter. For example,
 MessageFormatter.format("Hi {}. My name is {}.", "Alice", "Bob");
 
will return the string "Hi Alice. My name is Bob.".

Parameters:
messagePattern The message pattern which will be parsed and formatted
argA The argument to be substituted in place of the first formatting anchor
argB The argument to be substituted in place of the second formatting anchor
Returns:
The formatted message
    static public FormattingTuple format(final String messagePattern,
                                  Object argAObject argB) {
        return arrayFormat(messagePatternnew Object[]{argAargB});
    }
    static public Throwable getThrowableCandidate(Object[] argArray) {
        if (argArray == null || argArray.length == 0) {
            return null;
        }
        final Object lastEntry = argArray[argArray.length - 1];
        if (lastEntry instanceof Throwable) {
            return (ThrowablelastEntry;
        }
        return null;
    }

    
Same principle as the format(java.lang.String,java.lang.Object) and format(java.lang.String,java.lang.Object,java.lang.Object) methods except that any number of arguments can be passed in an array.

Parameters:
messagePattern The message pattern which will be parsed and formatted
argArray An array of arguments to be substituted in place of formatting anchors
Returns:
The formatted message
    static public FormattingTuple arrayFormat(final String messagePattern,
                                       final Object[] argArray) {
        Throwable throwableCandidate = getThrowableCandidate(argArray);
        if (messagePattern == null) {
            return new FormattingTuple(nullargArraythrowableCandidate);
        }
        if (argArray == null) {
            return new FormattingTuple(messagePattern);
        }
        int i = 0;
        int j;
        StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);
        int L;
        for (L = 0; L < argArray.lengthL++) {
            j = messagePattern.indexOf(i);
            if (j == -1) {
                // no more variables
                if (i == 0) { // this is a simple string
                    return new FormattingTuple(messagePatternargArray,
                            throwableCandidate);
                } else { // add the tail string which contains no variables and return
                    // the result.
                    sbuf.append(messagePattern.substring(imessagePattern.length()));
                    return new FormattingTuple(sbuf.toString(), argArray,
                            throwableCandidate);
                }
            } else {
                if (isEscapedDelimeter(messagePatternj)) {
                    if (!isDoubleEscaped(messagePatternj)) {
                        L--; // DELIM_START was escaped, thus should not be incremented
                        sbuf.append(messagePattern.substring(ij - 1));
                        sbuf.append();
                        i = j + 1;
                    } else {
                        // The escape character preceding the delimiter start is
                        // itself escaped: "abc x:\\{}"
                        // we have to consume one backward slash
                        sbuf.append(messagePattern.substring(ij - 1));
                        deeplyAppendParameter(sbufargArray[L], new HashMap<Object[], Void>());
                        i = j + 2;
                    }
                } else {
                    // normal case
                    sbuf.append(messagePattern.substring(ij));
                    deeplyAppendParameter(sbufargArray[L], new HashMap<Object[], Void>());
                    i = j + 2;
                }
            }
        }
        // append the characters following the last {} pair.
        sbuf.append(messagePattern.substring(imessagePattern.length()));
        if (L < argArray.length - 1) {
            return new FormattingTuple(sbuf.toString(), argArraythrowableCandidate);
        } else {
            return new FormattingTuple(sbuf.toString(), argArraynull);
        }
    }
    static public boolean isEscapedDelimeter(String messagePattern,
                                      int delimeterStartIndex) {
        if (delimeterStartIndex == 0) {
            return false;
        }
        return messagePattern.charAt(delimeterStartIndex - 1) == ;
    }
    static public boolean isDoubleEscaped(String messagePattern,
                                   int delimeterStartIndex) {
        return delimeterStartIndex >= 2 && messagePattern.charAt(delimeterStartIndex - 2) == ;
    }
    // special treatment of array values was suggested by 'lizongbo'
    private static void deeplyAppendParameter(StringBuffer sbufObject o,
                                              Map<Object[], VoidseenMap) {
        if (o == null) {
            sbuf.append("null");
            return;
        }
        if (!o.getClass().isArray()) {
            safeObjectAppend(sbufo);
        } else {
            // check for primitive array types because they
            // unfortunately cannot be cast to Object[]
            if (o instanceof boolean[]) {
                booleanArrayAppend(sbuf, (boolean[]) o);
            } else if (o instanceof byte[]) {
                byteArrayAppend(sbuf, (byte[]) o);
            } else if (o instanceof char[]) {
                charArrayAppend(sbuf, (char[]) o);
            } else if (o instanceof short[]) {
                shortArrayAppend(sbuf, (short[]) o);
            } else if (o instanceof int[]) {
                intArrayAppend(sbuf, (int[]) o);
            } else if (o instanceof long[]) {
                longArrayAppend(sbuf, (long[]) o);
            } else if (o instanceof float[]) {
                floatArrayAppend(sbuf, (float[]) o);
            } else if (o instanceof double[]) {
                doubleArrayAppend(sbuf, (double[]) o);
            } else {
                objectArrayAppend(sbuf, (Object[]) oseenMap);
            }
        }
    }
    private static void safeObjectAppend(StringBuffer sbufObject o) {
        try {
            String oAsString = o.toString();
            sbuf.append(oAsString);
        } catch (Throwable t) {
            .
                    .println("SLF4J: Failed toString() invocation on an object of type ["
                            + o.getClass().getName() + ']');
            t.printStackTrace();
            sbuf.append("[FAILED toString()]");
        }
    }
    private static void objectArrayAppend(StringBuffer sbufObject[] a,
                                          Map<Object[], VoidseenMap) {
        sbuf.append('[');
        if (!seenMap.containsKey(a)) {
            seenMap.put(anull);
            final int len = a.length;
            for (int i = 0; i < leni++) {
                deeplyAppendParameter(sbufa[i], seenMap);
                if (i != len - 1) {
                    sbuf.append(", ");
                }
            }
            // allow repeats in siblings
            seenMap.remove(a);
        } else {
            sbuf.append("...");
        }
        sbuf.append(']');
    }
    private static void booleanArrayAppend(StringBuffer sbufboolean[] a) {
        sbuf.append('[');
        final int len = a.length;
        for (int i = 0; i < leni++) {
            sbuf.append(a[i]);
            if (i != len - 1) {
                sbuf.append(", ");
            }
        }
        sbuf.append(']');
    }
    private static void byteArrayAppend(StringBuffer sbufbyte[] a) {
        sbuf.append('[');
        final int len = a.length;
        for (int i = 0; i < leni++) {
            sbuf.append(a[i]);
            if (i != len - 1) {
                sbuf.append(", ");
            }
        }
        sbuf.append(']');
    }
    private static void charArrayAppend(StringBuffer sbufchar[] a) {
        sbuf.append('[');
        final int len = a.length;
        for (int i = 0; i < leni++) {
            sbuf.append(a[i]);
            if (i != len - 1) {
                sbuf.append(", ");
            }
        }
        sbuf.append(']');
    }
    private static void shortArrayAppend(StringBuffer sbufshort[] a) {
        sbuf.append('[');
        final int len = a.length;
        for (int i = 0; i < leni++) {
            sbuf.append(a[i]);
            if (i != len - 1) {
                sbuf.append(", ");
            }
        }
        sbuf.append(']');
    }
    private static void intArrayAppend(StringBuffer sbufint[] a) {
        sbuf.append('[');
        final int len = a.length;
        for (int i = 0; i < leni++) {
            sbuf.append(a[i]);
            if (i != len - 1) {
                sbuf.append(", ");
            }
        }
        sbuf.append(']');
    }
    private static void longArrayAppend(StringBuffer sbuflong[] a) {
        sbuf.append('[');
        final int len = a.length;
        for (int i = 0; i < leni++) {
            sbuf.append(a[i]);
            if (i != len - 1) {
                sbuf.append(", ");
            }
        }
        sbuf.append(']');
    }
    private static void floatArrayAppend(StringBuffer sbuffloat[] a) {
        sbuf.append('[');
        final int len = a.length;
        for (int i = 0; i < leni++) {
            sbuf.append(a[i]);
            if (i != len - 1) {
                sbuf.append(", ");
            }
        }
        sbuf.append(']');
    }
    private static void doubleArrayAppend(StringBuffer sbufdouble[] a) {
        sbuf.append('[');
        final int len = a.length;
        for (int i = 0; i < leni++) {
            sbuf.append(a[i]);
            if (i != len - 1) {
                sbuf.append(", ");
            }
        }
        sbuf.append(']');
    }
    private MessageFormatter() {
    }
New to GrepCode? Check out our FAQ X