1 19 20 package org.netbeans.core; 21 22 import java.io.OutputStreamWriter ; 23 import java.io.PrintStream ; 24 import java.io.PrintWriter ; 25 import java.io.StringWriter ; 26 import java.text.MessageFormat ; 27 import java.util.ArrayList ; 28 import java.util.Arrays ; 29 import java.util.Date ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.ResourceBundle ; 34 import java.util.Set ; 35 import java.util.concurrent.Callable ; 36 import java.util.logging.Handler ; 37 import java.util.logging.Level ; 38 import java.util.logging.LogRecord ; 39 import java.util.logging.Logger ; 40 41 45 public final class NbErrorManager extends Handler { 46 47 static Exc createExc(Throwable t, Level severity, LogRecord add) { 48 LogRecord [] ann = findAnnotations(t, add); 49 return new Exc(t, severity, ann, findAnnotations0(t, add, true, new HashSet <Throwable >())); 50 } 51 52 public void publish(LogRecord record) { 53 if (record.getThrown() != null) { 54 Level level = record.getLevel(); 55 if (level.intValue() == Level.WARNING.intValue() + 1) { 56 level = null; 58 } 59 if (level != null && level.intValue() == Level.SEVERE.intValue() + 1) { 60 level = null; 62 } 63 Exc ex = createExc(record.getThrown(), level, record.getLevel().intValue() == 1973 ? record : null); 64 NotifyExcPanel.notify(ex); 65 } 66 } 67 68 public void flush() { 69 } 71 72 public void close() throws SecurityException { 73 } 75 76 77 private static final String getLocalizedMessage(LogRecord rec) { 78 ResourceBundle rb = rec.getResourceBundle(); 79 if (rb == null) { 80 return null; 81 } 82 83 String msg = rec.getMessage(); 84 if (msg == null) { 85 return null; 86 } 87 88 String format = rb.getString(msg); 89 90 Object [] arr = rec.getParameters(); 91 if (arr == null) { 92 return format; 93 } 94 95 return MessageFormat.format(format, arr); 96 } 97 98 102 private static LogRecord [] findAnnotations(Throwable t, LogRecord add) { 103 return findAnnotations0(t, add, false, new HashSet <Throwable >()); 104 } 105 106 110 private static LogRecord [] findAnnotations0(Throwable t, LogRecord add, boolean recursively, Set <Throwable > alreadyVisited) { 111 List <LogRecord > l = new ArrayList <LogRecord >(); 112 Throwable collect = t; 113 while (collect != null) { 114 if (collect instanceof Callable ) { 115 Object res = null; 116 try { 117 res = ((Callable ) collect).call(); 118 } catch (Exception ex) { 119 ex.printStackTrace(); 120 } 121 if (res instanceof LogRecord []) { 122 LogRecord [] arr = (LogRecord [])res; 123 l.addAll(Arrays.asList(arr)); 124 } 125 } 126 collect = collect.getCause(); 127 } 128 129 if (add != null) { 130 l.add(add); 131 } 132 133 134 if (recursively) { 135 ArrayList <LogRecord > al = new ArrayList <LogRecord >(); 136 for (Iterator <LogRecord > i = l.iterator(); i.hasNext(); ) { 137 LogRecord ano = i.next(); 138 Throwable t1 = ano.getThrown(); 139 if ((t1 != null) && (! alreadyVisited.contains(t1))) { 140 alreadyVisited.add(t1); 141 LogRecord [] tmpAnnoArray = findAnnotations0(t1, null, true, alreadyVisited); 142 if ((tmpAnnoArray != null) && (tmpAnnoArray.length > 0)) { 143 al.addAll(Arrays.asList(tmpAnnoArray)); 144 } 145 } 146 } 147 l.addAll(al); 148 } 149 150 Throwable cause = t.getCause(); 151 if (cause != null) { 152 LogRecord [] extras = findAnnotations0(cause, null, true, alreadyVisited); 153 if (extras != null && extras.length > 0) { 154 l.addAll(Arrays.asList(extras)); 155 } 156 } 157 158 LogRecord [] arr; 159 arr = new LogRecord [l.size()]; 160 l.toArray(arr); 161 162 return arr; 163 } 164 165 169 static final class Exc { 170 171 private Throwable t; 172 private Date d; 173 private LogRecord [] arr; 174 private LogRecord [] arrAll; private Level severity; 176 177 180 Exc(Throwable t, Level severity, LogRecord [] arr, LogRecord [] arrAll) { 181 this.t = t; 182 this.severity = severity; 183 this.arr = arr == null ? new LogRecord [0] : arr; 184 this.arrAll = arrAll == null ? new LogRecord [0] : arrAll; 185 } 186 187 188 String getMessage() { 189 String m = t.getMessage(); 190 if (m != null) { 191 return m; 192 } 193 return (String )find(1); 194 } 195 196 197 String getLocalizedMessage() { 198 String m = t.getLocalizedMessage(); 199 if (m != null && !m.equals(t.getMessage())) { 200 return m; 201 } 202 if (arrAll == null) { 203 return (String )find(2); 205 } 206 for (int i = 0; i < arrAll.length; i++) { 207 String s = NbErrorManager.getLocalizedMessage(arrAll[i]); 208 if (s != null) { 209 return s; 210 } 211 } 212 return m; 213 } 214 215 boolean isLocalized() { 216 String m = t.getLocalizedMessage(); 217 if (m != null && !m.equals(t.getMessage())) { 218 return true; 219 } 220 if (arrAll == null) { 221 return (String )find(2) != null; 223 } 224 for (int i = 0; i < arrAll.length; i++) { 225 String s = NbErrorManager.getLocalizedMessage(arrAll[i]); 226 if (s != null) { 227 return true; 228 } 229 } 230 return false; 231 } 232 233 234 String getClassName() { 235 return (String )find(3); 236 } 237 238 239 Level getSeverity() { 240 if (severity != null) { 241 return severity; 242 } 243 244 LogRecord [] anns = (arrAll != null) ? arrAll : arr; 245 for (int i = 0; i < anns.length; i++) { 246 Level s = anns[i].getLevel(); 247 if (severity == null || s.intValue() > severity.intValue()) { 248 severity = s; 249 } 250 } 251 252 if (severity == null || severity == Level.ALL) { 253 severity = t instanceof Error ? Level.SEVERE : Level.WARNING; 255 } 256 257 return severity; 258 } 259 260 261 Date getDate() { 262 if (d == null) { 263 d = (Date )find(4); 264 } 265 return d; 266 } 267 268 void printStackTrace(PrintStream ps) { 269 printStackTrace(new PrintWriter (new OutputStreamWriter (ps))); 270 } 271 274 void printStackTrace(PrintWriter pw) { 275 printStackTrace(pw, new HashSet <Throwable >(10)); 277 } 278 279 private void printStackTrace(PrintWriter pw, Set <Throwable > nestingCheck) { 280 if (t != null && !nestingCheck.add(t)) { 281 Logger l = Logger.getAnonymousLogger(); 283 l.warning("WARNING - ErrorManager detected cyclic exception nesting:"); Iterator it = nestingCheck.iterator(); 285 while (it.hasNext()) { 286 Throwable t = (Throwable )it.next(); 287 l.warning("\t" + t); LogRecord [] anns = findAnnotations(t, null); 289 if (anns != null) { 290 for (int i = 0; i < anns.length; i++) { 291 Throwable t2 = anns[i].getThrown(); 292 if (t2 != null) { 293 l.warning("\t=> " + t2); } 295 } 296 } 297 } 298 l.warning("Be sure not to annotate an exception with itself, directly or indirectly."); return; 300 } 301 314 315 for (int i = 0; i < arr.length; i++) { 316 if (arr[i] == null) continue; 317 318 Throwable thr = arr[i].getThrown(); 319 String annotation = NbErrorManager.getLocalizedMessage(arr[i]); 320 321 if (annotation == null) annotation = arr[i].getMessage(); 322 326 327 if (annotation != null) { 328 if (thr == null) { 329 pw.println("Annotation: "+annotation); } 331 } 333 } 334 335 if (t instanceof VirtualMachineError ) { 339 t.printStackTrace(pw); 342 } else { 343 StackTraceElement [] tStack = t.getStackTrace(); 346 StackTraceElement [] hereStack = new Throwable ().getStackTrace(); 347 int idx = -1; 348 for (int i = 1; i <= Math.min(tStack.length, hereStack.length); i++) { 349 if (!tStack[tStack.length - i].equals(hereStack[hereStack.length - i])) { 350 idx = tStack.length - i + 1; 351 break; 352 } 353 } 354 String [] tLines = decompose(t); 355 for (int i = 0; i < tLines.length; i++) { 356 if (i == idx) { 357 pw.print("[catch]"); if (tLines[i].charAt(0) == '\t') { 361 pw.print(' '); 362 tLines[i] = tLines[i].substring(1); 363 } 364 } 365 pw.println(tLines[i]); 366 } 367 } 368 369 for (int i = 0; i < arr.length; i++) { 370 if (arr[i] == null) continue; 371 372 Throwable thr = arr[i].getThrown(); 373 if (thr != null) { 374 LogRecord [] ans = findAnnotations(thr, null); 375 Exc ex = new Exc(thr, null, ans, null); 376 pw.println("==>"); ex.printStackTrace(pw, nestingCheck); 378 } 379 } 380 } 381 382 383 private String [] decompose(Throwable t) { 384 StringWriter sw = new StringWriter (); 385 t.printStackTrace(new PrintWriter (sw)); 386 return sw.toString().split("(\r\n?|\n)($|(?=\\s*at ))"); } 388 389 396 private Object find(int kind) { 397 return find(kind, true); 398 } 399 400 407 private Object find(int kind, boolean def) { 408 for (int i = 0; i < arr.length; i++) { 409 LogRecord a = arr[i]; 410 411 Object o = null; 412 switch (kind) { 413 case 1: o = a.getMessage(); break; 415 case 2: o = NbErrorManager.getLocalizedMessage(a); break; 417 case 3: { 419 Throwable t = a.getThrown(); 420 o = t == null ? null : t.getClass().getName(); 421 break; 422 } 423 case 4: o = new Date (a.getMillis()); break; 425 } 426 427 if (o != null) { 428 return o; 429 } 430 } 431 432 if (!def) 433 return null; 434 switch (kind) { 435 case 1: return t.getMessage(); 437 case 2: return t.getLocalizedMessage(); 439 case 3: return t.getClass().getName(); 441 case 4: return new Date (); 443 default: 444 throw new IllegalArgumentException ( 445 "Unknown " + Integer.valueOf(kind) ); 447 } 448 } 449 } 450 451 } 452 | Popular Tags |