1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.exception.util;
18
19 import java.util.List;
20 import java.util.ArrayList;
21 import java.util.Set;
22 import java.util.Map;
23 import java.io.IOException;
24 import java.io.Serializable;
25 import java.io.ObjectOutputStream;
26 import java.io.ObjectInputStream;
27 import java.util.HashMap;
28 import java.text.MessageFormat;
29 import java.util.Locale;
30
31
32
33
34
35
36
37
38 public class ExceptionContext implements Serializable {
39
40 private static final long serialVersionUID = -6024911025449780478L;
41
42
43
44 private Throwable throwable;
45
46
47
48 private List<Localizable> msgPatterns;
49
50
51
52
53
54 private List<Object[]> msgArguments;
55
56
57
58 private Map<String, Object> context;
59
60
61
62
63 public ExceptionContext(final Throwable throwable) {
64 this.throwable = throwable;
65 msgPatterns = new ArrayList<>();
66 msgArguments = new ArrayList<>();
67 context = new HashMap<>();
68 }
69
70
71
72
73 public Throwable getThrowable() {
74 return throwable;
75 }
76
77
78
79
80
81
82
83
84 public void addMessage(Localizable pattern,
85 Object... arguments) {
86 msgPatterns.add(pattern);
87 msgArguments.add(ArgUtils.flatten(arguments));
88 }
89
90
91
92
93
94
95
96
97
98 public void setValue(String key, Object value) {
99 context.put(key, value);
100 }
101
102
103
104
105
106
107
108 public Object getValue(String key) {
109 return context.get(key);
110 }
111
112
113
114
115
116
117 public Set<String> getKeys() {
118 return context.keySet();
119 }
120
121
122
123
124
125
126 public String getMessage() {
127 return getMessage(Locale.US);
128 }
129
130
131
132
133
134
135 public String getLocalizedMessage() {
136 return getMessage(Locale.getDefault());
137 }
138
139
140
141
142
143
144
145 public String getMessage(final Locale locale) {
146 return buildMessage(locale, ": ");
147 }
148
149
150
151
152
153
154
155
156 public String getMessage(final Locale locale,
157 final String separator) {
158 return buildMessage(locale, separator);
159 }
160
161
162
163
164
165
166
167
168 private String buildMessage(Locale locale,
169 String separator) {
170 final StringBuilder sb = new StringBuilder();
171 int count = 0;
172 final int len = msgPatterns.size();
173 for (int i = 0; i < len; i++) {
174 final Localizable pat = msgPatterns.get(i);
175 final Object[] args = msgArguments.get(i);
176 final MessageFormat fmt = new MessageFormat(pat.getLocalizedString(locale),
177 locale);
178 sb.append(fmt.format(args));
179 if (++count < len) {
180
181 sb.append(separator);
182 }
183 }
184
185 return sb.toString();
186 }
187
188
189
190
191
192
193
194 private void writeObject(ObjectOutputStream out)
195 throws IOException {
196 out.writeObject(throwable);
197 serializeMessages(out);
198 serializeContext(out);
199 }
200
201
202
203
204
205
206
207 private void readObject(ObjectInputStream in)
208 throws IOException,
209 ClassNotFoundException {
210 throwable = (Throwable) in.readObject();
211 deSerializeMessages(in);
212 deSerializeContext(in);
213 }
214
215
216
217
218
219
220
221 private void serializeMessages(ObjectOutputStream out)
222 throws IOException {
223
224 final int len = msgPatterns.size();
225 out.writeInt(len);
226
227 for (int i = 0; i < len; i++) {
228 final Localizable pat = msgPatterns.get(i);
229
230 out.writeObject(pat);
231 final Object[] args = msgArguments.get(i);
232 final int aLen = args.length;
233
234 out.writeInt(aLen);
235 for (int j = 0; j < aLen; j++) {
236 if (args[j] instanceof Serializable) {
237
238 out.writeObject(args[j]);
239 } else {
240
241 out.writeObject(nonSerializableReplacement(args[j]));
242 }
243 }
244 }
245 }
246
247
248
249
250
251
252
253
254 private void deSerializeMessages(ObjectInputStream in)
255 throws IOException,
256 ClassNotFoundException {
257
258 final int len = in.readInt();
259 msgPatterns = new ArrayList<>(len);
260 msgArguments = new ArrayList<>(len);
261
262 for (int i = 0; i < len; i++) {
263
264 final Localizable pat = (Localizable) in.readObject();
265 msgPatterns.add(pat);
266
267 final int aLen = in.readInt();
268 final Object[] args = new Object[aLen];
269 for (int j = 0; j < aLen; j++) {
270
271 args[j] = in.readObject();
272 }
273 msgArguments.add(args);
274 }
275 }
276
277
278
279
280
281
282
283 private void serializeContext(ObjectOutputStream out)
284 throws IOException {
285
286 final int len = context.size();
287 out.writeInt(len);
288 for (Map.Entry<String, Object> entry : context.entrySet()) {
289
290 out.writeObject(entry.getKey());
291 final Object value = entry.getValue();
292 if (value instanceof Serializable) {
293
294 out.writeObject(value);
295 } else {
296
297 out.writeObject(nonSerializableReplacement(value));
298 }
299 }
300 }
301
302
303
304
305
306
307
308
309 private void deSerializeContext(ObjectInputStream in)
310 throws IOException,
311 ClassNotFoundException {
312
313 final int len = in.readInt();
314 context = new HashMap<>();
315 for (int i = 0; i < len; i++) {
316
317 final String key = (String) in.readObject();
318
319 final Object value = in.readObject();
320 context.put(key, value);
321 }
322 }
323
324
325
326
327
328
329
330
331 private static String nonSerializableReplacement(Object obj) {
332 return "[Object could not be serialized: " + obj.getClass().getName() + "]";
333 }
334 }