X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fjava%2Forg%2Fibex%2Fxt%2FTemplate.java;h=6afe1b2adba218a6007704957c044a4ae1a032fd;hb=HEAD;hp=c30ece66ff9d74223df874474a476d48ef5aac74;hpb=f84b9c1b2991c4f349d8ae63585cb51efef6f2da;p=org.ibex.xt-crawshaw.git diff --git a/src/java/org/ibex/xt/Template.java b/src/java/org/ibex/xt/Template.java index c30ece6..6afe1b2 100644 --- a/src/java/org/ibex/xt/Template.java +++ b/src/java/org/ibex/xt/Template.java @@ -14,6 +14,9 @@ import java.util.*; 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))); @@ -40,10 +43,7 @@ public class Template extends JSLeaf.Element { //#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 @@ -62,15 +62,16 @@ public class Template extends JSLeaf.Element { 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); @@ -107,11 +108,14 @@ public class Template extends JSLeaf.Element { /** 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); } @@ -134,7 +138,7 @@ public class Template extends JSLeaf.Element { 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()); @@ -221,16 +225,36 @@ public class Template extends JSLeaf.Element { // 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: - 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); } } @@ -238,7 +262,6 @@ public class Template extends JSLeaf.Element { 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()));