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.Collections;
20 import java.util.Map;
21 import java.util.SortedMap;
22 import java.util.TreeMap;
23
24 import org.apache.logging.log4j.util.EnglishEnums;
25 import org.apache.logging.log4j.util.StringBuilders;
26 import org.apache.logging.log4j.util.Strings;
27
28
29
30
31
32
33
34
35
36 public class MapMessage implements MultiformatMessage {
37
38
39
40
41 public enum MapFormat {
42
43 XML,
44
45 JSON,
46
47 JAVA
48 }
49
50 private static final long serialVersionUID = -5031471831131487120L;
51
52 private final SortedMap<String, String> data;
53
54
55
56
57 public MapMessage() {
58 data = new TreeMap<>();
59 }
60
61
62
63
64
65 public MapMessage(final Map<String, String> map) {
66 this.data = map instanceof SortedMap ? (SortedMap<String, String>) map : new TreeMap<>(map);
67 }
68
69 @Override
70 public String[] getFormats() {
71 final String[] formats = new String[MapFormat.values().length];
72 int i = 0;
73 for (final MapFormat format : MapFormat.values()) {
74 formats[i++] = format.name();
75 }
76 return formats;
77 }
78
79
80
81
82
83 @Override
84 public Object[] getParameters() {
85 return data.values().toArray();
86 }
87
88
89
90
91
92 @Override
93 public String getFormat() {
94 return Strings.EMPTY;
95 }
96
97
98
99
100
101 public Map<String, String> getData() {
102 return Collections.unmodifiableMap(data);
103 }
104
105
106
107
108 public void clear() {
109 data.clear();
110 }
111
112
113
114
115
116
117
118 public MapMessage with(final String key, final String value) {
119 put(key, value);
120 return this;
121 }
122
123
124
125
126
127
128 public void put(final String key, final String value) {
129 if (value == null) {
130 throw new IllegalArgumentException("No value provided for key " + key);
131 }
132 validate(key, value);
133 data.put(key, value);
134 }
135
136 protected void validate(final String key, final String value) {
137
138 }
139
140
141
142
143
144 public void putAll(final Map<String, String> map) {
145 data.putAll(map);
146 }
147
148
149
150
151
152
153 public String get(final String key) {
154 return data.get(key);
155 }
156
157
158
159
160
161
162 public String remove(final String key) {
163 return data.remove(key);
164 }
165
166
167
168
169
170
171 public String asString() {
172 return asString((MapFormat) null);
173 }
174
175 public String asString(final String format) {
176 try {
177 return asString(EnglishEnums.valueOf(MapFormat.class, format));
178 } catch (final IllegalArgumentException ex) {
179 return asString();
180 }
181 }
182
183
184
185
186
187
188 private String asString(final MapFormat format) {
189 final StringBuilder sb = new StringBuilder();
190 if (format == null) {
191 appendMap(sb);
192 } else {
193 switch (format) {
194 case XML : {
195 asXml(sb);
196 break;
197 }
198 case JSON : {
199 asJson(sb);
200 break;
201 }
202 case JAVA : {
203 asJava(sb);
204 break;
205 }
206 default : {
207 appendMap(sb);
208 }
209 }
210 }
211 return sb.toString();
212 }
213
214 public void asXml(final StringBuilder sb) {
215 sb.append("<Map>\n");
216 for (final Map.Entry<String, String> entry : data.entrySet()) {
217 sb.append(" <Entry key=\"").append(entry.getKey()).append("\">").append(entry.getValue())
218 .append("</Entry>\n");
219 }
220 sb.append("</Map>");
221 }
222
223
224
225
226
227 @Override
228 public String getFormattedMessage() {
229 return asString();
230 }
231
232
233
234
235
236
237
238
239
240 @Override
241 public String getFormattedMessage(final String[] formats) {
242 if (formats == null || formats.length == 0) {
243 return asString();
244 }
245 for (final String format : formats) {
246 for (final MapFormat mapFormat : MapFormat.values()) {
247 if (mapFormat.name().equalsIgnoreCase(format)) {
248 return asString(mapFormat);
249 }
250 }
251 }
252 return asString();
253
254 }
255
256 protected void appendMap(final StringBuilder sb) {
257 boolean first = true;
258 for (final Map.Entry<String, String> entry : data.entrySet()) {
259 if (!first) {
260 sb.append(' ');
261 }
262 first = false;
263 StringBuilders.appendKeyDqValue(sb, entry);
264 }
265 }
266
267 protected void asJson(final StringBuilder sb) {
268 boolean first = true;
269 sb.append('{');
270 for (final Map.Entry<String, String> entry : data.entrySet()) {
271 if (!first) {
272 sb.append(", ");
273 }
274 first = false;
275 StringBuilders.appendDqValue(sb, entry.getKey()).append(':');
276 StringBuilders.appendDqValue(sb, entry.getValue());
277 }
278 sb.append('}');
279 }
280
281
282 protected void asJava(final StringBuilder sb) {
283 boolean first = true;
284 sb.append('{');
285 for (final Map.Entry<String, String> entry : data.entrySet()) {
286 if (!first) {
287 sb.append(", ");
288 }
289 first = false;
290 StringBuilders.appendKeyDqValue(sb, entry);
291 }
292 sb.append('}');
293 }
294
295 public MapMessage newInstance(final Map<String, String> map) {
296 return new MapMessage(map);
297 }
298
299 @Override
300 public String toString() {
301 return asString();
302 }
303
304 @Override
305 public boolean equals(final Object o) {
306 if (this == o) {
307 return true;
308 }
309 if (o == null || this.getClass() != o.getClass()) {
310 return false;
311 }
312
313 final MapMessage that = (MapMessage) o;
314
315 return this.data.equals(that.data);
316 }
317
318 @Override
319 public int hashCode() {
320 return data.hashCode();
321 }
322
323
324
325
326
327
328 @Override
329 public Throwable getThrowable() {
330 return null;
331 }
332 }