From 308cbbe7be5a020b654771ea07ff07f13475793a Mon Sep 17 00:00:00 2001 From: megacz Date: Fri, 30 Jan 2004 07:39:20 +0000 Subject: [PATCH] 2003/10/15 21:43:01 darcs-hash:20040130073920-2ba56-d99d1c0281bd262b3956403fe9f23a5eea20ca03.gz --- src/org/xwt/Res.java | 11 +++++++++++ src/org/xwt/XWT.java | 9 +++++++++ src/org/xwt/js/JS.java | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/org/xwt/Res.java b/src/org/xwt/Res.java index 228b289..896220b 100644 --- a/src/org/xwt/Res.java +++ b/src/org/xwt/Res.java @@ -143,6 +143,7 @@ public abstract class Res extends JS { public Res graft(Object newResource) { return new Graft(parent, key, newResource); } } + // FEATURE: eliminate code duplication with JS.Graft /** shadow resource which replaces the graft */ public static class Graft extends Res { Res graftee; @@ -155,6 +156,16 @@ public abstract class Res extends JS { public Object get(Object key) { return replaced_key.equals(key) ? replaced_val : graftee.get(key); } public String getDescriptiveName() { return graftee.getDescriptiveName(); } public Res getParent() { return graftee.getParent(); } + public Object callMethod(Object method, Array args, boolean checkOnly) throws JS.Exn { + if (!replaced_key.equals(method)) return graftee.callMethod(method, args, checkOnly); + if (replaced_val instanceof Callable) return checkOnly ? Boolean.TRUE : ((Callable)replaced_val).call(args); + if (checkOnly) return Boolean.FALSE; + throw new JS.Exn("attempt to call non-function"); + } + public Number coerceToNumber() { return graftee.coerceToNumber(); } + public String coerceToString() { return graftee.coerceToString(); } + public boolean coerceToBoolean() { return graftee.coerceToBoolean(); } + public String typeName() { return graftee.typeName(); } } /** shadow resource which replaces the graft */ diff --git a/src/org/xwt/XWT.java b/src/org/xwt/XWT.java index f5e11c4..9fa97b8 100644 --- a/src/org/xwt/XWT.java +++ b/src/org/xwt/XWT.java @@ -71,6 +71,15 @@ public final class XWT extends JS.Obj { if (checkOnly) return Boolean.TRUE; return new XWT((Res)args.elementAt(0)); + } else if (method.equals("graft")) { + if (checkOnly) return Boolean.TRUE; + if (args.elementAt(0) instanceof Box) throw new JS.Exn("can't graft onto Boxes (yet)"); + if (args.elementAt(0) instanceof Number) throw new JS.Exn("can't graft onto Numbers (yet)"); + if (args.elementAt(0) instanceof String) throw new JS.Exn("can't graft onto Strings (yet)"); + if (args.elementAt(0) instanceof Res) + return new Res.Graft((Res)args.elementAt(0), args.elementAt(1), args.elementAt(2)); + return new JS.Graft((JS)args.elementAt(0), args.elementAt(1), args.elementAt(2)); + } else if (method.equals("watchProgress")) { if (checkOnly) return Boolean.TRUE; return new Res.ProgressWatcher((Res)args.elementAt(0), (JS.Callable)args.elementAt(1)); diff --git a/src/org/xwt/js/JS.java b/src/org/xwt/js/JS.java index 2ed9755..885d840 100644 --- a/src/org/xwt/js/JS.java +++ b/src/org/xwt/js/JS.java @@ -156,6 +156,43 @@ public abstract class JS { public void declare(String s) { super.declare(s); } } + /** the result of a graft */ + public static class Graft extends JS { + private JS graftee; + private Object replaced_key; + private Object replaced_val; + public Graft(JS graftee, Object key, Object val) { + if (graftee instanceof Array) throw new JS.Exn("can't graft onto Arrays (yet)"); + if (graftee instanceof Callable) throw new JS.Exn("can't graft onto Callables (yet)"); + if (graftee instanceof Scope) throw new JS.Exn("can't graft onto Scopes (yet)"); + this.graftee = graftee; + replaced_key = key; + replaced_val = val; + } + public boolean equals(Object o) { return (this == o || graftee.equals(o)); } + 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 callMethod(Object method, Array args, boolean checkOnly) throws JS.Exn { + if (!replaced_key.equals(method)) return graftee.callMethod(method, args, checkOnly); + if (replaced_val instanceof Callable) return checkOnly ? Boolean.TRUE : ((Callable)replaced_val).call(args); + if (checkOnly) return Boolean.FALSE; + throw new JS.Exn("attempt to call non-function"); + } + public Number coerceToNumber() { return graftee.coerceToNumber(); } + public String coerceToString() { return graftee.coerceToString(); } + public boolean coerceToBoolean() { return graftee.coerceToBoolean(); } + public String typeName() { return graftee.typeName(); } + public Object[] keys() { + Object[] ret = graftee.keys(); + for(int i=0; i