2003/11/17 01:53:25
[org.ibex.core.git] / src / org / xwt / js / JS.java
index f1f6726..327d35c 100644 (file)
@@ -11,7 +11,7 @@ import java.util.*;
  *  implementing the absolute minimal amount of functionality for an
  *  Object which can be manipulated by JavaScript code.
  */
-public abstract class JS { 
+public class JS { 
 
     // Public Helper Methods //////////////////////////////////////////////////////////////////////
 
@@ -74,10 +74,29 @@ public abstract class JS {
     
     // Instance Methods ////////////////////////////////////////////////////////////////////
  
-    public abstract Object get(Object key) throws JS.Exn; 
-    public void put(Object key, Object val) throws JS.Exn { throw new JS.Exn("you cannot put to this object"); }
+    // this gets around a wierd fluke in the Java type checking rules for ?..:
+    public static final Object T = Boolean.TRUE;
+    public static final Object F = Boolean.FALSE;
+
+    // FEATURE: be smart here; perhaps intern
+    public static final Number N(int i) { return new Integer(i); }
+    public static final Number N(long l) { return new Long(l); }
+    public static final Number N(double d) { return new Double(d); }
+    public static final Boolean B(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; }
+    
+    private static Enumeration emptyEnumeration = new Enumeration() {
+            public boolean hasMoreElements() { return false; }
+            public Object nextElement() { throw new NoSuchElementException(); }
+        };
+    
+    private Hash entries = null;
+    public Enumeration keys() { return entries == null ? emptyEnumeration : entries.keys(); }
+    public Object get(Object key) { return entries == null ? null : entries.get(key, null); }
+    public void put(Object key, Object val) { if (entries == null) entries = new Hash(); entries.put(key, null, val); }
 
-    public Enumeration keys() { throw new Error("you cannot apply for..in to a " + this.getClass().getName()); }
+    // note that we don't actually implement trappable... we just provide these for subclasses which choose to
+    public JSTrap getTrap(Object key) { return entries == null ? null : (JSTrap)entries.get(key, JSTrap.class); }
+    public void putTrap(Object key, JSTrap t) { if (entries == null) entries = new Hash(); entries.put(key, JSTrap.class, t); }
 
     public Number coerceToNumber() { throw new JS.Exn("tried to coerce a JavaScript object to a Number"); }
     public String coerceToString() { throw new JS.Exn("tried to coerce a JavaScript object to a String"); }
@@ -98,6 +117,7 @@ public abstract class JS {
     } 
 
     /** the result of a graft */
+    // FIXME: uber-broken
     public static class Graft extends JSCallable {
         private JS graftee;
         private Object replaced_key;
@@ -114,11 +134,13 @@ public abstract class JS {
         public int hashCode() { return graftee.hashCode(); }
         public Object get(Object key) { return replaced_key.equals(key) ? replaced_val : graftee.get(key); }
         public void put(Object key, Object val) { graftee.put(key, val); }
+        /*
         public Object call(Object method, JSArray args) {
             if (replaced_key.equals(method)) return ((JSCallable)replaced_val).call(null, args);
             else if (graftee instanceof JSCallable) return ((JSCallable)graftee).call(method, args);
             else throw new JS.Exn("cannot call this value");
         }
+        */
         public Number coerceToNumber() { return graftee.coerceToNumber(); }
         public String coerceToString() { return graftee.coerceToString(); }
         public boolean coerceToBoolean() { return graftee.coerceToBoolean(); }