01: /*
02: * Copyright (C) 2004 Joe Walnes.
03: * Copyright (C) 2006, 2007 XStream Committers.
04: * All rights reserved.
05: *
06: * The software in this package is published under the terms of the BSD
07: * style license a copy of which has been included with this distribution in
08: * the LICENSE.txt file.
09: *
10: * Created on 29. May 2004 by Joe Walnes
11: */
12: package com.thoughtworks.xstream.converters.extended;
13:
14: import java.util.regex.Matcher;
15: import java.util.regex.Pattern;
16:
17: import com.thoughtworks.xstream.converters.ConversionException;
18: import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
19:
20: /**
21: * Converter for StackTraceElement (the lines of a stack trace) - JDK 1.4+ only.
22: *
23: * @author <a href="mailto:boxley@thoughtworks.com">B. K. Oxley (binkley)</a>
24: * @author Joe Walnes
25: */
26: public class StackTraceElementConverter extends
27: AbstractSingleValueConverter {
28:
29: // Regular expression to parse a line of a stack trace. Returns 4 groups.
30: //
31: // Example: com.blah.MyClass.doStuff(MyClass.java:123)
32: // |-------1------| |--2--| |----3-----| |4|
33: // (Note group 4 is optional is optional and only present if a colon char exists.)
34:
35: private static final Pattern PATTERN = Pattern
36: .compile("^(.+)\\.([^\\(]+)\\(([^:]*)(:(\\d+))?\\)$");
37: private static final StackTraceElementFactory FACTORY = new StackTraceElementFactory();
38:
39: public boolean canConvert(Class type) {
40: return StackTraceElement.class.equals(type);
41: }
42:
43: public String toString(Object obj) {
44: String s = super .toString(obj);
45: // JRockit adds ":???" for invalid line number
46: return s.replaceFirst(":\\?\\?\\?", "");
47: }
48:
49: public Object fromString(String str) {
50: Matcher matcher = PATTERN.matcher(str);
51: if (matcher.matches()) {
52: String declaringClass = matcher.group(1);
53: String methodName = matcher.group(2);
54: String fileName = matcher.group(3);
55: if (fileName.equals("Unknown Source")) {
56: return FACTORY.unknownSourceElement(declaringClass,
57: methodName);
58: } else if (fileName.equals("Native Method")) {
59: return FACTORY.nativeMethodElement(declaringClass,
60: methodName);
61: } else {
62: if (matcher.group(4) != null) {
63: int lineNumber = Integer.parseInt(matcher.group(5));
64: return FACTORY.element(declaringClass, methodName,
65: fileName, lineNumber);
66: } else {
67: return FACTORY.element(declaringClass, methodName,
68: fileName);
69: }
70: }
71: } else {
72: throw new ConversionException(
73: "Could not parse StackTraceElement : " + str);
74: }
75: }
76:
77: }
|