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.Map;
20
21 import org.apache.logging.log4j.util.EnglishEnums;
22
23
24
25
26 public class StructuredDataMessage extends MapMessage {
27
28 private static final long serialVersionUID = 1703221292892071920L;
29 private static final int MAX_LENGTH = 32;
30 private static final int HASHVAL = 31;
31
32 private StructuredDataId id;
33
34 private String message;
35
36 private String type;
37
38
39
40
41 public enum Format {
42
43 XML,
44
45 FULL
46 }
47
48
49
50
51
52
53
54 public StructuredDataMessage(final String id, final String msg, final String type) {
55 this.id = new StructuredDataId(id, null, null);
56 this.message = msg;
57 this.type = type;
58 }
59
60
61
62
63
64
65
66 public StructuredDataMessage(final String id, final String msg, final String type,
67 final Map<String, String> data) {
68 super(data);
69 this.id = new StructuredDataId(id, null, null);
70 this.message = msg;
71 this.type = type;
72 }
73
74
75
76
77
78
79
80 public StructuredDataMessage(final StructuredDataId id, final String msg, final String type) {
81 this.id = id;
82 this.message = msg;
83 this.type = type;
84 }
85
86
87
88
89
90
91
92
93 public StructuredDataMessage(final StructuredDataId id, final String msg, final String type,
94 final Map<String, String> data) {
95 super(data);
96 this.id = id;
97 this.message = msg;
98 this.type = type;
99 }
100
101
102
103
104
105
106
107 private StructuredDataMessage(final StructuredDataMessage msg, final Map<String, String> map) {
108 super(map);
109 this.id = msg.id;
110 this.message = msg.message;
111 this.type = msg.type;
112 }
113
114
115
116
117
118 protected StructuredDataMessage() {
119
120 }
121
122
123
124
125
126 @Override
127 public String[] getFormats() {
128 final String[] formats = new String[Format.values().length];
129 int i = 0;
130 for (final Format format : Format.values()) {
131 formats[i++] = format.name();
132 }
133 return formats;
134 }
135
136
137
138
139
140 public StructuredDataId getId() {
141 return id;
142 }
143
144
145
146
147
148 protected void setId(final String id) {
149 this.id = new StructuredDataId(id, null, null);
150 }
151
152
153
154
155
156 protected void setId(final StructuredDataId id) {
157 this.id = id;
158 }
159
160
161
162
163
164 public String getType() {
165 return type;
166 }
167
168 protected void setType(final String type) {
169 if (type.length() > MAX_LENGTH) {
170 throw new IllegalArgumentException("Structured data type exceeds maximum length of 32 characters: " + type);
171 }
172 this.type = type;
173 }
174
175
176
177
178 @Override
179 public String getFormat() {
180 return message;
181 }
182
183 protected void setMessageFormat(final String msg) {
184 this.message = msg;
185 }
186
187
188 @Override
189 protected void validate(final String key, final String value) {
190 if (key.length() > MAX_LENGTH) {
191 throw new IllegalArgumentException("Structured data keys are limited to 32 characters. key: " + key +
192 " value: " + value);
193 }
194 }
195
196
197
198
199
200
201 @Override
202 public String asString() {
203 return asString(Format.FULL, null);
204 }
205
206
207
208
209
210
211
212
213 @Override
214 public String asString(final String format) {
215 try {
216 return asString(EnglishEnums.valueOf(Format.class, format), null);
217 } catch (final IllegalArgumentException ex) {
218 return asString();
219 }
220 }
221
222
223
224
225
226
227
228
229
230
231 public final String asString(final Format format, final StructuredDataId structuredDataId) {
232 final StringBuilder sb = new StringBuilder();
233 final boolean full = Format.FULL.equals(format);
234 if (full) {
235 final String type = getType();
236 if (type == null) {
237 return sb.toString();
238 }
239 sb.append(getType()).append(" ");
240 }
241 StructuredDataId id = getId();
242 if (id != null) {
243 id = id.makeId(structuredDataId);
244 } else {
245 id = structuredDataId;
246 }
247 if (id == null || id.getName() == null) {
248 return sb.toString();
249 }
250 sb.append("[");
251 sb.append(id);
252 sb.append(" ");
253 appendMap(sb);
254 sb.append("]");
255 if (full) {
256 final String msg = getFormat();
257 if (msg != null) {
258 sb.append(" ").append(msg);
259 }
260 }
261 return sb.toString();
262 }
263
264
265
266
267
268 @Override
269 public String getFormattedMessage() {
270 return asString(Format.FULL, null);
271 }
272
273
274
275
276
277
278
279
280
281
282 @Override
283 public String getFormattedMessage(final String[] formats) {
284 if (formats != null && formats.length > 0) {
285 for (final String format : formats) {
286 if (Format.XML.name().equalsIgnoreCase(format)) {
287 return asXML();
288 } else if (Format.FULL.name().equalsIgnoreCase(format)) {
289 return asString(Format.FULL, null);
290 }
291 }
292 return asString(null, null);
293 } else {
294 return asString(Format.FULL, null);
295 }
296 }
297
298 private String asXML() {
299 final StringBuilder sb = new StringBuilder();
300 final StructuredDataId id = getId();
301 if (id == null || id.getName() == null || type == null) {
302 return sb.toString();
303 }
304 sb.append("<StructuredData>\n");
305 sb.append("<type>").append(type).append("</type>\n");
306 sb.append("<id>").append(id).append("</id>\n");
307 super.asXML(sb);
308 sb.append("</StructuredData>\n");
309 return sb.toString();
310 }
311
312 @Override
313 public String toString() {
314 return asString(null, null);
315 }
316
317
318 @Override
319 public MapMessage newInstance(final Map<String, String> map) {
320 return new StructuredDataMessage(this, map);
321 }
322
323 @Override
324 public boolean equals(final Object o) {
325 if (this == o) {
326 return true;
327 }
328 if (o == null || getClass() != o.getClass()) {
329 return false;
330 }
331
332 final StructuredDataMessage that = (StructuredDataMessage) o;
333
334 if (!super.equals(o)) {
335 return false;
336 }
337 if (type != null ? !type.equals(that.type) : that.type != null) {
338 return false;
339 }
340 if (id != null ? !id.equals(that.id) : that.id != null) {
341 return false;
342 }
343 if (message != null ? !message.equals(that.message) : that.message != null) {
344 return false;
345 }
346
347 return true;
348 }
349
350 @Override
351 public int hashCode() {
352 int result = super.hashCode();
353 result = HASHVAL * result + (type != null ? type.hashCode() : 0);
354 result = HASHVAL * result + (id != null ? id.hashCode() : 0);
355 result = HASHVAL * result + (message != null ? message.hashCode() : 0);
356 return result;
357 }
358 }