-// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the GNU General Public License version 2 ("the License").
+// You may not use this file except in compliance with the License.
+
package org.ibex.core;
import java.io.*;
import org.ibex.crypto.*;
/** Singleton class that provides all functionality in the ibex.* namespace */
-public final class Ibex extends JS implements JS.Cloneable {
+public final class Ibex extends JS.Obj implements JS.Cloneable {
// FIXME remove this
private final JS rr;
+ private static final JS.Method METHOD = new JS.Method();
- public Ibex(Stream rr) { try { this.rr = bless(rr);} catch(JSExn e) { throw new Error("should never happen: " + e); } }
+ public Ibex(Fountain rr) { try { this.rr = bless(rr);} catch(JSExn e) { throw new Error("should never happen: " + e); } }
public JS resolveString(String str, boolean permitAbsolute) throws JSExn {
if (str.indexOf("://") != -1) {
while(str.indexOf('.') != -1) {
String path = str.substring(0, str.indexOf('.'));
str = str.substring(str.indexOf('.') + 1);
- ret = ret.get(JS.S(path));
+ ret = ret.get(JSU.S(path));
}
- if (!"".equals(str)) ret = ret.get(JS.S(str));
+ if (!"".equals(str)) ret = ret.get(JSU.S(str));
return ret;
}
/** lets us put multi-level get/put/call keys all in the same method */
- private class Sub extends JS {
+ private class Sub extends JS.Obj {
JS key;
Sub(JS key) { this.key = key; }
- public void put(JS key, JS val) throws JSExn { Ibex.this.put(JS.S(JS.toString(this.key) + "." + JS.toString(key)), val); }
- public JS get(JS key) throws JSExn { return Ibex.this.get(JS.S(JS.toString(this.key) + "." + JS.toString(key))); }
- public JS call(JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
- return Ibex.this.callMethod(this.key, a0, a1, a2, rest, nargs);
- }
- public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
- return Ibex.this.callMethod(JS.S(JS.toString(this.key) + "." + JS.toString(method)), a0, a1, a2, rest, nargs);
+ public void put(JS key, JS val) throws JSExn { Ibex.this.put(JSU.S(JSU.toString(this.key) + "." + JSU.toString(key)), val); }
+ public JS get(JS key) throws JSExn { return Ibex.this.get(JSU.S(JSU.toString(this.key) + "." + JSU.toString(key))); }
+ public JS call(JS method, JS[] args) throws JSExn {
+ if (method == null) return super.call(null, args);
+ return Ibex.this.call(JSU.S(JSU.toString(this.key) + "." + JSU.toString(method)), args);
}
}
- private Cache subCache = new Cache(20);
+ private Cache subCache = new Cache(20, true);
private Sub getSub(JS key) {
Sub ret = (Sub)subCache.get(key);
if (ret == null) subCache.put(key, ret = new Sub(key));
public JS get(JS name) throws JSExn {
// FIXME: SHouldn't need this (just trap [""])
- if (JS.isString(name) && JS.toString(name).length() == 0) return rr;
+ if (JSU.isString(name) && JSU.toString(name).length() == 0) return rr;
// FEATURE: Preprocessor hack to generate specialized JS instances (avoid all this string concatenation)
- //#jswitch(name)
+ //#switch(JSU.toString(name))
case "math": return ibexMath;
case "string": return ibexString;
case "date": return METHOD;
case "ui.font.wait": return METHOD;
case "ui.font.width": return METHOD;
case "ui.font.height": return METHOD;
- case "ui.font.sansserif": return Main.builtin.get(JS.S("fonts/vera/Vera.ttf"));
- case "ui.font.monospace": return Main.builtin.get(JS.S("fonts/vera/VeraMono.ttf"));
- case "ui.font.serif": return Main.builtin.get(JS.S("fonts/vera/VeraSe.ttf"));
+ case "ui.font.sansserif": return Main.vera;
+ case "ui.font.monospace": return Main.vera;
+ case "ui.font.serif": return Main.vera;
case "ui.browser": return METHOD;
case "ui.mouse": return getSub(name);
case "ui.mouse.button":
- if (Surface.button1 && !Surface.button2 && !Surface.button3) return N(1);
- else if (!Surface.button1 && Surface.button2 && !Surface.button3) return N(2);
- else if (!Surface.button1 && !Surface.button2 && Surface.button3) return N(3);
- else return ZERO;
+ if (Surface.button1 && !Surface.button2 && !Surface.button3) return JSU.N(1);
+ else if (!Surface.button1 && Surface.button2 && !Surface.button3) return JSU.N(2);
+ else if (!Surface.button1 && !Surface.button2 && Surface.button3) return JSU.N(3);
+ else return JSU.ZERO;
case "ui.key": return getSub(name);
case "ui.key.name": return getSub(name);
- case "ui.key.name.alt": return JS.S(Platform.altKeyName());
- case "ui.key.alt": return Surface.alt ? T : F;
- case "ui.key.control": return Surface.control ? T : F;
- case "ui.key.shift": return Surface.shift ? T : F;
- case "ui.clipboard": return JS.S((String)Platform.getClipBoard());
- case "ui.maxdim": return N(Short.MAX_VALUE);
+ case "ui.key.name.alt": return JSU.S(Platform.altKeyName());
+ case "ui.key.alt": return Surface.alt ? JSU.T : JSU.F;
+ case "ui.key.control": return Surface.control ? JSU.T : JSU.F;
+ case "ui.key.shift": return Surface.shift ? JSU.T : JSU.F;
+ case "ui.clipboard": return JSU.S((String)Platform.getClipBoard());
+ case "ui.maxdim": return JSU.N(Short.MAX_VALUE);
case "ui.screen": return getSub(name);
- case "ui.screen.width": return N(Platform.getScreenWidth());
- case "ui.screen.height": return N(Platform.getScreenHeight());
+ case "ui.screen.width": return JSU.N(Platform.getScreenWidth());
+ case "ui.screen.height": return JSU.N(Platform.getScreenHeight());
case "undocumented": return getSub(name);
- case "undocumented.initialOrigin": return JS.S(Main.origin);
- case "undocumented.initialTemplate": return JS.S(Main.initialTemplate);
+ case "undocumented.initialOrigin": return JSU.S(Main.origin);
+ case "undocumented.initialTemplate": return JSU.S(Main.initialTemplate);
case "thread": return getSub(name);
case "thread.yield": return METHOD;
case "thread.sleep": return METHOD;
}
public void put(JS name, JS value) throws JSExn {
- //#jswitch(name)
- case "thread": Scheduler.add((Task)value); return;
- case "ui.clipboard": Platform.setClipBoard(JS.toString(value)); return;
+ //#switch(JSU.toString(name))
+ case "thread": Platform.Scheduler.add((Callable)value); return;
+ case "ui.clipboard": Platform.setClipBoard(JSU.toString(value)); return;
case "ui.frame": Platform.createSurface((Box)value, true, true); return;
case "ui.window": Platform.createSurface((Box)value, false, true); return;
case "undocumented.proxyAuthorization":
throw new JSExn("attempted to put unknown property: ibex."+name);
}
- public JS callMethod(JS name, JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
+ public JS call(JS method, JS[] args) throws JSExn {
try {
- //#jswitch(name)
- case "date": return new JSDate(a, b, c, rest, nargs);
- case "net.rpc.soap": return new SOAP(JS.toString(a), "", JS.toString(b), JS.toString(c));
+ //#switch(JSU.toString(method))
+ case "date": return new JSDate(args);
+ case "net.rpc.soap": return new SOAP(
+ args.length < 1 ? null : JSU.toString(args[0]),
+ "",
+ args.length < 2 ? null : JSU.toString(args[1]),
+ args.length < 3 ? null : JSU.toString(args[2]));
// FIXME support object dumping
- case "log.debug": JS.debug(a== null ? "**null**" : JS.debugToString(a)); return null;
- case "log.info": JS.info(a== null ? "**null**" : JS.debugToString(a)); return null;
- case "log.warn": JS.warn(a== null ? "**null**" : JS.debugToString(a)); return null;
- case "log.error": JS.error(a== null ? "**null**" : JS.debugToString(a)); return null;
+ case "log.debug": JSU.debug(args.length < 1 ? "**null**" : JSU.str(args[0])); return null;
+ case "log.info": JSU.info(args.length < 1 ? "**null**" : JSU.str(args[0])); return null;
+ case "log.warn": JSU.warn(args.length < 1 ? "**null**" : JSU.str(args[0])); return null;
+ case "log.error": JSU.error(args.length < 1 ? "**null**" : JSU.str(args[0])); return null;
//#end
- switch (nargs) {
+ switch (args.length) {
case 0:
- //#jswitch(name)
+ //#switch(JSU.toString(method))
case "thread.yield": sleep(0); return null;
//#end
break;
case 1:
- //#jswitch(name)
+ //#switch(JSU.toString(method))
case "clone":
- if(a == null) throw new JSExn("can't clone the null value");
- return ((JS)a).jsclone();
- case "bless": return bless((JS)a);
- case "ui.browser": Platform.newBrowserWindow(JS.toString(a)); return null;
- case "stream.unzip": return a == null ? null : new Stream.Zip(a);
- case "stream.uncab": return a == null ? null : new Stream.Cab(a);
+ if(args[0] == null) throw new JSExn("can't clone the null value");
+ return new JS.Clone((JS)args[0]);
+ case "bless": return bless((JS)args[0]);
+ case "ui.browser": Platform.newBrowserWindow(JSU.toString(args[0])); return null;
+ case "stream.unzip": return args[0] == null ? null : new Fountain.Zip((Fountain)args[0]);
+ //case "stream.uncab": return a == null ? null : new Stream.Cab(a);
case "stream.cache":
- try { return a == null ? null : new Stream.CachedStream(a, "resources", true); }
- catch (Stream.NotCacheableException e) { throw new JSExn("this resource cannot be cached"); }
+ //try { return args[0] == null ? null : new Fountain.CachedStream((Stream)args[0], "resources", true); }
+ //catch (Stream.NotCacheableException e) { throw new JSExn("this resource cannot be cached"); }
case "stream.url": {
- String url = JS.toString(a);
- if (url.startsWith("http://")) return new Stream.HTTP(url);
- else if (url.startsWith("https://")) return new Stream.HTTP(url);
- else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
- else if (url.startsWith("utf8:")) return new Stream.ByteArray(url.substring(5).getBytes(), null);
+ String url = JSU.toString(args[0]);
+ if (url.startsWith("http://")) return new Fountain.HTTP(url);
+ else if (url.startsWith("https://")) return new Fountain.HTTP(url);
+ else if (url.startsWith("data:")) return new Fountain.ByteArray(Encode.fromBase64(url.substring(5)), null);
+ else if (url.startsWith("utf8:")) return new Fountain.ByteArray(url.substring(5).getBytes(), null);
else if (url.startsWith("file:")) {
// FIXME
Platform.fileDialog(url.substring(5), false);
}
throw new JSExn("invalid resource specifier " + url);
}
- case "thread.sleep": sleep(JS.toInt(a)); return null;
- case "regexp": return new JSRegexp(a, null);
- case "net.rpc.xml": return new XMLRPC(JS.toString(a), "");
+ case "thread.sleep": sleep(JSU.toInt(args[0])); return null;
+ case "regexp": return new JSRegexp(args[0], null);
+ case "net.rpc.xml": return new XMLRPC(JSU.toString(args[0]), "");
case "crypto.rsa": /* FEATURE */ return null;
case "crypto.md5": /* FEATURE */ return null;
case "crypto.sha1": /* FEATURE */ return null;
case "crypto.rc4": /* FEATURE */ return null;
case "stream.parse.html": throw new JSExn("not implemented yet"); //return null;
- case "stream.parse.xml": if(a == null) return null; new XMLHelper(b).doParse(a); return null;
+ case "stream.parse.xml": if(args[0] == null) return null; new XMLHelper(args[1]).doParse(args[0]); return null;
// FIXME backgrounding
- case "stream.parse.utf8": if(a == null) return null;
- try { return JS.S(new String(InputStreamToByteArray.convert(a.getInputStream()))); }
+ case "stream.parse.utf8": if(args[0] == null) return null;
+ try { return JSU.S(new String(InputStreamToByteArray.convert(JSU.getInputStream(args[0])))); }
catch (Exception e) { Log.warn(this, e); }
//#end
break;
case 2:
- //#jswitch(name)
- case "stream.watch": return new Stream.ProgressWatcher(a, b);
- case "regexp": return new JSRegexp(a, b);
+ //#switch(JSU.toString(method))
+ case "stream.watch":
+ final JS func = args[1];
+ return new Fountain.ProgressWatcher((Fountain)args[0],
+ new Callable() {
+ public Object run(Object o) throws Exception {
+ JS[] args = (JS[])o;
+ return func.call(null, args);
+ }
+ });
+ case "regexp": return new JSRegexp(args[0], args[1]);
//#end
case 3:
- //#jswitch(name)
- case "ui.font.height": return N(Font.getFont(a, JS.toInt(b)).textheight(JS.toString(c)));
+ //#switch(JSU.toString(method))
+ case "ui.font.height": return JSU.N(Font.getFont(args[0], JSU.toInt(args[1])).textheight(JSU.toString(args[3])));
case "ui.font.wait": throw new Error("FIXME: ibex.ui.font.wait not implemented");
- case "ui.font.width": return N(Font.getFont(a, JS.toInt(b)).textwidth(JS.toString(c)));
+ case "ui.font.width": return JSU.N(Font.getFont(args[0], JSU.toInt(args[1])).textwidth(JSU.toString(args[3])));
//#end
break;
}
} catch (RuntimeException e) {
// FIXME: maybe JSExn should take a second argument, Exception
- Log.warn(this, "ibex."+name+"() threw: " + e);
- throw new JSExn("invalid argument for ibex object method "+name+"()");
+ Log.warn(this, "ibex."+method+"() threw: " + e);
+ throw new JSExn("invalid argument for ibex object method "+method+"()");
}
- throw new JSExn("invalid number of arguments ("+nargs+") for ibex object method "+name+"()");
+ throw new JSExn("invalid number of arguments ("+args.length+") for ibex object method "+method+"()");
}
public JS url2res(String url) throws JSExn {
- if (url.startsWith("http://")) return new Stream.HTTP(url);
- else if (url.startsWith("https://")) return new Stream.HTTP(url);
- else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
- else if (url.startsWith("utf8:")) return new Stream.ByteArray(url.substring(5).getBytes(), null);
+ if (url.startsWith("http://")) return new Fountain.HTTP(url);
+ else if (url.startsWith("https://")) return new Fountain.HTTP(url);
+ else if (url.startsWith("data:")) return new Fountain.ByteArray(Encode.fromBase64(url.substring(5)), null);
+ else if (url.startsWith("utf8:")) return new Fountain.ByteArray(url.substring(5).getBytes(), null);
else throw new JSExn("invalid resource specifier " + url);
// FIXME support file:// via dialog boxes
}
public static void sleep(final int i) throws JSExn {
try {
- final JS.UnpauseCallback callback = JS.pause();
+ final Pausable callback = JSU.pause();
// FEATURE use a single sleeper thread
new Thread() { public void run() {
try { Thread.sleep(i); } catch (InterruptedException e) { }
- Scheduler.add(callback);
+ Platform.Scheduler.add(callback);
} }.start();
- } catch (JS.NotPauseableException npe) {
+ } catch (Pausable.NotPausableException npe) {
throw new JSExn("you cannot sleep or yield in the foreground thread");
}
}
- public static final JS ibexMath = new JS() {
+ public static final JS ibexMath = new JS.Immutable() {
// FEATURE: find a cleaner way to do this
private JS gs = /*new JSScope.Global();*/ null; // FIXME: Global scope
public JS get(JS key) throws JSExn {
- //#jswitch(key)
+ //#switch(JSU.toString(key))
case "isNaN": return METHOD;
case "isFinite": return METHOD;
case "NaN": return METHOD;
case "Infinity": return METHOD;
//#end
- return MATH.get(key);
+ return JSU.MATH.get(key);
}
- public JS callMethod(JS name, JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
- //#jswitch(name)
- case "isNaN": return gs.callMethod(name,a,b,c,rest,nargs);
- case "isFinite": return gs.callMethod(name,a,b,c,rest,nargs);
- case "NaN": return gs.callMethod(name,a,b,c,rest,nargs);
- case "Infinity": return gs.callMethod(name,a,b,c,rest,nargs);
+ public JS call(JS method, JS[] args) throws JSExn {
+ //#switch(JSU.toString(method))
+ case "isNaN": return gs.call(method, args);
+ case "isFinite": return gs.call(method, args);
+ case "NaN": return gs.call(method, args);
+ case "Infinity": return gs.call(method, args);
//#end
- return MATH.callMethod(name,a,b,c,rest,nargs);
+ return JSU.MATH.call(method, args);
}
};
- public static final JS ibexString = new JS() {
+ public static final JS ibexString = new JS.Obj() {
private JS gs = /*new JSScope.Global();*/ null; // FIXME: Global scope
public JS get(JS key) throws JSExn {
- //#jswitch(key)
+ //#switch(JSU.toString(key))
case "parseInt": return METHOD;
case "parseFloat": return METHOD;
case "decodeURI": return METHOD;
//#end
return super.get(key);
}
- public JS callMethod(JS name, JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
- //#jswitch(name)
- case "parseInt": return gs.callMethod(name,a,b,c,rest,nargs);
- case "parseFloat": return gs.callMethod(name,a,b,c,rest,nargs);
- case "decodeURI": return gs.callMethod(name,a,b,c,rest,nargs);
- case "decodeURIComponent": return gs.callMethod(name,a,b,c,rest,nargs);
- case "encodeURI": return gs.callMethod(name,a,b,c,rest,nargs);
- case "encodeURIComponent": return gs.callMethod(name,a,b,c,rest,nargs);
- case "escape": return gs.callMethod(name,a,b,c,rest,nargs);
- case "unescape": return gs.callMethod(name,a,b,c,rest,nargs);
- case "fromCharCode": return gs.callMethod(name,a,b,c,rest,nargs);
+ public JS callMethod(JS method, JS[] args) throws JSExn {
+ //#switch(JSU.toString(method))
+ case "parseInt": return gs.call(method, args);
+ case "parseFloat": return gs.call(method, args);
+ case "decodeURI": return gs.call(method, args);
+ case "decodeURIComponent": return gs.call(method, args);
+ case "encodeURI": return gs.call(method, args);
+ case "encodeURIComponent": return gs.call(method, args);
+ case "escape": return gs.call(method, args);
+ case "unescape": return gs.call(method, args);
+ case "fromCharCode": return gs.call(method, args);
//#end
- return super.callMethod(name,a,b,c,rest,nargs);
+ return super.call(method, args);
}
};
private class Wrapper extends XML.Exn { public JSExn wrapee; public Wrapper(JSExn jse) { super(""); wrapee = jse; } }
private JS characters, whitespace, endElement, startElement;
public XMLHelper(JS b) throws JSExn {
- super(BUFFER_SIZE);
- startElement = b.getAndTriggerTraps(JS.S("startElement"));
- endElement = b.getAndTriggerTraps(JS.S("endElement"));
- characters = b.getAndTriggerTraps(JS.S("characters"));
- whitespace = b.getAndTriggerTraps(JS.S("whitespace"));
+ super(BUFFER_SIZE, true);
+ startElement = b.getAndTriggerTraps(JSU.S("startElement"));
+ endElement = b.getAndTriggerTraps(JSU.S("endElement"));
+ characters = b.getAndTriggerTraps(JSU.S("characters"));
+ whitespace = b.getAndTriggerTraps(JSU.S("whitespace"));
}
- public void startElement(XML.Element c) throws XML.Exn { try {
- JS attrs = new JS.O();
+ private final JS[] callargs1= new JS[1], callargs2= new JS[2], callargs3= new JS[3];
+ public void startElement(Tree.Element c) throws XML.Exn { try {
+ Tree.Attributes a = c.getAttributes();
+ JS attrs = new JS.Obj();
// FIXME attribute URIs? add an additional hash?
- for(int i=0; i<c.getAttrLen(); i++) attrs.put(JS.S(c.getAttrKey(i)), JS.S(c.getAttrVal(i)));
- startElement.call(JS.S(c.getLocalName()), attrs, JS.S(c.getUri()), null, 3);
- } catch (JSExn jse) { throw new Wrapper(jse); } }
+ for(int i=0; i<a.attrSize(); i++) attrs.put(JSU.S(a.getKey(i)), JSU.S(a.getVal(i)));
+ callargs3[0] = JSU.S(c.getLocalName());
+ callargs3[1] = attrs;
+ callargs3[2] = JSU.S(c.getUri());
+ startElement.call(null, callargs3);
+ } catch (JSExn jse) { throw new Wrapper(jse);
+ } finally { callargs3[0] = callargs3[1] = callargs3[2] = null; } }
- public void endElement(XML.Element c) throws XML.Exn { try {
- endElement.call(JS.S(c.getLocalName()), JS.S(c.getUri()), null, null, 2);
- } catch (JSExn jse) { throw new Wrapper(jse); } }
+ public void endElement(Tree.Element c) throws XML.Exn { try {
+ callargs2[0] = JSU.S(c.getLocalName());
+ callargs2[1] = JSU.S(c.getUri());
+ endElement.call(null, callargs2);
+ } catch (JSExn jse) { throw new Wrapper(jse); } finally { callargs2[0] = callargs2[1] = null; } }
public void characters(char[] ch, int start, int length) throws XML.Exn { try {
- characters.call(JS.S(new String(ch, start, length)), null, null, null, 1);
- } catch (JSExn jse) { throw new Wrapper(jse); } }
+ callargs1[0] = JSU.S(new String(ch, start, length));
+ characters.call(null, callargs1);
+ } catch (JSExn jse) { throw new Wrapper(jse); } finally { callargs1[0] = null; } }
public void whitespace(char[] ch, int start, int length) throws XML.Exn { try {
- whitespace.call(JS.S(new String(ch, start, length)), null, null, null, 1);
- } catch (JSExn jse) { throw new Wrapper(jse); } }
+ callargs1[0] = JSU.S(new String(ch, start, length));
+ whitespace.call(null, callargs1);
+ } catch (JSExn jse) { throw new Wrapper(jse); } finally { callargs1[0] = null; } }
public void doParse(JS s) throws JSExn {
try {
- parse(new BufferedReader(new InputStreamReader(s.getInputStream())));
+ parse(new BufferedReader(new InputStreamReader(JSU.getInputStream(s))));
} catch (Wrapper e) {
throw e.wrapee;
} catch (XML.Exn e) {
// FEATURE: move this into builtin.xwar
public Blessing bless(JS b) throws JSExn { return new Ibex.Blessing(b, this, null, null); }
// JS:FIXME: This doesn't properly handle traps
- public static class Blessing extends JS.O {
+ public static class Blessing extends JS.Clone {
private Ibex ibex;
private Template t = null;
public JS parentkey = null;
public Blessing parent = null;
public JS clonee;
- private Hash cache = new Hash();
+ private Basket.Map cache = new Basket.Hash();
public Blessing(JS clonee, Ibex ibex, Blessing parent, JS parentkey) throws JSExn {
- this.clonee = clonee; this.ibex = ibex; this.parentkey = parentkey; this.parent = parent; }
+ super(clonee); this.clonee = clonee; this.ibex = ibex; this.parentkey = parentkey; this.parent = parent; }
public JS get(JS key) throws JSExn {
- if (JS.isString(key) && JS.toString(key).equals("")) return getStatic();
+ if (JSU.isString(key) && JSU.toString(key).equals("")) return getStatic();
if (cache.get(key) != null) return (JS)cache.get(key);
- JS ret = new Blessing(clonee.get(key), ibex, this, key);
+ JS ret = new Blessing(super.get(key), ibex, this, key);
cache.put(key, ret);
return ret;
}
public static Blessing getBlessing(JS js) {
- while (js instanceof JS.Clone && !(js instanceof Blessing)) js = ((JS.Clone)js).getClonee();
+ while (js instanceof JS.Clone && !(js instanceof Blessing)) js = js.unclone();
if (!(js instanceof Blessing)) return null;
return (Blessing)js;
}
// FEATURE: This is a gross hack
public InputStream getImage() throws JSExn {
try {
- InputStream in = getInputStream();
+ InputStream in = JSU.getInputStream(this);
if (in != null) return in;
} catch (IOException e) { /* DELIBERATE */ }
String[] exts = new String[] { ".png", ".jpeg", ".gif" };
- for (int i=0; i < exts.length; i++)
+ for (int i=0; i < exts.length; i++) {
try {
- InputStream in = parent.get(JS.S(JS.toString(parentkey) + exts[i])).getInputStream();
+ InputStream in = JSU.getInputStream(parent.get(JSU.S(JSU.toString(parentkey) + exts[i])));
if (in != null) return in;
} catch (IOException f) { /* DELIBERATE */ }
+ }
return null;
}
public JS getStatic() throws JSExn {
try {
if (t == null) {
// FEATURE: Might want to handle the ".t" part better
- JS res = parent.get(JS.S(JS.toString(parentkey) + ".t"));
+ JS res = parent.get(JSU.S(JSU.toString(parentkey) + ".t"));
t = Template.buildTemplate(description(), res, ibex);
}
return t != null ? t.staticObject : null;
}
}
private String description() {
- String s = JS.debugToString(parentkey);
- for(Blessing b = parent; b.parentkey != null; b = b.parent) s = JS.debugToString(b.parentkey) + "." + s;
+ String s = JSU.str(parentkey);
+ for(Blessing b = parent; b.parentkey != null; b = b.parent) s = JSU.str(b.parentkey) + "." + s;
return s;
}
- public JS call(JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
- if (nargs != 1) throw new JSExn("can only call a template with one arg");
+ public JS call(JS method, JS[] args) throws JSExn {
+ if (method != null) return super.call(method, args);
+ if (args.length != 1) throw new JSExn("can only call a template with one arg");
getStatic();
- if (t == null) throw new JSExn("No such template " + parentkey);
- if(!(a instanceof Box)) throw new JSExn("can only apply templates to boxes");
- t.apply((Box)a);
- return a;
+ if (t == null) throw new JSExn("No such template " + JSU.str(parentkey));
+ if(!(args[0] instanceof Box)) throw new JSExn("can only apply templates to boxes");
+ t.apply((Box)args[0]);
+ return args[0];
}
// FEATURE: This is a gross hack
Template getTemplate() throws JSExn {
getStatic();
- if (t == null) throw new JSExn("No such template " + JS.debugToString(parentkey));
+ if (t == null) throw new JSExn("No such template " + JSU.str(parentkey));
return t;
}
- // JS:FIXME: Blessing shouldn't need to roll its own JS.Clone implementation
- public InputStream getInputStream() throws IOException { return clonee.getInputStream(); }
}
}