1 19 20 package org.openide; 21 22 import java.io.IOException ; 23 import java.io.PrintStream ; 24 import java.io.PrintWriter ; 25 import java.io.StringWriter ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.Enumeration ; 29 import java.util.HashSet ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.ResourceBundle ; 34 import java.util.Set ; 35 import java.util.WeakHashMap ; 36 import java.util.concurrent.Callable ; 37 import java.util.logging.Level ; 38 import java.util.logging.LogRecord ; 39 import java.util.logging.Logger ; 40 import org.openide.util.Enumerations; 41 import org.openide.util.Lookup; 42 import org.openide.util.LookupEvent; 43 import org.openide.util.LookupListener; 44 import org.openide.util.WeakSet; 45 46 232 public abstract class ErrorManager extends Object { 233 236 241 public static final int UNKNOWN = 0x00000000; 242 243 244 public static final int INFORMATIONAL = 0x00000001; 245 246 247 public static final int WARNING = 0x00000010; 248 249 250 public static final int USER = 0x00000100; 251 252 253 public static final int EXCEPTION = 0x00001000; 254 255 256 public static final int ERROR = 0x00010000; 257 258 259 private static DelegatingErrorManager current; 260 261 265 public static ErrorManager getDefault() { 266 synchronized (ErrorManager.class) { 267 if (current != null) { 268 return current; 269 } 270 } 271 272 return getDefaultDelegate(); 273 } 274 275 private static DelegatingErrorManager getDefaultDelegate() { 276 DelegatingErrorManager c = new DelegatingErrorManager(""); 278 try { 279 c.initialize(); 280 281 synchronized (ErrorManager.class) { 282 if (current == null) { 283 current = c; 284 285 current.r.addLookupListener(current); 287 } 288 } 289 } catch (RuntimeException e) { 290 e.printStackTrace(); 292 current = c; 293 } catch (LinkageError e) { 294 e.printStackTrace(); 296 current = c; 297 } 298 299 return current; 300 } 301 302 308 public abstract Throwable attachAnnotations(Throwable t, Annotation[] arr); 309 310 314 public abstract Annotation[] findAnnotations(Throwable t); 315 316 329 public abstract Throwable annotate( 330 Throwable t, int severity, String message, String localizedMessage, Throwable stackTrace, java.util.Date date 331 ); 332 333 340 public abstract void notify(int severity, Throwable t); 341 342 348 public final void notify(Throwable t) { 349 notify(UNKNOWN, t); 350 } 351 352 356 public abstract void log(int severity, String s); 357 359 363 public final void log(String s) { 364 log(INFORMATIONAL, s); 366 } 367 368 377 public boolean isLoggable(int severity) { 378 return true; 380 } 381 382 395 public boolean isNotifiable(int severity) { 396 return isLoggable(severity); 397 } 398 399 413 public abstract ErrorManager getInstance(String name); 414 415 419 428 public final Throwable annotate(Throwable t, String localizedMessage) { 429 return annotate(t, UNKNOWN, null, localizedMessage, null, null); 430 } 431 432 443 public final Throwable annotate(Throwable target, Throwable t) { 444 return annotate(target, UNKNOWN, null, null, t, null); 445 } 446 447 462 @Deprecated 463 public final Throwable copyAnnotation(Throwable t, Throwable copyFrom) { 464 466 475 return annotate(t, UNKNOWN, null, null, copyFrom, null); 476 477 480 } 481 482 484 public static interface Annotation { 485 488 public abstract String getMessage(); 489 490 493 public abstract String getLocalizedMessage(); 494 495 500 public abstract Throwable getStackTrace(); 501 502 505 public abstract java.util.Date getDate(); 506 507 511 public abstract int getSeverity(); 512 } 513 515 519 private static class DelegatingErrorManager extends ErrorManager implements LookupListener { 520 private String name = null; 521 522 525 private Set delegates = new HashSet (); 526 527 528 private Logger logger; 529 530 534 private WeakSet<DelegatingErrorManager> createdByMe = new WeakSet<DelegatingErrorManager>(); 535 536 540 Lookup.Result<ErrorManager> r; 541 542 public DelegatingErrorManager(String name) { 543 this.name = name; 544 } 545 546 548 Logger logger() { 549 if (logger == null) { 550 logger = Logger.getLogger(this.name); 551 } 552 return logger; 553 } 554 555 558 public ErrorManager getInstance(String name) { 559 if ((name == null) || ("".equals(name))) { 561 return this; 562 } 563 564 DelegatingErrorManager dem = new DelegatingErrorManager(name); 565 566 synchronized (this) { 567 attachNewDelegates(dem, name); 568 createdByMe.add(dem); 569 } 570 571 return dem; 572 } 573 574 575 public Throwable attachAnnotations(Throwable t, Annotation[] arr) { 576 for (Iterator i = delegates.iterator(); i.hasNext();) { 577 ErrorManager em = (ErrorManager) i.next(); 578 em.attachAnnotations(t, arr); 579 } 580 581 return t; 582 } 583 584 585 public Annotation[] findAnnotations(Throwable t) { 586 for (Iterator i = delegates.iterator(); i.hasNext();) { 587 ErrorManager em = (ErrorManager) i.next(); 588 Annotation[] res = em.findAnnotations(t); 589 590 if ((res != null) && (res.length > 0)) { 591 return res; 592 } 593 } 594 595 return new Annotation[0]; 596 } 597 598 599 public Throwable annotate( 600 Throwable t, int severity, String message, final String localizedMessage, Throwable stackTrace, 601 java.util.Date date 602 ) { 603 if (delegates.isEmpty()) { 604 LogRecord rec = new LogRecord (convertSeverity(severity, true, Level.ALL), message); 605 if (stackTrace != null) { 606 rec.setThrown(stackTrace); 607 } 608 if (date != null) { 609 rec.setMillis(date.getTime()); 610 } 611 if (localizedMessage != null) { 612 ResourceBundle rb = new ResourceBundle () { 613 public Object handleGetObject(String key) { 614 if ("msg".equals(key)) { return localizedMessage; 616 } else { 617 return null; 618 } 619 } 620 621 public Enumeration <String > getKeys() { 622 return Enumerations.singleton("msg"); } 624 }; 625 rec.setResourceBundle(rb); 626 rec.setMessage("msg"); } 628 629 AnnException ann = AnnException.findOrCreate(t, true); 630 ann.addRecord(rec); 631 632 return t; 633 } 634 635 for (Iterator i = delegates.iterator(); i.hasNext();) { 636 ErrorManager em = (ErrorManager) i.next(); 637 em.annotate(t, severity, message, localizedMessage, stackTrace, date); 638 } 639 640 return t; 641 } 642 643 644 public void notify(int severity, Throwable t) { 645 if (delegates.isEmpty()) { 646 if (enterLogger()) return; 647 try { 648 AnnException ext = AnnException.extras.get(t); 649 if (ext != null) { 650 t = ext; 651 } 652 logger().log(convertSeverity(severity, true, OwnLevel.UNKNOWN), t.getMessage(), t); 653 } finally { 654 exitLogger(); 655 } 656 return; 657 } 658 659 try { 660 for (Iterator i = delegates.iterator(); i.hasNext();) { 661 ErrorManager em = (ErrorManager) i.next(); 662 em.notify(severity, t); 663 } 664 } catch (RuntimeException e) { 665 e.printStackTrace(); 667 t.printStackTrace(); 668 } catch (LinkageError e) { 669 e.printStackTrace(); 671 t.printStackTrace(); 672 } 673 } 674 675 676 public void log(int severity, String s) { 677 if (severity == UNKNOWN) { 678 throw new IllegalArgumentException ("ErrorManager.log(UNKNOWN, ...) is not permitted"); } 680 681 if (delegates.isEmpty()) { 682 Level sev = convertSeverity(severity, false, Level.FINE); 683 if (enterLogger()) return; 684 try { 685 logger().log(sev, s); 686 } finally { 687 exitLogger(); 688 } 689 return; 690 } 691 692 for (Iterator i = delegates.iterator(); i.hasNext();) { 693 ErrorManager em = (ErrorManager) i.next(); 694 em.log(severity, s); 695 } 696 } 697 698 private static Level convertSeverity(final int severity, boolean forException, Level def) { 699 Level sev = def; 700 701 if (severity >= ERROR) { 702 sev = Level.SEVERE; 703 } else if (severity >= EXCEPTION) { 704 sev = Level.SEVERE; 705 } else if (severity >= USER) { 706 sev = OwnLevel.USER; 707 } else if (severity >= WARNING) { 708 sev = Level.WARNING; 709 } else if (severity >= INFORMATIONAL) { 710 sev = forException ? Level.INFO: Level.FINE; 711 } 712 return sev; 713 } 714 715 716 public boolean isLoggable(int severity) { 717 if (severity == UNKNOWN) { 718 throw new IllegalArgumentException ("ErrorManager.isLoggable(UNKNOWN) is not permitted"); } 720 721 if (delegates.isEmpty()) { 722 return logger().isLoggable(convertSeverity(severity, false, null)); 723 } 724 725 for (Iterator i = delegates.iterator(); i.hasNext();) { 726 ErrorManager em = (ErrorManager) i.next(); 727 728 if (em.isLoggable(severity)) { 729 return true; 730 } 731 } 732 733 return false; 734 } 735 736 737 public boolean isNotifiable(int severity) { 738 if (severity == UNKNOWN) { 739 throw new IllegalArgumentException ("ErrorManager.isNotifiable(UNKNOWN) is not permitted"); } 741 742 if (delegates.isEmpty()) { 743 return logger().isLoggable(convertSeverity(severity, true, null)); 744 } 745 746 for (Iterator i = delegates.iterator(); i.hasNext();) { 747 ErrorManager em = (ErrorManager) i.next(); 748 749 if (em.isNotifiable(severity)) { 750 return true; 751 } 752 } 753 754 return false; 755 } 756 757 761 public synchronized void setDelegates(Collection <? extends ErrorManager> newDelegates) { 762 java.util.LinkedHashSet <ErrorManager> d; 763 d = new java.util.LinkedHashSet <ErrorManager>(newDelegates); 764 delegates = d; 765 766 for (Iterator i = createdByMe.iterator(); i.hasNext();) { 767 DelegatingErrorManager dem = (DelegatingErrorManager) i.next(); 768 attachNewDelegates(dem, dem.getName()); 769 } 770 } 771 772 private String getName() { 773 return name; 774 } 775 776 782 private void attachNewDelegates(DelegatingErrorManager dem, String name) { 783 Set <ErrorManager> newDelegatesForDem = new HashSet <ErrorManager>(); 784 785 for (Iterator j = delegates.iterator(); j.hasNext();) { 786 ErrorManager e = (ErrorManager) j.next(); 787 newDelegatesForDem.add(e.getInstance(name)); 788 } 789 790 dem.setDelegates(newDelegatesForDem); 791 } 792 793 796 public void initialize() { 797 r = Lookup.getDefault().lookup(new Lookup.Template<ErrorManager>(ErrorManager.class)); 798 setDelegates(r.allInstances()); 799 } 800 801 802 public void resultChanged(LookupEvent ev) { 803 if (r != null) { 804 setDelegates(r.allInstances()); 805 } 806 } 807 808 private static volatile Thread lastThread; 809 private static boolean enterLogger() { 810 if (lastThread == Thread.currentThread()) { 811 new Exception ("using error manager from inside a logger").printStackTrace(); return true; 813 } 814 lastThread = Thread.currentThread(); 815 return false; 816 } 817 818 private static void exitLogger() { 819 lastThread = null; 820 } 821 } 822 823 826 private static final class AnnException extends Exception implements Callable <LogRecord []> { 827 private List <LogRecord > records; 828 829 private static Map <Throwable , AnnException> extras = new WeakHashMap <Throwable , AnnException>(); 830 831 public String getMessage() { 832 StringBuilder sb = new StringBuilder (); 833 String sep = ""; 834 for (LogRecord r : records) { 835 if (r.getMessage() != null) { 836 sb.append(sep); 837 sb.append(r.getMessage()); 838 sep = "\n"; 839 } 840 } 841 return sb.toString(); 842 } 843 844 static AnnException findOrCreate(Throwable t, boolean create) { 845 if (t instanceof AnnException) { 846 return (AnnException)t; 847 } 848 if (t.getCause() == null) { 849 if (create) { 850 try { 851 t.initCause(new AnnException()); 852 } catch (IllegalStateException x) { 853 AnnException ann = extras.get(t); 854 if (ann == null) { 855 ann = new AnnException(); 856 ann.initCause(t); 857 Logger.getLogger(ErrorManager.class.getName()).log(Level.FINE, "getCause was null yet initCause failed for " + t, x); 858 extras.put(t, ann); 859 } 860 return ann; 861 } 862 } 863 return (AnnException)t.getCause(); 864 } 865 return findOrCreate(t.getCause(), create); 866 } 867 868 private AnnException() { 869 } 870 871 public synchronized void addRecord(LogRecord rec) { 872 if (records == null) { 873 records = new ArrayList <LogRecord >(); 874 } 875 records.add(rec); 876 } 877 878 public LogRecord [] call() { 879 List <LogRecord > r = records; 880 LogRecord [] empty = new LogRecord [0]; 881 return r == null ? empty : r.toArray(empty); 882 } 883 884 public void printStackTrace(PrintStream s) { 885 super.printStackTrace(s); 886 logRecords(s); 887 } 888 889 public void printStackTrace(PrintWriter s) { 890 super.printStackTrace(s); 891 logRecords(s); 892 } 893 894 public void printStackTrace() { 895 printStackTrace(System.err); 896 } 897 898 private void logRecords(Appendable a) { 899 List <LogRecord > r = records; 900 if (r == null) { 901 return; 902 } 903 try { 904 905 for (LogRecord log : r) { 906 if (log.getMessage() != null) { 907 a.append(log.getMessage()).append("\n");; 908 } 909 if (log.getThrown() != null) { 910 StringWriter w = new StringWriter (); 911 log.getThrown().printStackTrace(new PrintWriter (w)); 912 a.append(w.toString()).append("\n"); 913 } 914 } 915 } catch (IOException ex) { 916 ex.printStackTrace(); 917 } 918 } 919 } 921 private static final class OwnLevel extends Level { 922 public static final Level USER = new OwnLevel("USER", 1973); public static final Level UNKNOWN = new OwnLevel("SEVERE", Level.SEVERE.intValue() + 1); 925 private OwnLevel(String s, int i) { 926 super(s, i); 927 } 928 } } 930 | Popular Tags |