1 // Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
4 import org.ibex.util.*;
7 import java.lang.reflect.*;
9 /** Automatic JS-ification via Reflection (not for use in the core) */
10 public class JSReflection extends JS {
12 public static JS wrap(Object o) throws JSExn {
13 if (o == null) return null;
14 if (o instanceof String) return JS.S((String)o);
15 if (o instanceof Boolean) return JS.B(((Boolean)o).booleanValue());
16 if (o instanceof Number) return JS.N((Number)o);
17 if (o instanceof JS) return (JS)o;
18 if (o instanceof Object[]) {
19 // FIXME: get element type here
21 throw new JSExn("Reflection object tried to return a " + o.getClass().getName());
24 public static class Array extends JS {
26 public Array(Object[] arr) { this.arr = arr; }
27 // FEATURE: Add a JSCounterEnumeration
28 public Enumeration keys() throws JSExn {
29 return new Enumeration(null) {
31 public boolean _hasMoreElements() { return n < arr.length; }
32 public JS _nextElement() {
33 return n >= arr.length ? null : JS.N(n++);
37 public JS get(JS key) throws JSExn { return wrap(arr[toInt(key)]); }
38 public void put(JS key, JS val) throws JSExn { throw new JSExn("can't write to org.ibex.js.Reflection.Array's"); }
41 // FIXME public static class Hash { }
42 // FIXME public Enumeration keys() throws JSExn { }
44 public JS get(JS key) throws JSExn {
45 String k = toString(key);
47 Field f = this.getClass().getField(k);
48 return wrap(f.get(this));
49 } catch (NoSuchFieldException nfe) {
50 } catch (IllegalAccessException nfe) {
51 } catch (SecurityException nfe) { }
54 Method[] methods = this.getClass().getMethods();
55 for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(k)) return METHOD;
56 } catch (SecurityException nfe) { }
60 public void put(JS key, JS val) throws JSExn {
61 throw new JSExn("put() not supported yet");
64 public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
65 String k = toString(method);
67 Method[] methods = this.getClass().getMethods();
68 for(int j=0; j<methods.length; j++) {
69 if (methods[j].getName().equals(k) && methods[j].getParameterTypes().length == nargs) {
70 Object[] args = new Object[nargs];
71 for(int i = 0; i<args.length; i++) {
72 if (i==0) args[i] = a0;
73 else if (i==1) args[i] = a1;
74 else if (i==2) args[i] = a2;
75 else args[i] = rest[i-3];
77 return wrap(methods[j].invoke(this, args));
80 } catch (IllegalAccessException nfe) {
81 } catch (InvocationTargetException it) {
82 Throwable ite = it.getTargetException();
83 if (ite instanceof JSExn) throw ((JSExn)ite);
85 throw new JSExn("unhandled reflected exception: " + ite.toString());
86 } catch (SecurityException nfe) { }
87 throw new JSExn("called a reflection method with the wrong number of arguments");