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<String, String>();
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<String, String>(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 public void put(final String key, final String value) {
118 if (value == null) {
119 throw new IllegalArgumentException("No value provided for key " + key);
120 }
121 validate(key, value);
122 data.put(key, value);
123 }
124
125 protected void validate(final String key, final String value) {
126
127 }
128
129
130
131
132
133 public void putAll(final Map<String, String> map) {
134 data.putAll(map);
135 }
136
137
138
139
140
141
142 public String get(final String key) {
143 return data.get(key);
144 }
145
146
147
148
149
150
151 public String remove(final String key) {
152 return data.remove(key);
153 }
154
155
156
157
158
159
160 public String asString() {
161 return asString((MapFormat) null);
162 }
163
164 public String asString(final String format) {
165 try {
166 return asString(EnglishEnums.valueOf(MapFormat.class, format));
167 } catch (final IllegalArgumentException ex) {
168 return asString();
169 }
170 }
171
172
173
174
175
176
177 private String asString(final MapFormat format) {
178 final StringBuilder sb = new StringBuilder();
179 if (format == null) {
180 appendMap(sb);
181 } else {
182 switch (format) {
183 case XML : {
184 asXml(sb);
185 break;
186 }
187 case JSON : {
188 asJson(sb);
189 break;
190 }
191 case JAVA : {
192 asJava(sb);
193 break;
194 }
195 default : {
196 appendMap(sb);
197 }
198 }
199 }
200 return sb.toString();
201 }
202
203 public void asXml(final StringBuilder sb) {
204 sb.append("<Map>\n");
205 for (final Map.Entry<String, String> entry : data.entrySet()) {
206 sb.append(" <Entry key=\"").append(entry.getKey()).append("\">").append(entry.getValue())
207 .append("</Entry>\n");
208 }
209 sb.append("</Map>");
210 }
211
212
213
214
215
216 @Override
217 public String getFormattedMessage() {
218 return asString();
219 }
220
221
222
223
224
225
226
227
228
229 @Override
230 public String getFormattedMessage(final String[] formats) {
231 if (formats == null || formats.length == 0) {
232 return asString();
233 }
234 for (final String format : formats) {
235 for (final MapFormat mapFormat : MapFormat.values()) {
236 if (mapFormat.name().equalsIgnoreCase(format)) {
237 return asString(mapFormat);
238 }
239 }
240 }
241 return asString();
242
243 }
244
245 protected void appendMap(final StringBuilder sb) {
246 boolean first = true;
247 for (final Map.Entry<String, String> entry : data.entrySet()) {
248 if (!first) {
249 sb.append(' ');
250 }
251 first = false;
252 StringBuilders.appendKeyDqValue(sb, entry);
253 }
254 }
255
256 protected void asJson(final StringBuilder sb) {
257 boolean first = true;
258 sb.append('{');
259 for (final Map.Entry<String, String> entry : data.entrySet()) {
260 if (!first) {
261 sb.append(", ");
262 }
263 first = false;
264 StringBuilders.appendDqValue(sb, entry.getKey()).append(':');
265 StringBuilders.appendDqValue(sb, entry.getValue());
266 }
267 sb.append('}');
268 }
269
270
271 protected void asJava(final StringBuilder sb) {
272 boolean first = true;
273 sb.append('{');
274 for (final Map.Entry<String, String> entry : data.entrySet()) {
275 if (!first) {
276 sb.append(", ");
277 }
278 first = false;
279 StringBuilders.appendKeyDqValue(sb, entry);
280 }
281 sb.append('}');
282 }
283
284 public MapMessage newInstance(final Map<String, String> map) {
285 return new MapMessage(map);
286 }
287
288 @Override
289 public String toString() {
290 return asString();
291 }
292
293 @Override
294 public boolean equals(final Object o) {
295 if (this == o) {
296 return true;
297 }
298 if (o == null || this.getClass() != o.getClass()) {
299 return false;
300 }
301
302 final MapMessage that = (MapMessage) o;
303
304 return this.data.equals(that.data);
305 }
306
307 @Override
308 public int hashCode() {
309 return data.hashCode();
310 }
311
312
313
314
315
316
317 @Override
318 public Throwable getThrowable() {
319 return null;
320 }
321 }