1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.slf4j.helpers;
26
27 import java.util.HashMap;
28 import java.util.Map;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 final public class MessageFormatter {
88 static final char DELIM_START = '{';
89 static final char DELIM_STOP = '}';
90 static final String DELIM_STR = "{}";
91 private static final char ESCAPE_CHAR = '\\';
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 final public static String format(String messagePattern, Object arg) {
114 return arrayFormat(messagePattern, new Object[] { arg });
115 }
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 final public static String format(final String messagePattern, Object arg1,
141 Object arg2) {
142 return arrayFormat(messagePattern, new Object[] { arg1, arg2 });
143 }
144
145
146
147
148
149
150
151
152
153
154
155
156
157 final public static String arrayFormat(final String messagePattern,
158 final Object[] argArray) {
159 if (messagePattern == null) {
160 return null;
161 }
162 if (argArray == null) {
163 return messagePattern;
164 }
165 int i = 0;
166 int j;
167 StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);
168
169 for (int L = 0; L < argArray.length; L++) {
170
171 j = messagePattern.indexOf(DELIM_STR, i);
172
173 if (j == -1) {
174
175 if (i == 0) {
176 return messagePattern;
177 } else {
178
179 sbuf.append(messagePattern.substring(i, messagePattern.length()));
180 return sbuf.toString();
181 }
182 } else {
183 if (isEscapedDelimeter(messagePattern, j)) {
184 if (!isDoubleEscaped(messagePattern, j)) {
185 L--;
186 sbuf.append(messagePattern.substring(i, j - 1));
187 sbuf.append(DELIM_START);
188 i = j + 1;
189 } else {
190
191
192
193 sbuf.append(messagePattern.substring(i, j - 1));
194 deeplyAppendParameter(sbuf, argArray[L], new HashMap());
195 i = j + 2;
196 }
197 } else {
198
199 sbuf.append(messagePattern.substring(i, j));
200 deeplyAppendParameter(sbuf, argArray[L], new HashMap());
201 i = j + 2;
202 }
203 }
204 }
205
206 sbuf.append(messagePattern.substring(i, messagePattern.length()));
207 return sbuf.toString();
208 }
209
210 final static boolean isEscapedDelimeter(String messagePattern,
211 int delimeterStartIndex) {
212
213 if (delimeterStartIndex == 0) {
214 return false;
215 }
216 char potentialEscape = messagePattern.charAt(delimeterStartIndex - 1);
217 if (potentialEscape == ESCAPE_CHAR) {
218 return true;
219 } else {
220 return false;
221 }
222 }
223
224 final static boolean isDoubleEscaped(String messagePattern,
225 int delimeterStartIndex) {
226 if (delimeterStartIndex >= 2
227 && messagePattern.charAt(delimeterStartIndex - 2) == ESCAPE_CHAR) {
228 return true;
229 } else {
230 return false;
231 }
232 }
233
234
235 private static void deeplyAppendParameter(StringBuffer sbuf, Object o,
236 Map seenMap) {
237 if (o == null) {
238 sbuf.append("null");
239 return;
240 }
241 if (!o.getClass().isArray()) {
242 safeObjectAppend(sbuf, o);
243 } else {
244
245
246 if (o instanceof boolean[]) {
247 booleanArrayAppend(sbuf, (boolean[]) o);
248 } else if (o instanceof byte[]) {
249 byteArrayAppend(sbuf, (byte[]) o);
250 } else if (o instanceof char[]) {
251 charArrayAppend(sbuf, (char[]) o);
252 } else if (o instanceof short[]) {
253 shortArrayAppend(sbuf, (short[]) o);
254 } else if (o instanceof int[]) {
255 intArrayAppend(sbuf, (int[]) o);
256 } else if (o instanceof long[]) {
257 longArrayAppend(sbuf, (long[]) o);
258 } else if (o instanceof float[]) {
259 floatArrayAppend(sbuf, (float[]) o);
260 } else if (o instanceof double[]) {
261 doubleArrayAppend(sbuf, (double[]) o);
262 } else {
263 objectArrayAppend(sbuf, (Object[]) o, seenMap);
264 }
265 }
266 }
267
268 private static void safeObjectAppend(StringBuffer sbuf, Object o) {
269 try {
270 String oAsString = o.toString();
271 sbuf.append(oAsString);
272 } catch( Throwable t) {
273 System.err.println("SLF4J: Failed toString() invocation on an object of type ["+o.getClass().getName()+"]");
274 t.printStackTrace();
275 sbuf.append("[FAILED toString()]");
276 }
277
278 }
279
280 private static void objectArrayAppend(StringBuffer sbuf, Object[] a,
281 Map seenMap) {
282 sbuf.append('[');
283 if (!seenMap.containsKey(a)) {
284 seenMap.put(a, null);
285 final int len = a.length;
286 for (int i = 0; i < len; i++) {
287 deeplyAppendParameter(sbuf, a[i], seenMap);
288 if (i != len - 1)
289 sbuf.append(", ");
290 }
291
292 seenMap.remove(a);
293 } else {
294 sbuf.append("...");
295 }
296 sbuf.append(']');
297 }
298
299 private static void booleanArrayAppend(StringBuffer sbuf, boolean[] a) {
300 sbuf.append('[');
301 final int len = a.length;
302 for (int i = 0; i < len; i++) {
303 sbuf.append(a[i]);
304 if (i != len - 1)
305 sbuf.append(", ");
306 }
307 sbuf.append(']');
308 }
309
310 private static void byteArrayAppend(StringBuffer sbuf, byte[] a) {
311 sbuf.append('[');
312 final int len = a.length;
313 for (int i = 0; i < len; i++) {
314 sbuf.append(a[i]);
315 if (i != len - 1)
316 sbuf.append(", ");
317 }
318 sbuf.append(']');
319 }
320
321 private static void charArrayAppend(StringBuffer sbuf, char[] a) {
322 sbuf.append('[');
323 final int len = a.length;
324 for (int i = 0; i < len; i++) {
325 sbuf.append(a[i]);
326 if (i != len - 1)
327 sbuf.append(", ");
328 }
329 sbuf.append(']');
330 }
331
332 private static void shortArrayAppend(StringBuffer sbuf, short[] a) {
333 sbuf.append('[');
334 final int len = a.length;
335 for (int i = 0; i < len; i++) {
336 sbuf.append(a[i]);
337 if (i != len - 1)
338 sbuf.append(", ");
339 }
340 sbuf.append(']');
341 }
342
343 private static void intArrayAppend(StringBuffer sbuf, int[] a) {
344 sbuf.append('[');
345 final int len = a.length;
346 for (int i = 0; i < len; i++) {
347 sbuf.append(a[i]);
348 if (i != len - 1)
349 sbuf.append(", ");
350 }
351 sbuf.append(']');
352 }
353
354 private static void longArrayAppend(StringBuffer sbuf, long[] a) {
355 sbuf.append('[');
356 final int len = a.length;
357 for (int i = 0; i < len; i++) {
358 sbuf.append(a[i]);
359 if (i != len - 1)
360 sbuf.append(", ");
361 }
362 sbuf.append(']');
363 }
364
365 private static void floatArrayAppend(StringBuffer sbuf, float[] a) {
366 sbuf.append('[');
367 final int len = a.length;
368 for (int i = 0; i < len; i++) {
369 sbuf.append(a[i]);
370 if (i != len - 1)
371 sbuf.append(", ");
372 }
373 sbuf.append(']');
374 }
375
376 private static void doubleArrayAppend(StringBuffer sbuf, double[] a) {
377 sbuf.append('[');
378 final int len = a.length;
379 for (int i = 0; i < len; i++) {
380 sbuf.append(a[i]);
381 if (i != len - 1)
382 sbuf.append(", ");
383 }
384 sbuf.append(']');
385 }
386 }