1 4 package com.tc.object.tx; 5 6 import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArrayList; 7 8 import com.tc.util.Assert; 9 10 import java.lang.reflect.Method ; 11 import java.util.Collection ; 12 import java.util.IdentityHashMap ; 13 import java.util.Iterator ; 14 import java.util.Map ; 15 16 22 public class ChangeListenerCollection implements Collection { 23 private final Collection listeners = new CopyOnWriteArrayList(); 24 private final String callbackMethod; 25 private final Map methodRefs = new IdentityHashMap (); 26 private final Class [] callbackSignature; 27 28 public static class NoSuchCallbackException extends RuntimeException { 29 public NoSuchCallbackException(String msg) { 30 super(msg); 31 } 32 } 33 34 public ChangeListenerCollection(String callbackMethod) { 35 super(); 36 Assert.assertNotNull("callbackmethod", callbackMethod); 37 this.callbackMethod = callbackMethod; 38 this.callbackSignature = new Class [] { Iterator .class }; 39 } 40 41 public synchronized boolean add(Object obj) { 42 if (obj == null) { throw new NullPointerException ("null not permitted in change listener collection"); } 43 findCallback(obj); 44 return listeners.add(obj); 45 } 46 47 private Method findCallback(Object o) { 48 53 Assert.assertNotNull(o); 54 55 if (!methodRefs.containsKey(o)) { 56 try { 57 Method method = o.getClass().getDeclaredMethod(callbackMethod, callbackSignature); 58 method.setAccessible(true); 59 methodRefs.put(o, method); 60 } catch (Exception e) { 61 throw new NoSuchCallbackException(e.getClass().getName() + " occured trying to locate callback method named " 63 + callbackMethod + " on class " + o.getClass()); 64 } 65 } 66 67 return (Method ) methodRefs.get(o); 68 } 69 70 public boolean addAll(Collection c) { 71 throw new UnsupportedOperationException (); 72 } 73 74 public synchronized void clear() { 75 listeners.clear(); 76 methodRefs.clear(); 77 } 78 79 public boolean contains(Object o) { 80 return listeners.contains(o); 81 } 82 83 public boolean containsAll(Collection c) { 84 throw new UnsupportedOperationException (); 85 } 86 87 public boolean equals(Object obj) { 88 return this == obj; 89 } 90 91 public int hashCode() { 92 return listeners.hashCode(); 93 } 94 95 public boolean isEmpty() { 96 return listeners.isEmpty(); 97 } 98 99 public Iterator iterator() { 100 final Iterator internalIter = listeners.iterator(); 101 102 return new Iterator () { 103 public void remove() { 104 throw new UnsupportedOperationException (); 106 } 107 108 public boolean hasNext() { 109 return internalIter.hasNext(); 110 } 111 112 public Object next() { 113 return internalIter.next(); 114 } 115 }; 116 } 117 118 public synchronized boolean remove(Object o) { 119 if (null == o) { return false; } 120 methodRefs.remove(o); 121 return listeners.remove(o); 122 } 123 124 public boolean removeAll(Collection c) { 125 throw new UnsupportedOperationException (); 126 } 127 128 public boolean retainAll(Collection c) { 129 throw new UnsupportedOperationException (); 130 } 131 132 public int size() { 133 return listeners.size(); 134 } 135 136 public Object [] toArray() { 137 return listeners.toArray(); 138 } 139 140 public Object [] toArray(Object [] a) { 141 return listeners.toArray(a); 142 } 143 144 public String toString() { 145 StringBuffer buf = new StringBuffer ('['); 146 147 final Iterator iter = listeners.iterator(); 148 boolean hasNext = iter.hasNext(); 149 while (hasNext) { 150 Object obj = iter.next(); 151 buf.append(obj == this ? "(this collection)" : String.valueOf(obj)); 152 hasNext = iter.hasNext(); 153 if (hasNext) buf.append(", "); 154 } 155 156 return buf.append(']').toString(); 157 } 158 159 synchronized Method getCallbackFor(Object obj) { 160 Assert.assertNotNull(obj); 161 return (Method ) methodRefs.get(obj); 162 } 163 } | Popular Tags |