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.Level;
21 import org.apache.log4j.Logger;
22 import org.apache.log4j.helpers.UtilLoggingLevel;
23 import org.apache.log4j.spi.Decoder;
24 import org.apache.log4j.spi.LocationInfo;
25 import org.apache.log4j.spi.LoggingEvent;
26 import org.apache.log4j.spi.ThrowableInformation;
27 import org.w3c.dom.Document;
28 import org.w3c.dom.Node;
29 import org.w3c.dom.NodeList;
30 import org.xml.sax.InputSource;
31
32 import javax.swing.*;
33 import javax.xml.parsers.DocumentBuilder;
34 import javax.xml.parsers.DocumentBuilderFactory;
35 import javax.xml.parsers.ParserConfigurationException;
36 import java.awt.*;
37 import java.io.*;
38 import java.net.URL;
39 import java.util.*;
40 import java.util.zip.ZipInputStream;
41
42
43
44
45
46
47
48
49
50 public class UtilLoggingXMLDecoder implements Decoder {
51
52
53
54
55
56 private static final String BEGIN_PART =
57 "<log>";
58
59
60
61 private static final String END_PART = "</log>";
62
63
64
65 private DocumentBuilder docBuilder;
66
67
68
69 private Map additionalProperties = new HashMap();
70
71
72
73 private String partialEvent;
74
75
76
77 private static final String RECORD_END = "</record>";
78
79
80
81 private Component owner = null;
82
83 private static final String ENCODING = "UTF-8";
84
85
86
87
88
89
90 public UtilLoggingXMLDecoder(final Component o) {
91 this();
92 this.owner = o;
93 }
94
95
96
97
98 public UtilLoggingXMLDecoder() {
99 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
100 dbf.setValidating(false);
101
102 try {
103 docBuilder = dbf.newDocumentBuilder();
104 docBuilder.setErrorHandler(new SAXErrorHandler());
105 docBuilder.setEntityResolver(new UtilLoggingEntityResolver());
106 } catch (ParserConfigurationException pce) {
107 System.err.println("Unable to get document builder");
108 }
109 }
110
111
112
113
114
115
116
117
118
119 public void setAdditionalProperties(final Map properties) {
120 this.additionalProperties = properties;
121 }
122
123
124
125
126
127
128
129
130 private Document parse(final String data) {
131 if (docBuilder == null || data == null) {
132 return null;
133 }
134
135 Document document = null;
136
137 try {
138
139
140
141
142
143
144
145
146
147 StringBuilder buf = new StringBuilder(1024);
148
149 if (!data.startsWith("<?xml")) {
150 buf.append(BEGIN_PART);
151 }
152
153 buf.append(data);
154
155 if (!data.endsWith(END_PART)) {
156 buf.append(END_PART);
157 }
158
159 InputSource inputSource =
160 new InputSource(new StringReader(buf.toString()));
161 document = docBuilder.parse(inputSource);
162 } catch (Exception e) {
163 e.printStackTrace();
164 }
165
166 return document;
167 }
168
169
170
171
172
173
174
175
176 public Vector<LoggingEvent> decode(final URL url) throws IOException {
177 LineNumberReader reader;
178 boolean isZipFile = url.getPath().toLowerCase().endsWith(".zip");
179 InputStream inputStream;
180 if (isZipFile) {
181 inputStream = new ZipInputStream(url.openStream());
182
183 ((ZipInputStream) inputStream).getNextEntry();
184 } else {
185 inputStream = url.openStream();
186 }
187 if (owner != null) {
188 reader = new LineNumberReader(
189 new InputStreamReader(
190 new ProgressMonitorInputStream(owner,
191 "Loading " + url, inputStream), ENCODING));
192 } else {
193 reader = new LineNumberReader(new InputStreamReader(inputStream, ENCODING));
194 }
195 Vector<LoggingEvent> v = new Vector<>();
196
197 String line;
198 Vector<LoggingEvent> events;
199 try {
200 while ((line = reader.readLine()) != null) {
201 StringBuilder buffer = new StringBuilder(line);
202 for (int i = 0; i < 1000; i++) {
203 buffer.append(reader.readLine()).append("\n");
204 }
205 events = decodeEvents(buffer.toString());
206 if (events != null) {
207 v.addAll(events);
208 }
209 }
210 } finally {
211 partialEvent = null;
212 try {
213 if (reader != null) {
214 reader.close();
215 }
216 } catch (Exception e) {
217 e.printStackTrace();
218 }
219 }
220 return v;
221 }
222
223
224
225
226
227
228
229
230 public Vector<LoggingEvent> decodeEvents(final String document) {
231
232 if (document != null) {
233
234 if (document.trim().equals("")) {
235 return null;
236 }
237
238 String newDoc;
239 String newPartialEvent = null;
240
241
242
243
244
245
246 if (document.lastIndexOf(RECORD_END) == -1) {
247 partialEvent = partialEvent + document;
248 return null;
249 }
250
251 if (document.lastIndexOf(RECORD_END) + RECORD_END.length()
252 < document.length()) {
253 newDoc = document.substring(0,
254 document.lastIndexOf(RECORD_END) + RECORD_END.length());
255 newPartialEvent = document.substring(
256 document.lastIndexOf(RECORD_END) + RECORD_END.length());
257 } else {
258 newDoc = document;
259 }
260 if (partialEvent != null) {
261 newDoc = partialEvent + newDoc;
262 }
263 partialEvent = newPartialEvent;
264
265 Document doc = parse(newDoc);
266 if (doc == null) {
267 return null;
268 }
269 return decodeEvents(doc);
270 }
271 return null;
272 }
273
274
275
276
277
278
279
280
281
282 public LoggingEvent decode(final String data) {
283 Document document = parse(data);
284
285 if (document == null) {
286 return null;
287 }
288
289 Vector<LoggingEvent> events = decodeEvents(document);
290
291 if (events.size() > 0) {
292 return events.firstElement();
293 }
294
295 return null;
296 }
297
298
299
300
301
302
303
304 private Vector<LoggingEvent> decodeEvents(final Document document) {
305 Vector<LoggingEvent> events = new Vector<>();
306
307 NodeList eventList = document.getElementsByTagName("record");
308
309 for (int eventIndex = 0; eventIndex < eventList.getLength();
310 eventIndex++) {
311 Node eventNode = eventList.item(eventIndex);
312
313 Logger logger = null;
314 long timeStamp = 0L;
315 Level level = null;
316 String threadName = null;
317 Object message = null;
318 String ndc = null;
319 String[] exception = null;
320 String className = null;
321 String methodName = null;
322 String fileName = null;
323 String lineNumber = null;
324 Hashtable properties = new Hashtable();
325
326
327
328 NodeList list = eventNode.getChildNodes();
329 int listLength = list.getLength();
330
331 if (listLength == 0) {
332 continue;
333 }
334
335 for (int y = 0; y < listLength; y++) {
336 String tagName = list.item(y).getNodeName();
337
338 if (tagName.equalsIgnoreCase("logger")) {
339 logger = Logger.getLogger(getCData(list.item(y)));
340 }
341
342 if (tagName.equalsIgnoreCase("millis")) {
343 timeStamp = Long.parseLong(getCData(list.item(y)));
344 }
345
346 if (tagName.equalsIgnoreCase("level")) {
347 level = UtilLoggingLevel.toLevel(getCData(list.item(y)));
348 }
349
350 if (tagName.equalsIgnoreCase("thread")) {
351 threadName = getCData(list.item(y));
352 }
353
354 if (tagName.equalsIgnoreCase("sequence")) {
355 properties.put("log4jid", getCData(list.item(y)));
356 }
357
358 if (tagName.equalsIgnoreCase("message")) {
359 message = getCData(list.item(y));
360 }
361
362 if (tagName.equalsIgnoreCase("class")) {
363 className = getCData(list.item(y));
364 }
365
366 if (tagName.equalsIgnoreCase("method")) {
367 methodName = getCData(list.item(y));
368 }
369
370 if (tagName.equalsIgnoreCase("exception")) {
371 ArrayList<String> exceptionList = new ArrayList<>();
372 NodeList exList = list.item(y).getChildNodes();
373 int exlistLength = exList.getLength();
374
375 for (int i2 = 0; i2 < exlistLength; i2++) {
376 Node exNode = exList.item(i2);
377 String exName = exList.item(i2).getNodeName();
378
379 if (exName.equalsIgnoreCase("message")) {
380 exceptionList.add(getCData(exList.item(i2)));
381 }
382
383 if (exName.equalsIgnoreCase("frame")) {
384 NodeList exList2 = exNode.getChildNodes();
385 int exlist2Length = exList2.getLength();
386
387 for (int i3 = 0; i3 < exlist2Length; i3++) {
388 exceptionList.add(getCData(exList2.item(i3)) + "\n");
389 }
390 }
391 }
392 if (exceptionList.size() > 0) {
393 exception =
394 (String[]) exceptionList.toArray(new String[exceptionList.size()]);
395 }
396 }
397 }
398
399
400
401
402
403 if (additionalProperties.size() > 0) {
404 if (properties == null) {
405 properties = new Hashtable(additionalProperties);
406 }
407 for (Object o : additionalProperties.entrySet()) {
408 Map.Entry e = (Map.Entry) o;
409 properties.put(e.getKey(), e.getValue());
410 }
411 }
412
413 LocationInfo info;
414 if ((fileName != null)
415 || (className != null)
416 || (methodName != null)
417 || (lineNumber != null)) {
418 info = new LocationInfo(fileName, className, methodName, lineNumber);
419 } else {
420 info = LocationInfo.NA_LOCATION_INFO;
421 }
422
423 ThrowableInformation throwableInfo = null;
424 if (exception != null) {
425 throwableInfo = new ThrowableInformation(exception);
426 }
427
428 LoggingEvent loggingEvent = new LoggingEvent(null,
429 logger, timeStamp, level, message,
430 threadName,
431 throwableInfo,
432 ndc,
433 info,
434 properties);
435
436 events.add(loggingEvent);
437
438 }
439 return events;
440 }
441
442
443
444
445
446
447
448 private String getCData(final Node n) {
449 StringBuilder buf = new StringBuilder();
450 NodeList nl = n.getChildNodes();
451
452 for (int x = 0; x < nl.getLength(); x++) {
453 Node innerNode = nl.item(x);
454
455 if (
456 (innerNode.getNodeType() == Node.TEXT_NODE)
457 || (innerNode.getNodeType() == Node.CDATA_SECTION_NODE)) {
458 buf.append(innerNode.getNodeValue());
459 }
460 }
461
462 return buf.toString();
463 }
464 }