| 1 33 package net.sf.jga.swing; 34 35 import java.awt.Event ; 36 import java.io.Serializable ; 37 import java.lang.ref.Reference ; 38 import java.lang.ref.WeakReference ; 39 import java.lang.reflect.InvocationHandler ; 40 import java.lang.reflect.InvocationTargetException ; 41 import java.lang.reflect.Method ; 42 import java.lang.reflect.Proxy ; 43 import java.util.Collections ; 44 import java.util.EventListener ; 45 import java.util.HashMap ; 46 import java.util.HashSet ; 47 import java.util.Iterator ; 48 import java.util.Map ; 49 import java.util.Set ; 50 import java.util.WeakHashMap ; 51 import net.sf.jga.algorithms.Filter; 52 import net.sf.jga.fn.BinaryFunctor; 53 import net.sf.jga.fn.UnaryFunctor; 54 import net.sf.jga.parser.GenericParser; 55 import net.sf.jga.parser.ParseException; 56 import net.sf.jga.parser.UncheckedParseException; 57 58 66 67 public class FunctorProxy { 68 69 74 static public Proxy makeListenerFor(Object obj) { 75 return newProxyInstance(obj.getClass().getClassLoader(), identifyListeners(obj.getClass())); 76 } 77 78 79 83 static public Proxy newProxyInstance(ClassLoader loader, Class [] interfaces) { 84 return (Proxy ) Proxy.newProxyInstance(loader, interfaces, 85 new FunctorInvocationHandler(interfaces)); 86 } 87 88 92 101 static public void register(Proxy proxy, String methodName, String expression) 102 throws ParseException, NoSuchMethodException  103 { 104 getFunctorInvocationHandler(proxy).register(methodName, expression); 105 } 106 107 108 116 static public void register(Proxy proxy, String methodName, UnaryFunctor functor) 117 throws NoSuchMethodException  118 { 119 getFunctorInvocationHandler(proxy).register(methodName, functor); 120 } 121 122 123 127 static public void register(Proxy proxy, Method method, UnaryFunctor functor) { 128 getFunctorInvocationHandler(proxy).register(method, functor); 129 } 130 131 132 139 static public void register(Proxy proxy, Class listenerClass, Class eventClass, 140 String methodName, UnaryFunctor functor) 141 throws NoSuchMethodException , IllegalArgumentException  142 { 143 if (listenerClass.isInstance(proxy)) { 144 Method m = listenerClass.getMethod(methodName, new Class []{eventClass}); 145 getFunctorInvocationHandler(proxy).register(m, functor); 146 return; 147 } 148 149 throw new IllegalArgumentException ("This does not implement " +listenerClass.getName()); 150 } 151 152 153 157 158 static private Map <Class <?>,WeakReference > proxyClasses = 160 Collections.synchronizedMap(new WeakHashMap <Class <?>,WeakReference >()); 161 162 163 static private final UnaryFunctor<Method ,Boolean > isAddListenerMethod = 165 GenericParser.parse("x.getName().matches(\"^add.*Listener$\")", Method .class, Boolean .class); 166 167 171 static private Class [] identifyListeners(Class <?> clasz) { 172 synchronized (proxyClasses) { 173 Object value = proxyClasses.get(clasz); 175 if (value instanceof Reference ) { 176 return (Class []) ((Reference ) value).get(); 177 } 178 179 Set <Class <?>> interfaceSet = new HashSet <Class <?>>(); 183 184 Iterator <Method > iter = Filter.filter(clasz.getMethods(),isAddListenerMethod).iterator(); 186 while(iter.hasNext()) { 187 Method m = iter.next(); 188 Class [] argtypes = m.getParameterTypes(); 189 if (argtypes.length == 1) { 190 Class c = m.getParameterTypes()[0]; 191 if (EventListener .class.isAssignableFrom(c)) { 192 interfaceSet.add(c); 193 } 194 } 195 } 196 197 Class [] interfaceArray = interfaceSet.toArray(new Class [interfaceSet.size()]); 199 proxyClasses.put(clasz, new WeakReference (interfaceArray)); 200 return interfaceArray; 201 } 202 } 203 204 205 209 static private FunctorInvocationHandler getFunctorInvocationHandler(Proxy proxy) { 210 return (FunctorInvocationHandler) Proxy.getInvocationHandler(proxy); 211 } 212 213 214 221 static public class FunctorInvocationHandler implements InvocationHandler , Serializable { 222 223 static final long serialVersionUID = -6537167128759416788L; 224 225 private Class [] _interfaces; 227 228 private Map <Method ,UnaryFunctor> _functors = new HashMap <Method ,UnaryFunctor>(); 230 231 static private final BinaryFunctor<Method ,String ,Boolean > isNameEq = 233 GenericParser.parse("x.getName() == y", Method .class, String .class, Boolean .class); 234 235 private FunctorInvocationHandler(Class [] interfaces) { 236 _interfaces = interfaces; 237 } 238 239 240 244 private Method getMethod(String name) throws NoSuchMethodException { 245 UnaryFunctor<Method ,Boolean > hasGivenName = isNameEq.bind2nd(name); 246 247 250 for (int i = 0; i < _interfaces.length; ++i) { 252 Class iface = _interfaces[i]; 253 254 Iterator <Method > iter = Filter.filter(iface.getMethods(), hasGivenName).iterator(); 256 if(iter.hasNext()) { 257 return iter.next(); 258 } 259 } 260 261 throw new NoSuchMethodException (name); 262 } 263 264 265 273 private void register(String methodName, String expression) 274 throws ParseException, NoSuchMethodException  275 { 276 Method m = getMethod(methodName); 277 UnaryFunctor fn = 278 GenericParser.parse(expression, m.getParameterTypes()[0], m.getReturnType()); 279 280 register(m, fn); 281 } 282 283 284 291 private void register(String methodName, UnaryFunctor functor) 292 throws NoSuchMethodException  293 { 294 Method m = getMethod(methodName); 295 register(m, functor); 296 } 297 298 299 302 private void register(Method method, UnaryFunctor functor) { 303 _functors.put(method, functor); 304 } 305 306 307 309 private void unregister(Method method) { 310 _functors.remove(method); 311 } 312 313 314 316 private UnaryFunctor getFunctor(Method method){ 317 return _functors.get(method); 318 } 319 320 324 326 public Object invoke(Object object, Method method, Object [] objectArray) throws Throwable { 327 UnaryFunctor functor = getFunctor(method); 328 if (functor != null) { 329 functor.fn(objectArray[0]); 330 } 331 332 return null; 333 } 334 } 335 } 336 | Popular Tags |