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       *
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
56       *     The message pattern which will be parsed and formatted
57       * @param argument
58       *     The argument to be inserted instead of the formatting element
59       * @return The formatted message
60       */
61      public static String format(final String messagePattern,
62                                  final Object argument) {
63          int j = messagePattern.indexOf(DELIM_START);
64          int len = messagePattern.length();
65          char escape = 'x';
66  
67          // if there are no { characters or { is the last character
68          // then we just return messagePattern
69          if (j == -1 || (j + 1 == len)) {
70              return messagePattern;
71          } else {
72              char delimStop = messagePattern.charAt(j + 1);
73              if (j > 0) {
74                  escape = messagePattern.charAt(j - 1);
75              }
76              if ((delimStop != DELIM_STOP) || (escape == '\\')) {
77                  // invalid DELIM_START/DELIM_STOP pair or espace character is
78                  // present
79                  return messagePattern;
80              } else {
81                  StringBuffer sbuf = new StringBuffer(len + 20);
82                  sbuf.append(messagePattern.substring(0, j));
83                  sbuf.append(argument);
84                  sbuf.append(messagePattern.substring(j + 2));
85                  return sbuf.toString();
86              }
87          }
88      }
89  
90      /**
91       * /**
92       * Performs a two argument substitution for the 'messagePattern' passed as
93       * parameter.
94       *
95       * <p>For example, <code>MessageFormatter.format("Hi {}. My name is {}.",
96       * "there", "David");</code> will return the string
97       * "Hi there. My name is David.".
98       * </p>
99       * The '{}' pair is called a formatting element. It serves to designate the
100      * location where the arguments need to be inserted within
101      * the message pattern.
102      *
103      * @param messagePattern
104      *     The message pattern which will be parsed and formatted
105      * @param arg1
106      *     The first argument to replace the first formatting element
107      * @param arg2
108      *     The second argument to replace the second formatting element
109      * @return The formatted message
110      */
111     public static String format(final String messagePattern,
112                                 final Object arg1,
113                                 final Object arg2) {
114         int i = 0;
115         int len = messagePattern.length();
116 
117         StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);
118 
119         for (int l = 0; l < 2; l++) {
120             int j = messagePattern.indexOf(DELIM_START, i);
121 
122             if (j == -1 || (j + 1 == len)) {
123                 // no more variables
124                 if (i == 0) { // this is a simple string
125                     return messagePattern;
126                 } else {
127                     // add the tail string which contains no variables
128                     // and return the result.
129                     sbuf.append(messagePattern.substring(i,
130                                     messagePattern.length()));
131                     return sbuf.toString();
132                 }
133             } else {
134                 char delimStop = messagePattern.charAt(j + 1);
135                 if ((delimStop != DELIM_STOP)) {
136                     // invalid DELIM_START/DELIM_STOP pair
137                     sbuf.append(messagePattern.substring(i,
138                             messagePattern.length()));
139                     return sbuf.toString();
140                 }
141                 sbuf.append(messagePattern.substring(i, j));
142                 if (l == 0) {
143                     sbuf.append(arg1);
144                 } else {
145                     sbuf.append(arg2);
146                 }
147                 i = j + 2;
148             }
149         }
150         // append the characters following the second {} pair.
151         sbuf.append(messagePattern.substring(i, messagePattern.length()));
152         return sbuf.toString();
153     }
154 }