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.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.util.Locale;
23 import java.util.MissingResourceException;
24 import java.util.ResourceBundle;
25
26 import org.apache.logging.log4j.status.StatusLogger;
27
28
29
30
31
32
33
34
35
36
37 public class LocalizedMessage implements Message, LoggerNameAwareMessage {
38 private static final long serialVersionUID = 3893703791567290742L;
39
40 private String baseName;
41
42
43 private transient ResourceBundle resourceBundle;
44
45 private final Locale locale;
46
47 private transient StatusLogger logger = StatusLogger.getLogger();
48
49 private String loggerName;
50 private String key;
51 private String[] stringArgs;
52 private transient Object[] argArray;
53 private String formattedMessage;
54 private transient Throwable throwable;
55
56
57
58
59
60
61
62 public LocalizedMessage(final String messagePattern, final Object[] arguments) {
63 this((ResourceBundle) null, (Locale) null, messagePattern, arguments);
64 }
65
66 public LocalizedMessage(final String baseName, final String key, final Object[] arguments) {
67 this(baseName, (Locale) null, key, arguments);
68 }
69
70 public LocalizedMessage(final ResourceBundle bundle, final String key, final Object[] arguments) {
71 this(bundle, (Locale) null, key, arguments);
72 }
73
74 public LocalizedMessage(final String baseName, final Locale locale, final String key, final Object[] arguments) {
75 this.key = key;
76 this.argArray = arguments;
77 this.throwable = null;
78 this.baseName = baseName;
79 this.resourceBundle = null;
80 this.locale = locale;
81 }
82
83 public LocalizedMessage(final ResourceBundle bundle, final Locale locale, final String key,
84 final Object[] arguments) {
85 this.key = key;
86 this.argArray = arguments;
87 this.throwable = null;
88 this.baseName = null;
89 this.resourceBundle = bundle;
90 this.locale = locale;
91 }
92
93 public LocalizedMessage(final Locale locale, final String key, final Object[] arguments) {
94 this((ResourceBundle) null, locale, key, arguments);
95 }
96
97 public LocalizedMessage(final String messagePattern, final Object arg) {
98 this((ResourceBundle) null, (Locale) null, messagePattern, new Object[] {arg});
99 }
100
101 public LocalizedMessage(final String baseName, final String key, final Object arg) {
102 this(baseName, (Locale) null, key, new Object[] {arg});
103 }
104
105
106
107
108 public LocalizedMessage(final ResourceBundle bundle, final String key) {
109 this(bundle, (Locale) null, key, new Object[] {});
110 }
111
112 public LocalizedMessage(final ResourceBundle bundle, final String key, final Object arg) {
113 this(bundle, (Locale) null, key, new Object[] {arg});
114 }
115
116 public LocalizedMessage(final String baseName, final Locale locale, final String key, final Object arg) {
117 this(baseName, locale, key, new Object[] {arg});
118 }
119
120 public LocalizedMessage(final ResourceBundle bundle, final Locale locale, final String key, final Object arg) {
121 this(bundle, locale, key, new Object[] {arg});
122 }
123
124 public LocalizedMessage(final Locale locale, final String key, final Object arg) {
125 this((ResourceBundle) null, locale, key, new Object[] {arg});
126 }
127
128 public LocalizedMessage(final String messagePattern, final Object arg1, final Object arg2) {
129 this((ResourceBundle) null, (Locale) null, messagePattern, new Object[] {arg1, arg2});
130 }
131
132 public LocalizedMessage(final String baseName, final String key, final Object arg1, final Object arg2) {
133 this(baseName, (Locale) null, key, new Object[] {arg1, arg2});
134 }
135
136 public LocalizedMessage(final ResourceBundle bundle, final String key, final Object arg1, final Object arg2) {
137 this(bundle, (Locale) null, key, new Object[] {arg1, arg2});
138 }
139
140 public LocalizedMessage(final String baseName, final Locale locale, final String key, final Object arg1,
141 final Object arg2) {
142 this(baseName, locale, key, new Object[] {arg1, arg2});
143 }
144
145 public LocalizedMessage(final ResourceBundle bundle, final Locale locale, final String key, final Object arg1,
146 final Object arg2) {
147 this(bundle, locale, key, new Object[] {arg1, arg2});
148 }
149
150 public LocalizedMessage(final Locale locale, final String key, final Object arg1, final Object arg2) {
151 this((ResourceBundle) null, locale, key, new Object[] {arg1, arg2});
152 }
153
154
155
156
157
158
159 @Override
160 public void setLoggerName(final String name) {
161 this.loggerName = name;
162 }
163
164
165
166
167
168
169 @Override
170 public String getLoggerName() {
171 return this.loggerName;
172 }
173
174
175
176
177
178
179 @Override
180 public String getFormattedMessage() {
181 if (formattedMessage != null) {
182 return formattedMessage;
183 }
184 ResourceBundle bundle = this.resourceBundle;
185 if (bundle == null) {
186 if (baseName != null) {
187 bundle = getResourceBundle(baseName, locale, false);
188 } else {
189 bundle = getResourceBundle(loggerName, locale, true);
190 }
191 }
192 final String myKey = getFormat();
193 final String msgPattern = (bundle == null || !bundle.containsKey(myKey)) ? myKey : bundle.getString(myKey);
194 final Object[] array = argArray == null ? stringArgs : argArray;
195 final FormattedMessage msg = new FormattedMessage(msgPattern, array);
196 formattedMessage = msg.getFormattedMessage();
197 throwable = msg.getThrowable();
198 return formattedMessage;
199 }
200
201 @Override
202 public String getFormat() {
203 return key;
204 }
205
206 @Override
207 public Object[] getParameters() {
208 if (argArray != null) {
209 return argArray;
210 }
211 return stringArgs;
212 }
213
214 @Override
215 public Throwable getThrowable() {
216 return throwable;
217 }
218
219
220
221
222
223
224
225
226
227
228 protected ResourceBundle getResourceBundle(final String rbBaseName, final Locale resourceBundleLocale,
229 final boolean loop) {
230 ResourceBundle rb = null;
231
232 if (rbBaseName == null) {
233 return null;
234 }
235 try {
236 if (resourceBundleLocale != null) {
237 rb = ResourceBundle.getBundle(rbBaseName, resourceBundleLocale);
238 } else {
239 rb = ResourceBundle.getBundle(rbBaseName);
240 }
241 } catch (final MissingResourceException ex) {
242 if (!loop) {
243 logger.debug("Unable to locate ResourceBundle " + rbBaseName);
244 return null;
245 }
246 }
247
248 String substr = rbBaseName;
249 int i;
250 while (rb == null && (i = substr.lastIndexOf('.')) > 0) {
251 substr = substr.substring(0, i);
252 try {
253 if (resourceBundleLocale != null) {
254 rb = ResourceBundle.getBundle(substr, resourceBundleLocale);
255 } else {
256 rb = ResourceBundle.getBundle(substr);
257 }
258 } catch (final MissingResourceException ex) {
259 logger.debug("Unable to locate ResourceBundle " + substr);
260 }
261 }
262 return rb;
263 }
264
265 @Override
266 public String toString() {
267 return getFormattedMessage();
268 }
269
270 private void writeObject(final ObjectOutputStream out) throws IOException {
271 out.defaultWriteObject();
272 getFormattedMessage();
273 out.writeUTF(formattedMessage);
274 out.writeUTF(key);
275 out.writeUTF(baseName);
276 out.writeInt(argArray.length);
277 stringArgs = new String[argArray.length];
278 int i = 0;
279 for (final Object obj : argArray) {
280 stringArgs[i] = obj.toString();
281 ++i;
282 }
283 out.writeObject(stringArgs);
284 }
285
286 private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
287 in.defaultReadObject();
288 formattedMessage = in.readUTF();
289 key = in.readUTF();
290 baseName = in.readUTF();
291 in.readInt();
292 stringArgs = (String[]) in.readObject();
293 logger = StatusLogger.getLogger();
294 resourceBundle = null;
295 argArray = null;
296 }
297 }