1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.message;
18
19 import java.util.Arrays;
20
21 import org.apache.logging.log4j.util.StringBuilderFormattable;
22
23
24
25
26
27
28
29
30
31 public class ParameterizedMessage implements Message, StringBuilderFormattable {
32
33
34 private static final int DEFAULT_STRING_BUILDER_SIZE = 255;
35
36
37
38
39 public static final String RECURSION_PREFIX = ParameterFormatter.RECURSION_PREFIX;
40
41
42
43 public static final String RECURSION_SUFFIX = ParameterFormatter.RECURSION_SUFFIX;
44
45
46
47
48 public static final String ERROR_PREFIX = ParameterFormatter.ERROR_PREFIX;
49
50
51
52
53 public static final String ERROR_SEPARATOR = ParameterFormatter.ERROR_SEPARATOR;
54
55
56
57
58 public static final String ERROR_MSG_SEPARATOR = ParameterFormatter.ERROR_MSG_SEPARATOR;
59
60
61
62
63 public static final String ERROR_SUFFIX = ParameterFormatter.ERROR_SUFFIX;
64
65 private static final long serialVersionUID = -665975803997290697L;
66
67 private static final int HASHVAL = 31;
68
69
70 private static ThreadLocal<StringBuilder> threadLocalStringBuilder = new ThreadLocal<>();
71
72 private String messagePattern;
73 private transient Object[] argArray;
74
75 private String formattedMessage;
76 private transient Throwable throwable;
77 private int[] indices;
78 private int usedCount;
79
80
81
82
83
84
85
86
87
88 @Deprecated
89 public ParameterizedMessage(final String messagePattern, final String[] arguments, final Throwable throwable) {
90 this.argArray = arguments;
91 this.throwable = throwable;
92 init(messagePattern);
93 }
94
95
96
97
98
99
100
101
102 public ParameterizedMessage(final String messagePattern, final Object[] arguments, final Throwable throwable) {
103 this.argArray = arguments;
104 this.throwable = throwable;
105 init(messagePattern);
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119 public ParameterizedMessage(final String messagePattern, final Object... arguments) {
120 this.argArray = arguments;
121 init(messagePattern);
122 }
123
124
125
126
127
128
129 public ParameterizedMessage(final String messagePattern, final Object arg) {
130 this(messagePattern, new Object[]{arg});
131 }
132
133
134
135
136
137
138
139 public ParameterizedMessage(final String messagePattern, final Object arg0, final Object arg1) {
140 this(messagePattern, new Object[]{arg0, arg1});
141 }
142
143 private void init(final String messagePattern) {
144 this.messagePattern = messagePattern;
145 final int len = Math.max(1, messagePattern == null ? 0 : messagePattern.length() >> 1);
146 this.indices = new int[len];
147 final int placeholders = ParameterFormatter.countArgumentPlaceholders2(messagePattern, indices);
148 initThrowable(argArray, placeholders);
149 this.usedCount = Math.min(placeholders, argArray == null ? 0 : argArray.length);
150 }
151
152 private void initThrowable(final Object[] params, final int usedParams) {
153 if (params != null) {
154 final int argCount = params.length;
155 if (usedParams < argCount && this.throwable == null && params[argCount - 1] instanceof Throwable) {
156 this.throwable = (Throwable) params[argCount - 1];
157 }
158 }
159 }
160
161
162
163
164
165 @Override
166 public String getFormat() {
167 return messagePattern;
168 }
169
170
171
172
173
174 @Override
175 public Object[] getParameters() {
176 return argArray;
177 }
178
179
180
181
182
183
184
185
186
187
188 @Override
189 public Throwable getThrowable() {
190 return throwable;
191 }
192
193
194
195
196
197 @Override
198 public String getFormattedMessage() {
199 if (formattedMessage == null) {
200 final StringBuilder buffer = getThreadLocalStringBuilder();
201 formatTo(buffer);
202 formattedMessage = buffer.toString();
203 }
204 return formattedMessage;
205 }
206
207 private static StringBuilder getThreadLocalStringBuilder() {
208 StringBuilder buffer = threadLocalStringBuilder.get();
209 if (buffer == null) {
210 buffer = new StringBuilder(DEFAULT_STRING_BUILDER_SIZE);
211 threadLocalStringBuilder.set(buffer);
212 }
213 buffer.setLength(0);
214 return buffer;
215 }
216
217 @Override
218 public void formatTo(final StringBuilder buffer) {
219 if (formattedMessage != null) {
220 buffer.append(formattedMessage);
221 } else {
222 if (indices[0] < 0) {
223 ParameterFormatter.formatMessage(buffer, messagePattern, argArray, usedCount);
224 } else {
225 ParameterFormatter.formatMessage2(buffer, messagePattern, argArray, usedCount, indices);
226 }
227 }
228 }
229
230
231
232
233
234
235
236
237 public static String format(final String messagePattern, final Object[] arguments) {
238 return ParameterFormatter.format(messagePattern, arguments);
239 }
240
241 @Override
242 public boolean equals(final Object o) {
243 if (this == o) {
244 return true;
245 }
246 if (o == null || getClass() != o.getClass()) {
247 return false;
248 }
249
250 final ParameterizedMessage that = (ParameterizedMessage) o;
251
252 if (messagePattern != null ? !messagePattern.equals(that.messagePattern) : that.messagePattern != null) {
253 return false;
254 }
255 if (!Arrays.equals(this.argArray, that.argArray)) {
256 return false;
257 }
258
259
260 return true;
261 }
262
263 @Override
264 public int hashCode() {
265 int result = messagePattern != null ? messagePattern.hashCode() : 0;
266 result = HASHVAL * result + (argArray != null ? Arrays.hashCode(argArray) : 0);
267 return result;
268 }
269
270
271
272
273
274
275
276 public static int countArgumentPlaceholders(final String messagePattern) {
277 return ParameterFormatter.countArgumentPlaceholders(messagePattern);
278 }
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298 public static String deepToString(final Object o) {
299 return ParameterFormatter.deepToString(o);
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 public static String identityToString(final Object obj) {
323 return ParameterFormatter.identityToString(obj);
324 }
325
326 @Override
327 public String toString() {
328 return "ParameterizedMessage[messagePattern=" + messagePattern + ", stringArgs=" +
329 Arrays.toString(argArray) + ", throwable=" + throwable + ']';
330 }
331 }