1 15 package org.apache.tapestry.util.exception; 16 17 import java.beans.BeanInfo ; 18 import java.beans.IntrospectionException ; 19 import java.beans.Introspector ; 20 import java.beans.PropertyDescriptor ; 21 import java.io.CharArrayWriter ; 22 import java.io.IOException ; 23 import java.io.LineNumberReader ; 24 import java.io.PrintStream ; 25 import java.io.PrintWriter ; 26 import java.io.StringReader ; 27 import java.lang.reflect.Method ; 28 import java.util.ArrayList ; 29 import java.util.List ; 30 31 36 37 public class ExceptionAnalyzer 38 { 39 private final List exceptionDescriptions = new ArrayList (); 40 41 private final List propertyDescriptions = new ArrayList (); 42 43 private final CharArrayWriter writer = new CharArrayWriter (); 44 45 private boolean exhaustive = false; 46 47 51 52 public boolean isExhaustive() 53 { 54 return exhaustive; 55 } 56 57 public void setExhaustive(boolean value) 58 { 59 exhaustive = value; 60 } 61 62 78 79 public ExceptionDescription[] analyze(Throwable exception) 80 { 81 try 82 { 83 84 while (exception != null) 85 { 86 exception = buildDescription(exception); 87 } 88 89 ExceptionDescription[] result = new ExceptionDescription[exceptionDescriptions.size()]; 90 91 return (ExceptionDescription[]) exceptionDescriptions.toArray(result); 92 } 93 finally 94 { 95 exceptionDescriptions.clear(); 96 propertyDescriptions.clear(); 97 98 writer.reset(); 99 } 100 } 101 102 protected Throwable buildDescription(Throwable exception) 103 { 104 BeanInfo info; 105 Class exceptionClass; 106 ExceptionProperty property; 107 PropertyDescriptor [] descriptors; 108 PropertyDescriptor descriptor; 109 Throwable next = null; 110 int i; 111 Object value; 112 Method method; 113 ExceptionProperty[] properties; 114 ExceptionDescription description; 115 String stringValue; 116 String message; 117 String [] stackTrace = null; 118 119 propertyDescriptions.clear(); 120 121 message = exception.getMessage(); 122 exceptionClass = exception.getClass(); 123 124 127 try 128 { 129 info = Introspector.getBeanInfo(exceptionClass, Throwable .class); 130 } 131 catch (IntrospectionException e) 132 { 133 return null; 134 } 135 136 descriptors = info.getPropertyDescriptors(); 137 138 for (i = 0; i < descriptors.length; i++) 139 { 140 descriptor = descriptors[i]; 141 142 method = descriptor.getReadMethod(); 143 if (method == null) 144 continue; 145 146 try 147 { 148 value = method.invoke(exception, null); 149 } 150 catch (Exception e) 151 { 152 continue; 153 } 154 155 if (value == null) 156 continue; 157 158 161 if (message != null && message.equals(value)) 162 continue; 163 164 169 if (value instanceof Throwable ) 170 { 171 if (next == null) 172 next = (Throwable ) value; 173 174 continue; 175 } 176 177 stringValue = value.toString().trim(); 178 179 if (stringValue.length() == 0) 180 continue; 181 182 property = new ExceptionProperty(descriptor.getDisplayName(), value); 183 184 propertyDescriptions.add(property); 185 } 186 187 190 if (next == null || exhaustive) 191 stackTrace = getStackTrace(exception); 192 193 195 properties = new ExceptionProperty[propertyDescriptions.size()]; 196 197 ExceptionProperty[] propArray = (ExceptionProperty[]) propertyDescriptions 198 .toArray(properties); 199 200 description = new ExceptionDescription(exceptionClass.getName(), message, propArray, 201 stackTrace); 202 203 exceptionDescriptions.add(description); 204 205 return next; 206 } 207 208 220 221 protected String [] getStackTrace(Throwable exception) 222 { 223 writer.reset(); 224 225 PrintWriter printWriter = new PrintWriter (writer); 226 227 exception.printStackTrace(printWriter); 228 229 printWriter.close(); 230 231 String fullTrace = writer.toString(); 232 233 writer.reset(); 234 235 237 StringReader stringReader = new StringReader (fullTrace); 238 LineNumberReader lineReader = new LineNumberReader (stringReader); 239 int lineNumber = 0; 240 List frames = new ArrayList (); 241 242 try 243 { 244 while (true) 245 { 246 String line = lineReader.readLine(); 247 248 if (line == null) 249 break; 250 251 253 if (++lineNumber == 1) 254 continue; 255 256 frames.add(stripFrame(line)); 257 } 258 259 lineReader.close(); 260 } 261 catch (IOException ex) 262 { 263 } 266 267 String result[] = new String [frames.size()]; 268 269 return (String []) frames.toArray(result); 270 } 271 272 private static final int SKIP_LEADING_WHITESPACE = 0; 273 274 private static final int SKIP_T = 1; 275 276 private static final int SKIP_OTHER_WHITESPACE = 2; 277 278 282 283 private String stripFrame(String frame) 284 { 285 char array[] = frame.toCharArray(); 286 287 int i = 0; 288 int state = SKIP_LEADING_WHITESPACE; 289 boolean more = true; 290 291 while (more) 292 { 293 295 if (i == array.length) 296 return ""; 297 298 char ch = array[i]; 299 300 switch (state) 301 { 302 304 case SKIP_LEADING_WHITESPACE: 305 306 if (Character.isWhitespace(ch)) 307 { 308 i++; 309 continue; 310 } 311 312 if (ch == 'a') 313 { 314 state = SKIP_T; 315 i++; 316 continue; 317 } 318 319 more = false; 321 break; 322 323 325 case SKIP_T: 326 327 if (ch == 't') 328 { 329 state = SKIP_OTHER_WHITESPACE; 330 i++; 331 continue; 332 } 333 334 336 i--; 337 more = false; 338 break; 339 340 342 case SKIP_OTHER_WHITESPACE: 343 344 if (Character.isWhitespace(ch)) 345 { 346 i++; 347 continue; 348 } 349 350 more = false; 352 break; 353 } 354 355 } 356 357 359 if (i == 0) 360 return frame; 361 362 return frame.substring(i); 363 } 364 365 368 369 public void reportException(Throwable exception, PrintStream stream) 370 { 371 int i; 372 int j; 373 ExceptionDescription[] descriptions; 374 ExceptionProperty[] properties; 375 String [] stackTrace; 376 String message; 377 378 descriptions = analyze(exception); 379 380 for (i = 0; i < descriptions.length; i++) 381 { 382 message = descriptions[i].getMessage(); 383 384 if (message == null) 385 stream.println(descriptions[i].getExceptionClassName()); 386 else 387 stream.println(descriptions[i].getExceptionClassName() + ": " 388 + descriptions[i].getMessage()); 389 390 properties = descriptions[i].getProperties(); 391 392 for (j = 0; j < properties.length; j++) 393 stream.println(" " + properties[j].getName() + ": " + properties[j].getValue()); 394 395 397 if (i + 1 == descriptions.length) 398 { 399 stackTrace = descriptions[i].getStackTrace(); 400 401 for (j = 0; j < stackTrace.length; j++) 402 stream.println(stackTrace[j]); 403 } 404 else 405 stream.println(); 406 } 407 } 408 409 } | Popular Tags |