added JSReflection.Wrap
authoradam <adam@megacz.com>
Fri, 25 Mar 2005 06:30:12 +0000 (06:30 +0000)
committeradam <adam@megacz.com>
Fri, 25 Mar 2005 06:30:12 +0000 (06:30 +0000)
darcs-hash:20050325063012-5007d-9bb43298a2a96dee9616073bda6838881a178f14.gz

src/org/ibex/js/JSReflection.java

index 2f163e7..d9c241f 100644 (file)
@@ -16,10 +16,56 @@ public class JSReflection extends JS.Immutable {
         if (o instanceof Boolean) return JSU.B(((Boolean)o).booleanValue());
         if (o instanceof Number) return JSU.N((Number)o);
         if (o instanceof JS) return (JS)o;
-        if (o instanceof Object[]) {
-            throw new JSExn("Reflection onto Object[] not supported yet");
+        if (o instanceof Object[]) throw new JSExn("Reflection onto Object[] not supported yet");
+        return new Wrapper(o);
+    }
+
+    public static class Wrapper extends JS.Immutable {
+        private final Object o;
+        public Wrapper(Object o) { this.o = o; }
+        public Object unwrap() { return o; }
+        public Enumeration keys() throws JSExn { throw new JSExn("JSReflection.keys() not supported yet"); }
+        public JS get(JS key) throws JSExn {
+            String k = JSU.toString(key);
+            Class c = o.getClass();
+            while(c != null) {
+                try {
+                    Field f = c.getField(k);
+                    if (f != null) return wrap(f.get(o));
+                } catch (NoSuchFieldException nfe) {
+                } catch (IllegalAccessException nfe) {
+                } catch (SecurityException nfe) { }
+                c = c.getSuperclass();
+            }
+            
+            try {
+                java.lang.reflect.Method[] methods = o.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(JS key, JS val) throws JSExn { throw new JSExn("put() not supported yet"); }
+        
+        public JS call(JS method, JS[] args) throws JSExn {
+            String k = JSU.toString(method);
+            try {
+                java.lang.reflect.Method[] methods = o.getClass().getMethods();
+                for(int j=0; j<methods.length; j++) {
+                    if (methods[j].getName().equals(k) &&
+                        methods[j].getParameterTypes().length == args.length) {
+                        return wrap(methods[j].invoke(o, (Object[])args));
+                    }
+                }
+            } catch (IllegalAccessException nfe) {
+            } catch (InvocationTargetException it) {
+                Throwable ite = it.getTargetException();
+                if (ite instanceof JSExn) throw ((JSExn)ite);
+                JSU.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");
         }
-        throw new JSExn("Reflection object tried to return a " + o.getClass().getName());
     }
 
     public static class Array extends JS.Immutable {