1 19 package org.openide.util; 20 21 import java.util.logging.Logger ; 22 import org.openide.filesystems.*; 23 import org.openide.nodes.*; 24 25 import java.awt.event.FocusEvent ; 26 import java.awt.event.FocusListener ; 27 28 import java.beans.*; 29 30 import java.lang.ref.*; 31 import java.lang.reflect.*; 32 33 import java.util.EventListener ; 34 import java.util.EventObject ; 35 import java.util.logging.Level ; 36 37 import javax.swing.event.*; 38 39 40 44 public abstract class WeakListener implements java.util.EventListener { 45 46 private Reference ref; 47 48 49 Class listenerClass; 50 51 52 private Reference source; 53 54 59 protected WeakListener(Class listenerClass, java.util.EventListener l) { 60 this.listenerClass = listenerClass; 61 ref = new ListenerReference(l, this); 62 63 if (!listenerClass.isAssignableFrom(l.getClass())) { 64 throw new IllegalArgumentException ( 65 getClass().getName() + " constructor is calling WeakListner.<init> with illegal arguments" 66 ); } 68 } 69 70 86 protected final void setSource(Object source) { 87 if (source == null) { 88 this.source = null; 89 } else { 90 this.source = new WeakReference(source); 91 } 92 } 93 94 98 protected abstract String removeMethodName(); 99 100 104 protected final java.util.EventListener get(java.util.EventObject ev) { 105 Object l = ref.get(); 107 if (l == null) { 109 removeListener((ev == null) ? null : ev.getSource()); 110 } 111 112 return (EventListener ) l; 113 } 114 115 121 private void removeListener(Object eventSource) { 122 Object [] params = new Object [] { getImplementator() }; 123 Object src = (source == null) ? null : source.get(); 124 125 try { 126 Method m = null; 127 128 if (src != null) { 129 m = getRemoveMethod(src.getClass(), removeMethodName(), listenerClass); 130 131 if (m != null) { 132 m.invoke(src, params); 133 } 134 } 135 136 if ((eventSource != src) && (eventSource != null)) { 137 m = getRemoveMethod(eventSource.getClass(), removeMethodName(), listenerClass); 138 139 if (m != null) { 140 m.invoke(eventSource, params); 141 } 142 } 143 144 if ((m == null) && (source == null)) { Logger.getAnonymousLogger().warning( 146 "Can't remove " + listenerClass.getName() + " using method " + removeMethodName() + " source=" + source + ", SRC=" + src + ", eventSource=" + eventSource 150 ); } 152 } catch (Exception ex) { Logger.getLogger(WeakListener.class.getName()).log(Level.WARNING, null, ex); 154 } 155 } 156 157 158 private static final Method getRemoveMethod(Class methodClass, String methodName, Class listenerClass) { 159 final Class [] clarray = new Class [] { listenerClass }; 160 Method m = null; 161 162 try { 163 m = methodClass.getMethod(methodName, clarray); 164 } catch (NoSuchMethodException e) { 165 do { 166 try { 167 m = methodClass.getDeclaredMethod(methodName, clarray); 168 } catch (NoSuchMethodException ex) { 169 } 170 171 methodClass = methodClass.getSuperclass(); 172 } while ((m == null) && (methodClass != Object .class)); 173 } 174 175 if ( 176 (m != null) && 177 (!Modifier.isPublic(m.getModifiers()) || !Modifier.isPublic(m.getDeclaringClass().getModifiers())) 178 ) { 179 m.setAccessible(true); 180 } 181 182 return m; 183 } 184 185 Object getImplementator() { 186 return this; 187 } 188 189 public String toString() { 190 Object listener = ref.get(); 191 192 return getClass().getName() + "[" + ((listener == null) ? "null" : (listener.getClass().getName() + "]")); 193 } 194 195 199 207 public static NodeListener node(NodeListener l, Object source) { 208 WeakListener.Node wl = new WeakListener.Node(l); 209 wl.setSource(source); 210 211 return wl; 212 } 213 214 222 public static PropertyChangeListener propertyChange(PropertyChangeListener l, Object source) { 223 WeakListener.PropertyChange wl = new WeakListener.PropertyChange(l); 224 wl.setSource(source); 225 226 return wl; 227 } 228 229 237 public static VetoableChangeListener vetoableChange(VetoableChangeListener l, Object source) { 238 WeakListener.VetoableChange wl = new WeakListener.VetoableChange(l); 239 wl.setSource(source); 240 241 return wl; 242 } 243 244 252 public static FileChangeListener fileChange(FileChangeListener l, Object source) { 253 WeakListener.FileChange wl = new WeakListener.FileChange(l); 254 wl.setSource(source); 255 256 return wl; 257 } 258 259 267 public static FileStatusListener fileStatus(FileStatusListener l, Object source) { 268 WeakListener.FileStatus wl = new WeakListener.FileStatus(l); 269 wl.setSource(source); 270 271 return wl; 272 } 273 274 281 public static RepositoryListener repository(RepositoryListener l, Object source) { 282 WeakListener.Repository wl = new WeakListener.Repository(l); 283 wl.setSource(source); 284 285 return wl; 286 } 287 288 296 public static DocumentListener document(DocumentListener l, Object source) { 297 WeakListener.Document wl = new WeakListener.Document(l); 298 wl.setSource(source); 299 300 return wl; 301 } 302 303 311 public static ChangeListener change(ChangeListener l, Object source) { 312 WeakListener.Change wl = new WeakListener.Change(l); 313 wl.setSource(source); 314 315 return wl; 316 } 317 318 326 public static FocusListener focus(FocusListener l, Object source) { 327 WeakListener.Focus wl = new WeakListener.Focus(l); 328 wl.setSource(source); 329 330 return wl; 331 } 332 333 346 public static EventListener create(Class lType, EventListener l, Object source) { 347 ProxyListener pl = new ProxyListener(lType, l); 348 pl.setSource(source); 349 350 return (EventListener ) pl.proxy; 351 } 352 353 356 public static class PropertyChange extends WeakListener implements PropertyChangeListener { 357 360 public PropertyChange(PropertyChangeListener l) { 361 super(PropertyChangeListener.class, l); 362 } 363 364 368 PropertyChange(Class clazz, PropertyChangeListener l) { 369 super(clazz, l); 370 } 371 372 376 public void propertyChange(PropertyChangeEvent ev) { 377 PropertyChangeListener l = (PropertyChangeListener) super.get(ev); 378 379 if (l != null) { 380 l.propertyChange(ev); 381 } 382 } 383 384 388 protected String removeMethodName() { 389 return "removePropertyChangeListener"; } 391 } 392 393 396 public static class VetoableChange extends WeakListener implements VetoableChangeListener { 397 400 public VetoableChange(VetoableChangeListener l) { 401 super(VetoableChangeListener.class, l); 402 } 403 404 408 public void vetoableChange(PropertyChangeEvent ev) 409 throws PropertyVetoException { 410 VetoableChangeListener l = (VetoableChangeListener) super.get(ev); 411 412 if (l != null) { 413 l.vetoableChange(ev); 414 } 415 } 416 417 421 protected String removeMethodName() { 422 return "removeVetoableChangeListener"; } 424 } 425 426 429 public static class FileChange extends WeakListener implements FileChangeListener { 430 433 public FileChange(FileChangeListener l) { 434 super(FileChangeListener.class, l); 435 } 436 437 443 public void fileFolderCreated(FileEvent ev) { 444 FileChangeListener l = (FileChangeListener) super.get(ev); 445 446 if (l != null) { 447 l.fileFolderCreated(ev); 448 } 449 } 450 451 457 public void fileDataCreated(FileEvent ev) { 458 FileChangeListener l = (FileChangeListener) super.get(ev); 459 460 if (l != null) { 461 l.fileDataCreated(ev); 462 } 463 } 464 465 468 public void fileChanged(FileEvent ev) { 469 FileChangeListener l = (FileChangeListener) super.get(ev); 470 471 if (l != null) { 472 l.fileChanged(ev); 473 } 474 } 475 476 479 public void fileDeleted(FileEvent ev) { 480 FileChangeListener l = (FileChangeListener) super.get(ev); 481 482 if (l != null) { 483 l.fileDeleted(ev); 484 } 485 } 486 487 491 public void fileRenamed(FileRenameEvent ev) { 492 FileChangeListener l = (FileChangeListener) super.get(ev); 493 494 if (l != null) { 495 l.fileRenamed(ev); 496 } 497 } 498 499 503 public void fileAttributeChanged(FileAttributeEvent ev) { 504 FileChangeListener l = (FileChangeListener) super.get(ev); 505 506 if (l != null) { 507 l.fileAttributeChanged(ev); 508 } 509 } 510 511 515 protected String removeMethodName() { 516 return "removeFileChangeListener"; } 518 } 519 520 523 public static class FileStatus extends WeakListener implements FileStatusListener { 524 526 public FileStatus(FileStatusListener l) { 527 super(FileStatusListener.class, l); 528 } 529 530 533 public void annotationChanged(FileStatusEvent ev) { 534 FileStatusListener l = (FileStatusListener) super.get(ev); 535 536 if (l != null) { 537 l.annotationChanged(ev); 538 } 539 } 540 541 545 protected String removeMethodName() { 546 return "removeFileStatusListener"; } 548 } 549 550 553 public static class Repository extends WeakListener implements RepositoryListener { 554 557 public Repository(RepositoryListener l) { 558 super(RepositoryListener.class, l); 559 } 560 561 564 public void fileSystemAdded(RepositoryEvent ev) { 565 RepositoryListener l = (RepositoryListener) super.get(ev); 566 567 if (l != null) { 568 l.fileSystemAdded(ev); 569 } 570 } 571 572 575 public void fileSystemRemoved(RepositoryEvent ev) { 576 RepositoryListener l = (RepositoryListener) super.get(ev); 577 578 if (l != null) { 579 l.fileSystemRemoved(ev); 580 } 581 } 582 583 584 public void fileSystemPoolReordered(RepositoryReorderedEvent ev) { 585 RepositoryListener l = (RepositoryListener) super.get(ev); 586 587 if (l != null) { 588 l.fileSystemPoolReordered(ev); 589 } 590 } 591 592 596 protected String removeMethodName() { 597 return "removeRepositoryListener"; } 599 } 600 601 606 public static final class Document extends WeakListener implements DocumentListener { 607 610 public Document(final DocumentListener l) { 611 super(DocumentListener.class, l); 612 } 613 614 617 public void changedUpdate(DocumentEvent ev) { 618 final DocumentListener l = docGet(ev); 619 620 if (l != null) { 621 l.changedUpdate(ev); 622 } 623 } 624 625 628 public void insertUpdate(DocumentEvent ev) { 629 final DocumentListener l = docGet(ev); 630 631 if (l != null) { 632 l.insertUpdate(ev); 633 } 634 } 635 636 639 public void removeUpdate(DocumentEvent ev) { 640 final DocumentListener l = docGet(ev); 641 642 if (l != null) { 643 l.removeUpdate(ev); 644 } 645 } 646 647 651 protected String removeMethodName() { 652 return "removeDocumentListener"; } 654 655 659 private DocumentListener docGet(DocumentEvent ev) { 660 DocumentListener l = (DocumentListener) super.ref.get(); 661 662 if (l == null) { 663 super.removeListener(ev.getDocument()); 664 } 665 666 return l; 667 } 668 } 669 671 676 public static final class Change extends WeakListener implements ChangeListener { 677 680 public Change(ChangeListener l) { 681 super(ChangeListener.class, l); 682 } 683 684 687 public void stateChanged(final ChangeEvent ev) { 688 ChangeListener l = (ChangeListener) super.get(ev); 689 690 if (l != null) { 691 l.stateChanged(ev); 692 } 693 } 694 695 699 protected String removeMethodName() { 700 return "removeChangeListener"; } 702 } 703 704 709 public static final class Node extends WeakListener.PropertyChange implements NodeListener { 710 713 public Node(NodeListener l) { 714 super(NodeListener.class, l); 715 } 716 717 719 public void childrenAdded(NodeMemberEvent ev) { 720 NodeListener l = (NodeListener) super.get(ev); 721 722 if (l != null) { 723 l.childrenAdded(ev); 724 } 725 } 726 727 729 public void childrenRemoved(NodeMemberEvent ev) { 730 NodeListener l = (NodeListener) super.get(ev); 731 732 if (l != null) { 733 l.childrenRemoved(ev); 734 } 735 } 736 737 739 public void childrenReordered(NodeReorderEvent ev) { 740 NodeListener l = (NodeListener) super.get(ev); 741 742 if (l != null) { 743 l.childrenReordered(ev); 744 } 745 } 746 747 749 public void nodeDestroyed(NodeEvent ev) { 750 NodeListener l = (NodeListener) super.get(ev); 751 752 if (l != null) { 753 l.nodeDestroyed(ev); 754 } 755 } 756 757 761 protected String removeMethodName() { 762 return "removeNodeListener"; } 764 } 765 766 771 public static final class Focus extends WeakListener implements FocusListener { 772 775 public Focus(FocusListener l) { 776 super(FocusListener .class, l); 777 } 778 779 781 public void focusGained(FocusEvent ev) { 782 FocusListener l = (FocusListener ) super.get(ev); 783 784 if (l != null) { 785 l.focusGained(ev); 786 } 787 } 788 789 791 public void focusLost(FocusEvent ev) { 792 FocusListener l = (FocusListener ) super.get(ev); 793 794 if (l != null) { 795 l.focusLost(ev); 796 } 797 } 798 799 803 protected String removeMethodName() { 804 return "removeFocusListener"; } 806 } 807 808 810 private static class ProxyListener extends WeakListener implements InvocationHandler { 811 812 private static Method equalsMth; 813 814 815 public final Object proxy; 816 817 819 public ProxyListener(Class c, java.util.EventListener listener) { 820 super(c, listener); 821 822 proxy = Proxy.newProxyInstance(c.getClassLoader(), new Class [] { c }, this); 823 } 824 825 826 private static Method getEquals() { 827 if (equalsMth == null) { 828 try { 829 equalsMth = Object .class.getMethod("equals", new Class [] { Object .class }); } catch (NoSuchMethodException e) { 831 e.printStackTrace(); 832 } 833 } 834 835 return equalsMth; 836 } 837 838 public java.lang.Object invoke(Object proxy, Method method, Object [] args) 839 throws Throwable { 840 if (method.getDeclaringClass() == Object .class) { 841 if (method == getEquals()) { 843 boolean ret = equals(args[0]); 844 845 return (ret ? Boolean.TRUE : Boolean.FALSE); 846 } 847 848 return method.invoke(this, args); 849 } 850 851 EventObject ev = (args[0] instanceof EventObject ) ? (EventObject ) args[0] : null; 853 854 Object listener = super.get(ev); 855 856 if (listener != null) { 857 return method.invoke(listener, args); 858 } else { 859 return null; 860 } 861 } 862 863 865 protected String removeMethodName() { 866 String name = listenerClass.getName(); 867 868 int dot = name.lastIndexOf('.'); 870 name = name.substring(dot + 1); 871 872 int i = name.lastIndexOf('$'); 876 if (i >= 0) { 877 name = name.substring(i + 1); 878 } 879 880 return "remove".concat(name); } 882 883 885 public String toString() { 886 return super.toString() + "[" + listenerClass + "]"; } 888 889 891 public boolean equals(Object obj) { 892 return (proxy == obj) || (this == obj); 893 } 894 895 Object getImplementator() { 896 return proxy; 897 } 898 } 899 900 902 private static final class ListenerReference extends WeakReference implements Runnable { 903 private static Class lastClass; 904 private static String lastMethodName; 905 private static Method lastRemove; 906 private static Object LOCK = new Object (); 907 final WeakListener weakListener; 908 909 public ListenerReference(Object ref, WeakListener weakListener) { 910 super(ref, Utilities.activeReferenceQueue()); 911 this.weakListener = weakListener; 912 } 913 914 public void run() { 915 ListenerReference lr = this; 916 917 Object [] params = new Object [1]; 919 Class [] types = new Class [1]; 920 Object src = null; Method remove = null; 922 923 WeakListener ref = lr.weakListener; 924 925 if ((ref.source == null) || ((src = ref.source.get()) == null)) { 926 return; 927 } 928 929 Class methodClass = src.getClass(); 930 String methodName = ref.removeMethodName(); 931 932 synchronized (LOCK) { 933 if ((lastClass == methodClass) && (lastMethodName == methodName) && (lastRemove != null)) { 934 remove = lastRemove; 935 } 936 } 937 938 if (remove == null) { 940 types[0] = ref.listenerClass; 941 remove = getRemoveMethod(methodClass, methodName, types[0]); 942 943 if (remove == null) { 944 Logger.getAnonymousLogger().warning( 945 "Can't remove " + ref.listenerClass.getName() + " using method " + methodName + " from " + src 948 ); 950 return; 951 } else { 952 synchronized (LOCK) { 953 lastClass = methodClass; 954 lastMethodName = methodName; 955 lastRemove = remove; 956 } 957 } 958 } 959 960 params[0] = ref.getImplementator(); 962 try { 963 remove.invoke(src, params); 964 } catch (Exception ex) { Exceptions.attachLocalizedMessage(ex, 966 "Problem encountered while calling " + 967 methodClass + "." + methodName + 968 "(...) on " + src); Logger.getAnonymousLogger().log(Level.WARNING, null, ex); 970 } 971 } 972 } 973 } 974 | Popular Tags |