rlm@10
|
1 /**
|
rlm@10
|
2 * Copyright (c) Rich Hickey. All rights reserved.
|
rlm@10
|
3 * The use and distribution terms for this software are covered by the
|
rlm@10
|
4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
rlm@10
|
5 * which can be found in the file epl-v10.html at the root of this distribution.
|
rlm@10
|
6 * By using this software in any fashion, you are agreeing to be bound by
|
rlm@10
|
7 * the terms of this license.
|
rlm@10
|
8 * You must not remove this notice, or any other, from this software.
|
rlm@10
|
9 **/
|
rlm@10
|
10
|
rlm@10
|
11 /* rich Oct 4, 2007 */
|
rlm@10
|
12
|
rlm@10
|
13 package clojure.lang;
|
rlm@10
|
14
|
rlm@10
|
15 import java.lang.reflect.InvocationHandler;
|
rlm@10
|
16 import java.lang.reflect.Method;
|
rlm@10
|
17
|
rlm@10
|
18 public class ProxyHandler implements InvocationHandler{
|
rlm@10
|
19 //method-name-string->fn
|
rlm@10
|
20 final IPersistentMap fns;
|
rlm@10
|
21
|
rlm@10
|
22
|
rlm@10
|
23 public ProxyHandler(IPersistentMap fns){
|
rlm@10
|
24 this.fns = fns;
|
rlm@10
|
25 }
|
rlm@10
|
26
|
rlm@10
|
27 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
|
rlm@10
|
28 Class rt = method.getReturnType();
|
rlm@10
|
29 IFn fn = (IFn) fns.valAt(method.getName());
|
rlm@10
|
30 if(fn == null)
|
rlm@10
|
31 {
|
rlm@10
|
32 if(rt == Void.TYPE)
|
rlm@10
|
33 return null;
|
rlm@10
|
34 else if(method.getName().equals("equals"))
|
rlm@10
|
35 {
|
rlm@10
|
36 return proxy == args[0];
|
rlm@10
|
37 }
|
rlm@10
|
38 else if(method.getName().equals("hashCode"))
|
rlm@10
|
39 {
|
rlm@10
|
40 return System.identityHashCode(proxy);
|
rlm@10
|
41 }
|
rlm@10
|
42 else if(method.getName().equals("toString"))
|
rlm@10
|
43 {
|
rlm@10
|
44 return "Proxy: " + System.identityHashCode(proxy);
|
rlm@10
|
45 }
|
rlm@10
|
46 throw new UnsupportedOperationException();
|
rlm@10
|
47 }
|
rlm@10
|
48 Object ret = fn.applyTo(ArraySeq.create(args));
|
rlm@10
|
49 if(rt == Void.TYPE)
|
rlm@10
|
50 return null;
|
rlm@10
|
51 else if(rt.isPrimitive())
|
rlm@10
|
52 {
|
rlm@10
|
53 if(rt == Character.TYPE)
|
rlm@10
|
54 return ret;
|
rlm@10
|
55 else if(rt == Integer.TYPE)
|
rlm@10
|
56 return ((Number) ret).intValue();
|
rlm@10
|
57 else if(rt == Long.TYPE)
|
rlm@10
|
58 return ((Number) ret).longValue();
|
rlm@10
|
59 else if(rt == Float.TYPE)
|
rlm@10
|
60 return ((Number) ret).floatValue();
|
rlm@10
|
61 else if(rt == Double.TYPE)
|
rlm@10
|
62 return ((Number) ret).doubleValue();
|
rlm@10
|
63 else if(rt == Boolean.TYPE && !(ret instanceof Boolean))
|
rlm@10
|
64 return ret == null ? Boolean.FALSE : Boolean.TRUE;
|
rlm@10
|
65 else if(rt == Byte.TYPE)
|
rlm@10
|
66 return (byte) ((Number) ret).intValue();
|
rlm@10
|
67 else if(rt == Short.TYPE)
|
rlm@10
|
68 return (short) ((Number) ret).intValue();
|
rlm@10
|
69 }
|
rlm@10
|
70 return ret;
|
rlm@10
|
71 }
|
rlm@10
|
72 }
|