View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.log4j.helpers;
19  
20  
21  /**
22   * Formats messages according to very simple rules.
23   * See {@link #format(String, Object)} and
24   * {@link #format(String, Object, Object)} for more details.
25   *
26   * @author Ceki Gülcü
27   */
28  public final class MessageFormatter {
29      /**
30       * Private formatter since all methods and members are static.
31       */
32      private MessageFormatter() {
33          super();
34      }
35  
36      /**
37       * Start of replacement block.
38       */
39      private static final char DELIM_START = '{';
40      /**
41       * End of replacement block.
42       */
43      private static final char DELIM_STOP = '}';
44  
45      /**
46       * Performs single argument substitution for the 'messagePattern' passed as
47       * parameter.
48       * <p>
49       * <p>For example, <code>MessageFormatter.format("Hi {}.", "there");</code>
50       * will return the string "Hi there.".
51       * </p>
52       * The {} pair is called the formatting element. It serves to designate the
53       * location where the argument needs to be inserted within the pattern.
54       *
55       * @param messagePattern The message pattern which will be parsed and formatted
56       * @param argument       The argument to be inserted instead of the formatting element
57       * @return The formatted message
58       */
59      public static String format(final String messagePattern,
60                                  final Object argument) {
61          int j = messagePattern.indexOf(DELIM_START);
62          int len = messagePattern.length();
63          char escape = 'x';
64  
65          // if there are no { characters or { is the last character
66          // then we just return messagePattern
67          if (j == -1 || (j + 1 == len)) {
68              return messagePattern;
69          } else {
70              char delimStop = messagePattern.charAt(j + 1);
71              if (j > 0) {
72                  escape = messagePattern.charAt(j - 1);
73              }
74              if ((delimStop != DELIM_STOP) || (escape == '\\')) {
75                  // invalid DELIM_START/DELIM_STOP pair or espace character is
76                  // present
77                  return messagePattern;
78              } else {
79                  String sbuf = messagePattern.substring(0, j) +
80                      argument +
81                      messagePattern.substring(j + 2);
82                  return sbuf;
83              }
84          }
85      }
86  
87      /**
88       * /**
89       * Performs a two argument substitution for the 'messagePattern' passed as
90       * parameter.
91       * <p>
92       * <p>For example, <code>MessageFormatter.format("Hi {}. My name is {}.",
93       * "there", "David");</code> will return the string
94       * "Hi there. My name is David.".
95       * </p>
96       * The '{}' pair is called a formatting element. It serves to designate the
97       * location where the arguments need to be inserted within
98       * the message pattern.
99       *
100      * @param messagePattern The message pattern which will be parsed and formatted
101      * @param arg1           The first argument to replace the first formatting element
102      * @param arg2           The second argument to replace the second formatting element
103      * @return The formatted message
104      */
105     public static String format(final String messagePattern,
106                                 final Object arg1,
107                                 final Object arg2) {
108         int i = 0;
109         int len = messagePattern.length();
110 
111         StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
112 
113         for (int l = 0; l < 2; l++) {
114             int j = messagePattern.indexOf(DELIM_START, i);
115 
116             if (j == -1 || (j + 1 == len)) {
117                 // no more variables
118                 if (i == 0) { // this is a simple string
119                     return messagePattern;
120                 } else {
121                     // add the tail string which contains no variables
122                     // and return the result.
123                     sbuf.append(messagePattern.substring(i,
124                         messagePattern.length()));
125                     return sbuf.toString();
126                 }
127             } else {
128                 char delimStop = messagePattern.charAt(j + 1);
129                 if ((delimStop != DELIM_STOP)) {
130                     // invalid DELIM_START/DELIM_STOP pair
131                     sbuf.append(messagePattern.substring(i,
132                         messagePattern.length()));
133                     return sbuf.toString();
134                 }
135                 sbuf.append(messagePattern.substring(i, j));
136                 if (l == 0) {
137                     sbuf.append(arg1);
138                 } else {
139                     sbuf.append(arg2);
140                 }
141                 i = j + 2;
142             }
143         }
144         // append the characters following the second {} pair.
145         sbuf.append(messagePattern.substring(i, messagePattern.length()));
146         return sbuf.toString();
147     }
148 }