1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.xml;
19
20 import org.apache.log4j.Layout;
21 import org.apache.log4j.LayoutTest;
22 import org.apache.log4j.Level;
23 import org.apache.log4j.Logger;
24 import org.apache.log4j.NDC;
25 import org.apache.log4j.MDC;
26 import org.apache.log4j.spi.LoggingEvent;
27
28 import org.w3c.dom.Document;
29 import org.w3c.dom.Element;
30 import org.w3c.dom.Node;
31 import org.w3c.dom.NodeList;
32
33 import org.xml.sax.InputSource;
34
35 import java.io.Reader;
36 import java.io.StringReader;
37 import java.util.Hashtable;
38
39 import javax.xml.parsers.DocumentBuilder;
40 import javax.xml.parsers.DocumentBuilderFactory;
41
42
43
44
45
46
47
48 public class XMLLayoutTest extends LayoutTest {
49
50
51
52
53
54 public XMLLayoutTest(final String testName) {
55 super(testName, "text/plain", false, null, null);
56 }
57
58
59
60
61 public void setUp() {
62 NDC.clear();
63 if (MDC.getContext() != null) {
64 MDC.getContext().clear();
65 }
66 }
67
68
69
70
71 public void tearDown() {
72 setUp();
73 }
74
75
76
77
78 protected Layout createLayout() {
79 return new XMLLayout();
80 }
81
82
83
84
85
86
87
88 private Element parse(final String source) throws Exception {
89 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
90 factory.setNamespaceAware(false);
91 factory.setCoalescing(true);
92
93 DocumentBuilder builder = factory.newDocumentBuilder();
94 Reader reader = new StringReader(source);
95 Document doc = builder.parse(new InputSource(reader));
96
97 return doc.getDocumentElement();
98 }
99
100
101
102
103
104
105 private void checkEventElement(
106 final Element element, final LoggingEvent event) {
107 assertEquals("log4j:event", element.getTagName());
108 assertEquals(
109 event.getLoggerName(), element.getAttribute("logger"));
110 assertEquals(
111 Long.toString(event.timeStamp), element.getAttribute("timestamp"));
112 assertEquals(event.getLevel().toString(), element.getAttribute("level"));
113 assertEquals(event.getThreadName(), element.getAttribute("thread"));
114 }
115
116
117
118
119
120
121 private void checkMessageElement(
122 final Element element, final String message) {
123 assertEquals("log4j:message", element.getTagName());
124
125 Node messageNode = element.getFirstChild();
126 assertNotNull(messageNode);
127 assertEquals(Node.TEXT_NODE, messageNode.getNodeType());
128 assertEquals(message, messageNode.getNodeValue());
129 assertNull(messageNode.getNextSibling());
130 }
131
132
133
134
135
136
137 private void checkNDCElement(final Element element, final String message) {
138 assertEquals("log4j:NDC", element.getTagName());
139
140 Node messageNode = element.getFirstChild();
141 assertNotNull(messageNode);
142 assertEquals(Node.TEXT_NODE, messageNode.getNodeType());
143 assertEquals(message, messageNode.getNodeValue());
144 assertNull(messageNode.getNextSibling());
145 }
146
147
148
149
150
151
152 private void checkThrowableElement(
153 final Element element, final Exception ex) {
154 assertEquals("log4j:throwable", element.getTagName());
155
156 Node messageNode = element.getFirstChild();
157 assertNotNull(messageNode);
158 assertEquals(Node.TEXT_NODE, messageNode.getNodeType());
159
160 String msg = ex.toString();
161 assertEquals(msg, messageNode.getNodeValue().substring(0, msg.length()));
162 assertNull(messageNode.getNextSibling());
163 }
164
165
166
167
168
169
170
171 private void checkPropertiesElement(
172 final Element element, final String key, final String value) {
173 assertEquals("log4j:properties", element.getTagName());
174
175 int childNodeCount = 0;
176 for(Node child = element.getFirstChild();
177 child != null;
178 child = child.getNextSibling()) {
179 if (child.getNodeType() == Node.ELEMENT_NODE) {
180 assertEquals("log4j:data", child.getNodeName());
181 Element childElement = (Element) child;
182 assertEquals(key, childElement.getAttribute("name"));
183 assertEquals(value, childElement.getAttribute("value"));
184 childNodeCount++;
185 }
186 }
187 assertEquals(1, childNodeCount);
188 }
189
190
191
192
193
194 public void testFormat() throws Exception {
195 Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest");
196 LoggingEvent event =
197 new LoggingEvent(
198 "org.apache.log4j.Logger", logger, Level.INFO, "Hello, World", null);
199 XMLLayout layout = (XMLLayout) createLayout();
200 String result = layout.format(event);
201 Element parsedResult = parse(result);
202 checkEventElement(parsedResult, event);
203
204 int childElementCount = 0;
205
206 for (
207 Node node = parsedResult.getFirstChild(); node != null;
208 node = node.getNextSibling()) {
209 switch (node.getNodeType()) {
210 case Node.ELEMENT_NODE:
211 childElementCount++;
212 checkMessageElement((Element) node, "Hello, World");
213
214 break;
215
216 case Node.COMMENT_NODE:
217 break;
218
219 case Node.TEXT_NODE:
220
221
222 break;
223
224 default:
225 fail("Unexpected node type");
226
227 break;
228 }
229 }
230
231 assertEquals(1, childElementCount);
232 }
233
234
235
236
237
238 public void testFormatWithException() throws Exception {
239 Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest");
240 Exception ex = new IllegalArgumentException("'foo' is not a valid name");
241 LoggingEvent event =
242 new LoggingEvent(
243 "org.apache.log4j.Logger", logger, Level.INFO, "Hello, World", ex);
244 XMLLayout layout = (XMLLayout) createLayout();
245 String result = layout.format(event);
246 Element parsedResult = parse(result);
247 checkEventElement(parsedResult, event);
248
249 int childElementCount = 0;
250
251 for (
252 Node node = parsedResult.getFirstChild(); node != null;
253 node = node.getNextSibling()) {
254 switch (node.getNodeType()) {
255 case Node.ELEMENT_NODE:
256 childElementCount++;
257
258 if (childElementCount == 1) {
259 checkMessageElement((Element) node, "Hello, World");
260 } else {
261 checkThrowableElement((Element) node, ex);
262 }
263
264 break;
265
266 case Node.COMMENT_NODE:
267 break;
268
269 case Node.TEXT_NODE:
270
271
272 break;
273
274 default:
275 fail("Unexpected node type");
276
277 break;
278 }
279 }
280
281 assertEquals(2, childElementCount);
282 }
283
284
285
286
287
288 public void testFormatWithNDC() throws Exception {
289 Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest");
290 NDC.push("NDC goes here");
291
292 LoggingEvent event =
293 new LoggingEvent(
294 "org.apache.log4j.Logger", logger, Level.INFO, "Hello, World", null);
295 XMLLayout layout = (XMLLayout) createLayout();
296 String result = layout.format(event);
297 NDC.pop();
298
299 Element parsedResult = parse(result);
300 checkEventElement(parsedResult, event);
301
302 int childElementCount = 0;
303
304 for (
305 Node node = parsedResult.getFirstChild(); node != null;
306 node = node.getNextSibling()) {
307 switch (node.getNodeType()) {
308 case Node.ELEMENT_NODE:
309 childElementCount++;
310
311 if (childElementCount == 1) {
312 checkMessageElement((Element) node, "Hello, World");
313 } else {
314 checkNDCElement((Element) node, "NDC goes here");
315 }
316
317 break;
318
319 case Node.COMMENT_NODE:
320 break;
321
322 case Node.TEXT_NODE:
323
324
325 break;
326
327 default:
328 fail("Unexpected node type");
329
330 break;
331 }
332 }
333
334 assertEquals(2, childElementCount);
335 }
336
337
338
339
340 public void testGetSetLocationInfo() {
341 XMLLayout layout = new XMLLayout();
342 assertEquals(false, layout.getLocationInfo());
343 layout.setLocationInfo(true);
344 assertEquals(true, layout.getLocationInfo());
345 layout.setLocationInfo(false);
346 assertEquals(false, layout.getLocationInfo());
347 }
348
349
350
351
352 public void testActivateOptions() {
353 XMLLayout layout = new XMLLayout();
354 layout.activateOptions();
355 }
356
357
358
359
360 private static final class ProblemLevel extends Level {
361 private static final long serialVersionUID = 1L;
362
363
364
365
366 public ProblemLevel(final String levelName) {
367 super(6000, levelName, 6);
368 }
369 }
370
371
372
373
374
375 public void testProblemCharacters() throws Exception {
376 String problemName = "com.example.bar<>&\"'";
377 Logger logger = Logger.getLogger(problemName);
378 Level level = new ProblemLevel(problemName);
379 Exception ex = new IllegalArgumentException(problemName);
380 String threadName = Thread.currentThread().getName();
381 Thread.currentThread().setName(problemName);
382 NDC.push(problemName);
383 Hashtable mdcMap = MDC.getContext();
384 if (mdcMap != null) {
385 mdcMap.clear();
386 }
387 MDC.put(problemName, problemName);
388 LoggingEvent event =
389 new LoggingEvent(
390 problemName, logger, level, problemName, ex);
391 XMLLayout layout = (XMLLayout) createLayout();
392 layout.setProperties(true);
393 String result = layout.format(event);
394 mdcMap = MDC.getContext();
395 if (mdcMap != null) {
396 mdcMap.clear();
397 }
398 Thread.currentThread().setName(threadName);
399
400 Element parsedResult = parse(result);
401 checkEventElement(parsedResult, event);
402
403 int childElementCount = 0;
404
405 for (
406 Node node = parsedResult.getFirstChild(); node != null;
407 node = node.getNextSibling()) {
408 switch (node.getNodeType()) {
409 case Node.ELEMENT_NODE:
410 childElementCount++;
411 switch(childElementCount) {
412 case 1:
413 checkMessageElement((Element) node, problemName);
414 break;
415
416 case 2:
417 checkNDCElement((Element) node, problemName);
418 break;
419
420 case 3:
421 checkThrowableElement((Element) node, ex);
422 break;
423
424 case 4:
425 checkPropertiesElement((Element) node, problemName, problemName);
426 break;
427
428 default:
429 fail("Unexpected element");
430 break;
431 }
432
433 break;
434
435 case Node.COMMENT_NODE:
436 break;
437
438 case Node.TEXT_NODE:
439
440
441 break;
442
443 default:
444 fail("Unexpected node type");
445
446 break;
447 }
448 }
449 }
450
451
452
453
454 public void testNDCWithCDATA() throws Exception {
455 Logger logger = Logger.getLogger("com.example.bar");
456 Level level = Level.INFO;
457 String ndcMessage ="<envelope><faultstring><![CDATA[The EffectiveDate]]></faultstring><envelope>";
458 NDC.push(ndcMessage);
459 LoggingEvent event =
460 new LoggingEvent(
461 "com.example.bar", logger, level, "Hello, World", null);
462 Layout layout = createLayout();
463 String result = layout.format(event);
464 NDC.clear();
465 Element parsedResult = parse(result);
466 NodeList ndcs = parsedResult.getElementsByTagName("log4j:NDC");
467 assertEquals(1, ndcs.getLength());
468 StringBuffer buf = new StringBuffer();
469 for(Node child = ndcs.item(0).getFirstChild();
470 child != null;
471 child = child.getNextSibling()) {
472 buf.append(child.getNodeValue());
473 }
474 assertEquals(ndcMessage, buf.toString());
475 }
476
477
478
479
480 public void testExceptionWithCDATA() throws Exception {
481 Logger logger = Logger.getLogger("com.example.bar");
482 Level level = Level.INFO;
483 String exceptionMessage ="<envelope><faultstring><![CDATA[The EffectiveDate]]></faultstring><envelope>";
484 LoggingEvent event =
485 new LoggingEvent(
486 "com.example.bar", logger, level, "Hello, World", new Exception(exceptionMessage));
487 Layout layout = createLayout();
488 String result = layout.format(event);
489 Element parsedResult = parse(result);
490 NodeList throwables = parsedResult.getElementsByTagName("log4j:throwable");
491 assertEquals(1, throwables.getLength());
492 StringBuffer buf = new StringBuffer();
493 for(Node child = throwables.item(0).getFirstChild();
494 child != null;
495 child = child.getNextSibling()) {
496 buf.append(child.getNodeValue());
497 }
498 assertTrue(buf.toString().indexOf(exceptionMessage) != -1);
499 }
500
501 }