added org.ibex.js.JSReflection
authoradam <adam@megacz.com>
Sun, 2 May 2004 08:10:40 +0000 (08:10 +0000)
committeradam <adam@megacz.com>
Sun, 2 May 2004 08:10:40 +0000 (08:10 +0000)
darcs-hash:20040502081040-5007d-9673391116d491a39b6e40eb388f4878f0c5640b.gz

src/org/ibex/js/JSReflection.java [new file with mode: 0644]

diff --git a/src/org/ibex/js/JSReflection.java b/src/org/ibex/js/JSReflection.java
new file mode 100644 (file)
index 0000000..070a35b
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL] 
+package org.ibex.js; 
+
+import org.ibex.util.*; 
+import java.io.*;
+import java.util.*;
+import java.lang.reflect.*;
+
+/** Automatic JS-ification via Reflection (not for use in the core) */
+public class JSReflection extends JS {
+
+    public static Object wrap(Object o) throws JSExn {
+        if (o instanceof String) return o;
+        if (o instanceof Boolean) return o;
+        if (o instanceof Number) return o;
+        if (o instanceof JS) return o;
+        if (o instanceof Object[]) {
+            // FIXME: get element type here
+        }
+        throw new JSExn("Reflection object tried to return a " + o.getClass().getName());
+    }
+
+    public static class Array extends JS {
+        final Object[] arr;
+        public Array(Object[] arr) { this.arr = arr; }
+        public Enumeration keys() throws JSExn { return new CounterEnumeration(arr.length); }
+        public Object get(Object key) throws JSExn { return wrap(arr[toInt(key)]); }
+        public void put(Object key, Object val) throws JSExn { throw new JSExn("can't write to org.ibex.js.Reflection.Array's"); }
+    }
+
+    // FIXME public static class Hash { }
+    // FIXME public Enumeration keys() throws JSExn {  }
+
+    public Object get(Object key) throws JSExn {
+        String k = toString(key);
+        try {
+            Field f = this.getClass().getField(k);
+            return wrap(f.get(this));
+        } catch (NoSuchFieldException nfe) {
+        } catch (IllegalAccessException nfe) {
+        } catch (SecurityException nfe) { }
+
+        try {
+            Method[] methods = this.getClass().getMethods();
+            for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(k)) return METHOD;
+        } catch (SecurityException nfe) { }
+        return null;
+    }
+
+    public void put(Object key, Object val) throws JSExn {
+        throw new JSExn("put() not supported yet");
+    }
+
+    public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+        String k = toString(method);
+        try {
+            Method[] methods = this.getClass().getMethods();
+            for(int j=0; j<methods.length; j++) {
+                if (methods[j].getName().equals(k) && methods[j].getParameterTypes().length == nargs) {
+                    Object[] args = new Object[nargs];
+                    for(int i = 0; i<args.length; i++) {
+                        if (i==0) args[i] = a0;
+                        else if (i==1) args[i] = a1;
+                        else if (i==2) args[i] = a2;
+                        else args[i] = rest[i-3];
+                    }
+                    return wrap(methods[j].invoke(this, args));
+                }
+            }
+        } catch (IllegalAccessException nfe) {
+        } catch (InvocationTargetException it) {
+            Throwable ite = it.getTargetException();
+            if (ite instanceof JSExn) throw ((JSExn)ite);
+            JS.warn(ite);
+            throw new JSExn("unhandled reflected exception: " + ite.toString());
+        } catch (SecurityException nfe) { }
+        throw new JSExn("called a reflection method with the wrong number of arguments");
+    }    
+}