001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.retrace;
022:
023: import proguard.obfuscate.MappingProcessor;
024:
025: import java.io.*;
026: import java.util.*;
027:
028: /**
029: * This class represents an obfuscated stack trace. It can read, de-obfuscate,
030: * and then write its contents.
031: *
032: * @author Eric Lafortune
033: */
034: final class StackTrace implements MappingProcessor {
035: // The stack trace settings.
036: private final boolean verbose;
037:
038: // The stack trace items.
039: private final List stackTraceItems = new ArrayList();
040:
041: /**
042: * Creates a new StackTrace.
043: * @param verbose specifies whether the de-obfuscated stack trace should
044: * be verbose.
045: */
046: public StackTrace(boolean verbose) {
047: this .verbose = verbose;
048: }
049:
050: /**
051: * Reads the stack trace file.
052: */
053: public void read(File stackTraceFile) throws IOException {
054: LineNumberReader lineNumberReader = null;
055:
056: try {
057: Reader reader = stackTraceFile == null ? (Reader) new InputStreamReader(
058: System.in)
059: : (Reader) new BufferedReader(new FileReader(
060: stackTraceFile));
061:
062: lineNumberReader = new LineNumberReader(reader);
063:
064: // Read the line in the stack trace.
065: while (true) {
066: String line = lineNumberReader.readLine();
067: if (line == null) {
068: break;
069: }
070:
071: line = line.trim();
072: if (line.length() == 0) {
073: continue;
074: }
075:
076: // Put the line in a stack trace item.
077: StackTraceItem item = new StackTraceItem(verbose);
078:
079: item.parse(line);
080:
081: stackTraceItems.add(item);
082: }
083: } catch (IOException ex) {
084: throw new IOException("Can't read stack trace ("
085: + ex.getMessage() + ")");
086: } finally {
087: if (stackTraceFile != null && lineNumberReader != null) {
088: try {
089: lineNumberReader.close();
090: } catch (IOException ex) {
091: // This shouldn't happen.
092: }
093: }
094: }
095: }
096:
097: /**
098: * Prints out the de-obfuscated stack trace.
099: */
100: public void print() {
101: // Delegate to each of the stack trace items.
102: for (int index = 0; index < stackTraceItems.size(); index++) {
103: StackTraceItem item = (StackTraceItem) stackTraceItems
104: .get(index);
105:
106: item.print();
107: }
108: }
109:
110: // Implementations for MappingProcessor.
111:
112: public boolean processClassMapping(String className,
113: String newClassName) {
114: // Delegate to each of the stack trace items.
115: boolean present = false;
116: for (int index = 0; index < stackTraceItems.size(); index++) {
117: StackTraceItem item = (StackTraceItem) stackTraceItems
118: .get(index);
119:
120: present |= item
121: .processClassMapping(className, newClassName);
122: }
123:
124: return present;
125: }
126:
127: public void processFieldMapping(String className, String fieldType,
128: String fieldName, String newFieldName) {
129: // A stack trace never contains any fields.
130: }
131:
132: public void processMethodMapping(String className,
133: int firstLineNumber, int lastLineNumber,
134: String methodReturnType, String methodNameAndArguments,
135: String newMethodName) {
136: // Delegate to each of the stack trace items.
137: for (int index = 0; index < stackTraceItems.size(); index++) {
138: StackTraceItem item = (StackTraceItem) stackTraceItems
139: .get(index);
140:
141: item.processMethodMapping(className, firstLineNumber,
142: lastLineNumber, methodReturnType,
143: methodNameAndArguments, newMethodName);
144: }
145: }
146: }
|