+
+ // FEATURE: move this into builtin.xwar
+ public Blessing bless(JS b) { return new XWT.Blessing((JS.Cloneable)b, this, null, null); }
+ public static class Blessing extends JS.Clone {
+ private XWT xwt;
+ private Template t = null;
+ private Object parentkey = null;
+ private Blessing parent = null;
+ public Blessing(JS.Cloneable clonee, XWT xwt, Blessing parent, Object parentkey) {
+ super(clonee); this.xwt = xwt; this.parentkey = parentkey; this.parent = parent; }
+ public Object get(Object key) throws JSExn {
+ return key.equals("") ? ((Object)getStatic()) : (new Blessing((JS.Cloneable)clonee.get(key), xwt, this, key));
+ }
+ public static Blessing getBlessing(Object o) {
+ if (!(o instanceof JS)) return null;
+ JS js = (JS)o;
+ while (js instanceof JS.Clone && !(js instanceof Blessing)) js = ((JS.Clone)js).getClonee();
+ if (!(js instanceof Blessing)) return null;
+ return (Blessing)js;
+ }
+ public InputStream getImage() throws JSExn {
+ try {
+ InputStream in = Stream.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++)
+ try {
+ InputStream in = Stream.getInputStream(parent.get(parentkey + exts[i]));
+ if (in != null) return in;
+ } catch (IOException f) { /* DELIBERATE */ }
+ return null;
+ }
+ public JSScope getStatic() {
+ try {
+ // FIXME background?
+ if (t == null) t = new Template(Stream.getInputStream(parent.get(parentkey + ".xwt")), xwt);
+ return t.getStatic();
+ } catch (Exception e) {
+ Log.error(this, e);
+ return null;
+ }
+ }
+ public Object call(Object a, Object b, Object c, Object[] rest, int nargs) throws JSExn {
+ if (nargs != 1) throw new JSExn("FIXME can only call with one arg");
+ getStatic();
+ t.apply((Box)a);
+ return a;
+ }
+ }
+