1 21 package proguard.retrace; 22 23 import java.io.*; 24 import java.util.*; 25 26 import proguard.obfuscate.MappingProcessor; 27 28 29 35 class StackTraceItem implements MappingProcessor 36 { 37 private boolean verbose; 39 40 public String prefix; 41 public String obfuscatedClassName; 42 public String obfuscatedMethodName; 43 public String sourceFile; 44 public int lineNumber; 45 public String suffix; 46 47 public String originalClassName; 48 public List originalMethodNames; 49 50 55 public StackTraceItem(boolean verbose) 56 { 57 this.verbose = verbose; 58 } 59 60 61 64 public void parse(String line) throws IOException 65 { 66 if (!parseAtLine(line) && 67 !parseExceptionInThreadLine(line)) 68 { 69 parseAnyLine(line); 70 } 71 } 72 73 74 78 private boolean parseAtLine(String line) 79 { 80 if (!line.startsWith("at ")) 81 { 82 return false; 83 } 84 85 int openParenthesisIndex = line.indexOf('(', 3); 86 if (openParenthesisIndex < 0) 87 { 88 return false; 89 } 90 91 int colonIndex = line.indexOf(':', openParenthesisIndex + 1); 92 93 int closeParenthesisIndex = line.indexOf(')', Math.max(openParenthesisIndex, colonIndex) + 1); 94 if (closeParenthesisIndex < 0) 95 { 96 return false; 97 } 98 99 int periodIndex = line.lastIndexOf('.', openParenthesisIndex - 1); 100 if (periodIndex < 0) 101 { 102 return false; 103 } 104 105 prefix = " at "; 106 obfuscatedClassName = line.substring(3, periodIndex).trim(); 107 obfuscatedMethodName = line.substring(periodIndex + 1, openParenthesisIndex).trim(); 108 sourceFile = line.substring(openParenthesisIndex + 1, colonIndex < 0 ? closeParenthesisIndex : colonIndex).trim(); 109 lineNumber = colonIndex < 0 ? 0 : Integer.parseInt(line.substring(colonIndex + 1, closeParenthesisIndex).trim()); 110 111 return true; 112 } 113 114 115 120 private boolean parseExceptionInThreadLine(String line) 121 { 122 if (line.startsWith("Exception in thread \"")) 124 { 125 int quote_index = line.indexOf('"', 21); 126 if (quote_index < 0) 127 { 128 return false; 129 } 130 131 prefix = line.substring(0, quote_index+1) + " "; 132 line = line.substring(quote_index+1).trim(); 133 } 134 135 int colonIndex = line.indexOf(':'); 136 if (colonIndex < 0) 137 { 138 return false; 139 } 140 141 int spaceIndex = line.lastIndexOf(' ', colonIndex); 142 143 prefix = line.substring(0, spaceIndex+1); 144 obfuscatedClassName = line.substring(spaceIndex+1, colonIndex).trim(); 145 suffix = line.substring(colonIndex); 146 147 return true; 148 } 149 150 151 154 private void parseAnyLine(String line) 155 { 156 prefix = line; 157 } 158 159 160 163 public void print() 164 { 165 String className = originalClassName != null ? 167 originalClassName : 168 obfuscatedClassName; 169 170 String methodName = originalMethodNames != null ? 172 (String )originalMethodNames.get(0) : 173 obfuscatedMethodName; 174 175 String source = lineNumber != 0 ? 177 sourceFile + ":" + lineNumber : 178 sourceFile; 179 180 if (prefix != null) 182 { 183 System.out.print(prefix); 184 } 185 186 if (className != null) 187 { 188 System.out.print(className); 189 } 190 191 if (methodName != null) 192 { 193 System.out.print("." + methodName + "(" + source + ")"); 194 195 if (originalMethodNames != null) 197 { 198 for (int otherMethodNameIndex = 1; otherMethodNameIndex < originalMethodNames.size(); otherMethodNameIndex++) { 199 String otherMethodName = (String )originalMethodNames.get(otherMethodNameIndex); 200 System.out.println(); 201 printSpaces(className.length()+12); 202 System.out.print(otherMethodName); 203 } 204 } 205 } 206 207 if (suffix != null) 208 { 209 System.out.print(suffix); 210 } 211 212 System.out.println(); 213 } 214 215 216 219 private void printSpaces(int aCount) 220 { 221 for (int counter = 0; counter < aCount; counter++) 222 System.out.print(' '); 223 } 224 225 226 228 public boolean processClassMapping(String className, 229 String newClassName) 230 { 231 boolean present = false; 232 233 if (newClassName.equals(obfuscatedClassName)) 234 { 235 originalClassName = className; 236 present = true; 237 } 238 239 return present; 240 } 241 242 243 public void processFieldMapping(String className, 244 String fieldType, 245 String fieldName, 246 String newFieldName) 247 { 248 } 250 251 252 public void processMethodMapping(String className, 253 int firstLineNumber, 254 int lastLineNumber, 255 String methodReturnType, 256 String methodNameAndArguments, 257 String newMethodName) 258 { 259 if (className.equals(originalClassName) && 260 newMethodName.equals(obfuscatedMethodName) && 261 (lineNumber == 0 || 262 firstLineNumber == 0 || 263 lastLineNumber == 0 || 264 (firstLineNumber <= lineNumber && 265 lastLineNumber >= lineNumber))) 266 { 267 if (originalMethodNames == null) 270 { 271 originalMethodNames = new ArrayList(); 272 } 273 274 if (firstLineNumber != 0 && 276 lastLineNumber != 0 && 277 lineNumber != 0) 278 { 279 obfuscatedMethodName = null; 281 originalMethodNames.clear(); 282 } 283 284 String originalMethodName = verbose ? 287 (methodReturnType + " " + methodNameAndArguments) : 288 methodNameAndArguments.substring(0, methodNameAndArguments.indexOf('(')); 289 290 originalMethodNames.add(originalMethodName); 292 } 293 } 294 } 295 | Popular Tags |