+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
package org.ibex.xt;
import org.ibex.js.*;
import org.ibex.util.*;
public class Template extends Node.Stream.Filter implements Node.Stream.Functor {
- static Template newTemplate(Servlet.ServletScope servletscope, JSScope scope, String str) {
+ static Template newTemplate(Servlet.ServletScope servletscope, Scope scope, String str) {
try {
File f = new File(str);
if (!f.exists()) f = new File(str + ".xt");
} catch (Exception e) { throw new RuntimeException(e); }
}
- static JSScope copyNodeToScope(Node n, JSScope scope) {
+ static Scope copyNodeToScope(Node n, Scope scope) {
try {
for(int i=0; i<n.numattrs; i++) {
scope.declare(n.attrs[i*2]);
- scope.put(n.attrs[i*2], n.attrs[i*2+1]);
+ scope.put(JSU.S(n.attrs[i*2]), JSU.S(n.attrs[i*2+1]));
}
return scope;
} catch (Exception e) { throw new RuntimeException(e); }
private class JSRewriter extends Node.Stream {
private Node.Stream in;
- private JSScope scope;
- public JSRewriter(Node.Stream in, JSScope scope) { this.in = in; this.scope = scope; }
+ private Scope scope;
+ public JSRewriter(Node.Stream in, Scope scope) { this.in = in; this.scope = scope; }
protected boolean _read(Node n) { if (!in.read(n)) return false; transform(n, scope); return true; }
}
- public static Node transform(Node n, JSScope scope) {
+ public static Node transform(Node n, Scope scope) {
if (n.cdata != null) n.cdata = eval(n.cdata, scope).toString();
else for(int i=1; i<n.numattrs*2; i+=2) n.attrs[i] = eval(n.attrs[i], scope).toString();
return n;
}
- private static Object eval(String s, JSScope scope) {
+ private static Object eval(String s, Scope scope) {
if (s == null) return null;
StringBuffer ret = new StringBuffer();
for(boolean first = true; s.indexOf("${") != -1; first = false) {
return ret.toString();
}
- public static Object exec(String s, JSScope scope) {
+ public static Object exec(String s, Scope scope) {
try {
- return JS.eval(JS.cloneWithNewParentScope(JS.fromReader("input", 0, new StringReader(s)), scope));
+ return JSU.cloneWithNewGlobalScope(JSU.fromReader("input", 0, new StringReader(s)), scope).call(null,null);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
- private JSScope scope;
+ private Scope scope;
private Servlet.ServletScope servletscope;
private Node.Stream children;
public Node.Stream wrap(Node.Stream children) { this.children = children; return this; }
- public Template(Servlet.ServletScope servletscope, JSScope scope, Reader template) {
+ public Template(Servlet.ServletScope servletscope, JS scope, Reader template) {
super(new Node.Stream.FromXML(template));
- this.scope = scope;
+ this.scope = new Scope(scope);
this.servletscope = servletscope;
}
public boolean _read(Node n) { boolean ret = __read(n); if (ret) transform(n, scope); return ret; }
final String rest = uri.substring(uri.indexOf(':')+1);
if (uri.equals("http://www.w3.org/1999/xhtml")) { return true;
} else if (method.equals("webinf")) {
- return graft(newTemplate(servletscope, copyNodeToScope(transform(n, scope), new JSScope(servletscope)),
+ return graft(newTemplate(servletscope, copyNodeToScope(transform(n, scope), new Scope(servletscope)),
servletscope.getRealPath("/") + "/WEB-INF/" + rest + name), n).upstreamRead(n);
} else if (uri.equals("http://xt.ibex.org/")) {
//#switch(name)
case "if":
transform(n, scope);
- return graft("true".equals(n.attr("if")) ? new DropTag() : new DropAll(), n).upstreamRead(n);
+ return graft((Node.Stream.Functor)("true".equals(n.attr("if")) ? new DropTag() : new DropAll()), n).upstreamRead(n);
case "js": return graft(new JsTag(scope), n).upstreamRead(n);
case "foreach": return graft(new ForEach(n, scope), n).upstreamRead(n);
case "children":
private class ForEach extends Node.Stream.Filter implements Node.Stream.Functor {
private Node[] nodes = null;
private Vec array = new Vec();
- private JSScope scope;
- public ForEach(Node n, JSScope s) {
+ private Scope scope;
+ public ForEach(Node n, Scope s) {
super(Node.Stream.NULL);
- Vec v = ((JSArray)exec("return (" + n.attr("in").toString() + ");", this.scope = s)).toVec();
- while(true) { Object o = v.pop(); if (o == null) break; array.push(o); }
+ try {
+ JSArray a = ((JSArray)exec("return (" + n.attr("in").toString() + ");", this.scope = s));
+ while(true) {
+ JS o = a.call(JSU.S("pop"), new JS[] { });
+ if (o == null) break;
+ array.push(o);
+ }
+ } catch (JSExn e) {
+ throw new RuntimeException(e);
+ }
}
public Node.Stream wrap(Node.Stream kids) {
Vec nodes = new Vec();
protected boolean _read(Node n) {
if (upstreamRead(n)) return true;
if (array.size() == 0) return false;
- JSScope scope2 = new JSScope(scope);
- try { scope2.declare("x"); scope2.put("x", array.pop()); } catch (JSExn e) { throw new RuntimeException(e); }
+ Scope scope2 = new Scope(scope);
+ try { scope2.declare("x"); scope2.put(JSU.S("x"), (JS)array.pop()); } catch (JSExn e) { throw new RuntimeException(e); }
return graft(new ConstantFunctor(new JSRewriter(new Node.Stream() {
private int i = 0;
protected boolean _read(Node n) {
}
}
+ public static class Scope extends JS.Immutable {
+ private final JS parent;
+ private final Hash declared = new Hash();
+ public Scope(JS parent) { this.parent = parent; }
+ public JS get(JS key) throws JSExn {
+ if (declared.get(key)!=null) return super.get(key);
+ return parent.get(key);
+ }
+ public void put(JS key, JS val) throws JSExn {
+ if (declared.get(key)!=null) super.put(key, val);
+ else parent.put(key, val);
+ }
+ public void declare(JS key) { declared.put(key, Boolean.TRUE); }
+ public void declare(String key) { declare(JSU.S(key)); }
+ public void undeclare(JS key) { declared.remove(key); }
+ public void undeclare(String key) { undeclare(JSU.S(key)); }
+ }
+
private class DropTag implements Node.Stream.Functor {
public Node.Stream wrap(Node.Stream kids) {
return kids;
} }
private class JsTag implements Node.Stream.Functor {
- JSScope scope;
- public JsTag(JSScope scope) { this.scope = scope; }
+ Scope scope;
+ public JsTag(Scope scope) { this.scope = scope; }
public Node.Stream wrap(final Node.Stream s) {
return new Node.Stream() {
protected boolean _read(Node n) {