view src/clojure/lang/ProxyHandler.java @ 10:ef7dbbd6452c

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