1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
7 import java.lang.reflect.*;
9 /** Automatic JS-ification via Reflection (not for use in the core) */
10 public class JSReflection extends JS.Immutable {
11 private static final JS.Method METHOD = new JS.Method();
13 public static JS wrap(Object o) throws JSExn {
14 if (o == null) return null;
15 if (o instanceof String) return JSU.S((String)o);
16 if (o instanceof Boolean) return JSU.B(((Boolean)o).booleanValue());
17 if (o instanceof Number) return JSU.N((Number)o);
18 if (o instanceof JS) return (JS)o;
19 if (o instanceof Object[]) throw new JSExn("Reflection onto Object[] not supported yet");
20 return new Wrapper(o);
23 public static class Wrapper extends JS.Immutable {
24 private final Object o;
25 public Wrapper(Object o) { this.o = o; }
26 public Object unwrap() { return o; }
27 public Enumeration keys() throws JSExn { throw new JSExn("JSReflection.keys() not supported yet"); }
28 public JS get(JS key) throws JSExn {
29 String k = JSU.toString(key);
30 Class c = o.getClass();
33 Field f = c.getField(k);
34 if (f != null) return wrap(f.get(o));
35 } catch (NoSuchFieldException nfe) {
36 } catch (IllegalAccessException nfe) {
37 } catch (SecurityException nfe) { }
38 c = c.getSuperclass();
42 java.lang.reflect.Method[] methods = o.getClass().getMethods();
43 for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(k)) return METHOD;
44 } catch (SecurityException nfe) { }
48 public void put(JS key, JS val) throws JSExn { throw new JSExn("put() not supported yet"); }
50 public JS call(JS method, JS[] args) throws JSExn {
51 String k = JSU.toString(method);
53 java.lang.reflect.Method[] methods = o.getClass().getMethods();
54 for(int j=0; j<methods.length; j++) {
55 if (methods[j].getName().equals(k) &&
56 methods[j].getParameterTypes().length == args.length) {
57 return wrap(methods[j].invoke(o, (Object[])args));
60 } catch (IllegalAccessException nfe) {
61 } catch (InvocationTargetException it) {
62 Throwable ite = it.getTargetException();
63 if (ite instanceof JSExn) throw ((JSExn)ite);
65 throw new JSExn("unhandled reflected exception: " + ite.toString());
66 } catch (SecurityException nfe) { }
67 throw new JSExn("called a reflection method with the wrong number of arguments");
71 public static class Array extends JS.Immutable {
73 public Array(Object[] arr) { this.arr = arr; }
74 // FEATURE: Add a JSCounterEnumeration
75 public Enumeration keys() throws JSExn {
76 return new Enumeration(null) {
78 public boolean _hasNext() { return n < arr.length; }
79 public JS _next() { return JSU.N(n++); }
82 public JS get(JS key) throws JSExn { return wrap(arr[JSU.toInt(key)]); }
85 public Enumeration keys() throws JSExn { throw new JSExn("JSReflection.keys() not supported yet"); }
87 public JS get(JS key) throws JSExn {
88 String k = JSU.toString(key);
89 Class c = this.getClass();
92 Field f = c.getField(k);
93 if (f != null) return wrap(f.get(this));
94 } catch (NoSuchFieldException nfe) {
95 } catch (IllegalAccessException nfe) {
96 } catch (SecurityException nfe) { }
97 c = c.getSuperclass();
101 java.lang.reflect.Method[] methods = this.getClass().getMethods();
102 for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(k)) return METHOD;
103 } catch (SecurityException nfe) { }
107 public void put(JS key, JS val) throws JSExn {
108 throw new JSExn("put() not supported yet");
111 public JS call(JS method, JS[] args) throws JSExn {
112 String k = JSU.toString(method);
114 java.lang.reflect.Method[] methods = this.getClass().getMethods();
115 for(int j=0; j<methods.length; j++) {
116 if (methods[j].getName().equals(k) &&
117 methods[j].getParameterTypes().length == args.length) {
118 return wrap(methods[j].invoke(this, (Object[])args));
121 } catch (IllegalAccessException nfe) {
122 } catch (InvocationTargetException it) {
123 Throwable ite = it.getTargetException();
124 if (ite instanceof JSExn) throw ((JSExn)ite);
126 throw new JSExn("unhandled reflected exception: " + ite.toString());
127 } catch (SecurityException nfe) { }
128 throw new JSExn("called a reflection method with the wrong number of arguments");