import org.ibex.util.*;
import org.ibex.js.*;
+// FIXME: replace scope().get("") with containsKey() check on attributes,
+// thereby neatly sidestepping any higher up user defined variables
+// (especially when combined with undeclare()
public class Template extends JSLeaf.Element {
public static Template parse(String path, Template.Scope s) throws FileNotFoundException, IOException {
Reader xmlreader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
//#end
} else if (uri.startsWith("http://xt.ibex.org/")) {
- //#switch(uri.substring(19))
- case "io": System.out.println("ibex.xt.io not yet implemented"); // TODO
- //#end
- //throw new JSLeaf.Exn("Unknown XT library: "+uri);
+ throw new JSLeaf.Exn("Unknown XT library: "+uri);
} else if (uri.startsWith("local:")) {
// merge a new template into this tree
e.getChildren().clear();
}
- Tree.Element merged = new JSLeaf.Merge(t, e);
+ // merge the attributes of the template and its representative
+ t.setAttributes(new JSLeaf.MergeAttr(e.getAttributes(), t.getAttributes()));
// remap the parent of the original element
if (e.getParent() != null) {
List ch = e.getParent().getChildren();
- ch.set(ch.indexOf(e), merged);
+ ch.set(ch.indexOf(e), t);
}
- return wrap(merged, s);
+ return wrap(t, s);
}
e = new Template.AttributeEval(e);
/** Processes ${...} blocks in attributes, loads applicable
* attributes into the JS scope and processes global attributes. */
public static class AttributeEval extends JSLeaf.Element implements Tree.Attributes {
+ // TODO: hide global attributes from out() function. waiting on util.XMLHelper
protected Tree.Attributes a;
- public AttributeEval(Tree.Element wrapped) { super(wrapped); a = wrapped.getAttributes(); }
-
- public Tree.Attributes getAttributes() { return this; }
+ public AttributeEval(Tree.Element wrapped) {
+ super(wrapped);
+ a = wrapped.getAttributes();
+ wrapped.setAttributes(this);
+ }
public int getIndex(String q) { return a.getIndex(q); }
public int getIndex(String u, String k) { return a.getIndex(u, k); }
case "declare":
Object d = eval(a.getVal(i));
if (!(d instanceof String)) throw new JSLeaf.Exn(
- "attribute "+getPrefix()+":declare can only contain a "+
+ "attribute '"+getPrefix()+":declare' can only contain a "+
"space seperated list of variable names to declare.");
StringTokenizer st = new StringTokenizer((String)d, " ");
while (st.hasMoreTokens()) scope().declare(st.nextToken());
// TODO: finish
public static final class Transaction extends JSLeaf.Element {
- private final Template.Scope scope; // FIXME: HACK. unstatisise all tags, or do this to all
- public Transaction(Tree.Element e, Template.Scope s) { super(e); scope = s;} // TODO: check kids
+ private Template.Scope scope;
+ public Transaction(Tree.Element e, Template.Scope s) { super(e); scope = s; }
public void out(Writer w) throws IOException {
- // TODO: <xt:use />
- List c = getChildren();
StringWriter sw = new StringWriter();
+ List c = getChildren();
for (int i=0; i < c.size(); i++) ((Tree.Leaf)c.get(i)).out(sw);
- JS t = JS.fromReader("input", 0, new StringReader(sw.toString()));
- t = JS.cloneWithNewParentScope(t, new JSScope(null));
+ StringReader sr = new StringReader(sw.toString());
+
+ JS t;
+ try { t = JS.cloneWithNewParentScope(
+ JS.fromReader("input", 0, sr), new JSScope(null)); }
+ catch (IOException e) { throw new JSLeaf.Exn(e.getMessage()); }
+
+ try {
+ JSScope scope = JS.getParentScope(t);
+
+ Object u = scope().get("use"); if (u != null) scope().undeclare("use");
+ if (u != null) {
+ if (!(u instanceof String)) throw new JSLeaf.Exn(
+ "<"+getPrefix()+":transaction> requires 'use' attribute "+
+ "to be a valid space-seperated list of variables");
+ StringTokenizer st = new StringTokenizer((String)u);
+ while (st.hasMoreTokens()) {
+ String k = st.nextToken();
+ scope.put(k, scope().get(k));
+ }
+ }
+ } catch (JSExn e) { throw new JSLeaf.Exn(e); }
+
scope.transaction(t);
}
}
public static final class Text extends JSLeaf {
public Text(Tree.Leaf w) { super(w); }
public void out(Writer w) throws IOException {
- // FIXME: make eval() take a writer
StringWriter sw = new StringWriter();
super.out(sw);
w.write((String)eval(sw.toString()));