001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.runtime13.v14.java.lang;
032:
033: import java.io.Serializable;
034:
035: /**
036: * @author Taras Puchko
037: */
038: public final class StackTraceElement_ implements Serializable {
039:
040: private static final String NATIVE_METHOD = "Native Method";
041: private static final String UNKNOWN_SOURCE = "Unknown Source";
042:
043: private String declaringClass;
044: private String methodName;
045: private String fileName;
046: private int lineNumber;
047:
048: public StackTraceElement_(String declaringClass, String methodName,
049: String fileName, int lineNumber) {
050: if (declaringClass == null || methodName == null) {
051: throw new NullPointerException();
052: }
053: this .declaringClass = declaringClass;
054: this .methodName = methodName;
055: this .fileName = fileName;
056: this .lineNumber = lineNumber;
057: }
058:
059: public String getClassName() {
060: return declaringClass;
061: }
062:
063: public String getFileName() {
064: return fileName;
065: }
066:
067: public int getLineNumber() {
068: return lineNumber;
069: }
070:
071: public String getMethodName() {
072: return methodName;
073: }
074:
075: public boolean isNativeMethod() {
076: return lineNumber == -2;
077: }
078:
079: public String toString() {
080: StringBuilder builder = new StringBuilder(declaringClass)
081: .append('.').append(methodName).append('(');
082: if (fileName != null) {
083: builder.append(fileName);
084: if (lineNumber >= 0) {
085: builder.append(':').append(lineNumber);
086: }
087: } else {
088: builder.append(isNativeMethod() ? NATIVE_METHOD
089: : UNKNOWN_SOURCE);
090: }
091: return builder.append(')').toString();
092: }
093:
094: public boolean equals(Object obj) {
095: if (obj == this ) {
096: return true;
097: }
098: if (!(obj instanceof StackTraceElement_)) {
099: return false;
100: }
101: StackTraceElement_ element = (StackTraceElement_) obj;
102: return equal(declaringClass, element.declaringClass)
103: && equal(methodName, element.methodName)
104: && equal(fileName, element.fileName)
105: && lineNumber == element.lineNumber;
106: }
107:
108: public int hashCode() {
109: return ((hash(declaringClass) * 31 + hash(methodName)) * 31 + hash(fileName))
110: * 31 + lineNumber;
111: }
112:
113: private static boolean equal(Object a, Object b) {
114: return a == b || a != null && a.equals(b);
115: }
116:
117: private static int hash(Object o) {
118: return o != null ? o.hashCode() : 0;
119: }
120:
121: static StackTraceElement_ valueOf(String s) {
122: int openIndex = s.lastIndexOf('(');
123: if (openIndex < 0 || !s.endsWith(")")) {
124: return null;
125: }
126: int dotIndex = s.lastIndexOf('.', openIndex);
127: if (dotIndex < 0) {
128: return null;
129: }
130: String declaringClass = s.substring(0, dotIndex);
131: String methodName = s.substring(dotIndex + 1, openIndex);
132: String position = s.substring(openIndex + 1, s.length() - 1);
133: String fileName = null;
134: int lineNumber = -1;
135: if (position.equals(NATIVE_METHOD)) {
136: lineNumber = -2;
137: } else if (!position.equals(UNKNOWN_SOURCE)) {
138: int colonIndex = position.lastIndexOf(':');
139: if (colonIndex < 0) {
140: fileName = position;
141: } else {
142: try {
143: lineNumber = Integer.parseInt(position
144: .substring(colonIndex + 1));
145: fileName = position.substring(0, colonIndex);
146: } catch (NumberFormatException e) {
147: fileName = position;
148: }
149: }
150: }
151: int index = methodName.indexOf('(');
152: if (index >= 0) {
153: methodName = methodName.substring(0, index);
154: }
155: return new StackTraceElement_(declaringClass, methodName,
156: fileName, lineNumber);
157: }
158:
159: }
|