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 }