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[]) {
20 throw new JSExn("Reflection onto Object[] not supported yet");
22 throw new JSExn("Reflection object tried to return a " + o.getClass().getName());
25 public static class Array extends JS.Immutable {
27 public Array(Object[] arr) { this.arr = arr; }
28 // FEATURE: Add a JSCounterEnumeration
29 public Enumeration keys() throws JSExn {
30 return new Enumeration(null) {
32 public boolean _hasNext() { return n < arr.length; }
33 public JS _next() { return JSU.N(n++); }
36 public JS get(JS key) throws JSExn { return wrap(arr[JSU.toInt(key)]); }
39 public Enumeration keys() throws JSExn { throw new JSExn("JSReflection.keys() not supported yet"); }
41 public JS get(JS key) throws JSExn {
42 String k = JSU.toString(key);
43 Class c = this.getClass();
46 Field f = c.getField(k);
47 if (f != null) return wrap(f.get(this));
48 } catch (NoSuchFieldException nfe) {
49 } catch (IllegalAccessException nfe) {
50 } catch (SecurityException nfe) { }
51 c = c.getSuperclass();
55 java.lang.reflect.Method[] methods = this.getClass().getMethods();
56 for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(k)) return METHOD;
57 } catch (SecurityException nfe) { }
61 public void put(JS key, JS val) throws JSExn {
62 throw new JSExn("put() not supported yet");
65 public JS call(JS method, JS[] args) throws JSExn {
66 String k = JSU.toString(method);
68 java.lang.reflect.Method[] methods = this.getClass().getMethods();
69 for(int j=0; j<methods.length; j++) {
70 if (methods[j].getName().equals(k) &&
71 methods[j].getParameterTypes().length == args.length) {
72 return wrap(methods[j].invoke(this, (Object[])args));
75 } catch (IllegalAccessException nfe) {
76 } catch (InvocationTargetException it) {
77 Throwable ite = it.getTargetException();
78 if (ite instanceof JSExn) throw ((JSExn)ite);
80 throw new JSExn("unhandled reflected exception: " + ite.toString());
81 } catch (SecurityException nfe) { }
82 throw new JSExn("called a reflection method with the wrong number of arguments");