import org.ibex.util.*;
import org.ibex.js.JS;
import org.ibex.js.JSScope;
+import org.ibex.js.JSExn;
public class JSElement extends JSScope implements XML.Element {
protected XML.Element wrapped;
declare(a.getKey(i));
put(a.getKey(i), eval(a.getVal(i)));
}
- } catch (Exception e) { throw new RuntimeException(e); }
+ } catch (JSExn e) { throw new Exn(e); }
}
private Object eval(String s) {
app instanceof String ||
app instanceof Number ||
app instanceof Boolean))
- throw new RuntimeException("javascripts within ${...} can only return " +
- "strings, numbers, and booleans; not a " +
- app.getClass().getName());
+ throw new Exn("javascripts within ${...} can only return " +
+ "strings, numbers, and booleans; not a " +
+ app.getClass().getName());
ret.append(app == null ? "null" : app.toString());
}
try {
return JS.eval(JS.cloneWithNewParentScope(
JS.fromReader("input", 0, new StringReader(s)), this));
- } catch (Exception e) {
+ } catch (IOException e) {
e.printStackTrace();
- throw new RuntimeException(e);
+ throw new Exn("impossible IOException, reading from StringReader");
+ } catch (JSExn e) {
+ throw new Exn(e);
}
}
return i >= a.attrSize() ? b.getUri(i-a.attrSize()) : a.getUri(i); }
public int attrSize() { return a.attrSize() + b.attrSize(); }
}
+
+ public static class Exn extends RuntimeException {
+ public Exn(String cause) { super(cause); }
+ public Exn(JSExn e) { super(e); }
+ public String toString() { return "JSElement.Exn: "+getMessage(); }
+ }
}
public class Servlet extends HttpServlet {
- private String path;
private Prevayler prevayler;
private JS prevalent;
private ServletContext cx = null;
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { doGet(request, response); }
public void doGet(HttpServletRequest rq, HttpServletResponse rs) throws IOException {
- String path = cx.getRealPath(rq.getServletPath());
+ String src = rq.getServletPath();
Servlet.Scope scope = new Servlet.Scope(cx, rq, rs, prevayler);
- rs.getWriter().write("beginning output...");
- try { Template.wrap(Template.parse(path, scope), scope).out(rs.getWriter()); }
- catch (Exception e) { e.printStackTrace(); System.out.println("e = "+e); }
- rs.getWriter().write("...output ends.");
+ try {
+ while (src != null) {
+ try {
+ StringWriter w = new StringWriter();
+ Template t = Template.parse(cx.getRealPath(src), scope);
+ Template.wrap(t, scope).out(w);
+ rs.getWriter().write(w.toString());
+ src = null;
+ } catch (Template.RedirectSignal r) {
+ src = r.getTarget();
+ }
+ }
+ } catch (Template.Signal s) {
+ } catch (JSElement.Exn e) {
+ PrintWriter w = new PrintWriter(rs.getWriter());
+ w.print("\n"+src+": ");
+ w.println(e.getMessage());
+ System.out.println(e);
+ } catch (Exception e) {
+ System.out.println("Unexpected Exception:");
+ e.printStackTrace();
+ }
}
public static class Scope extends Template.Scope {
//#switch(uri.substring(19))
case "io": System.out.println("ibex.xt.io not yet implemented"); // TODO
//#end
- //throw new RuntimeException("Unknown XT library: "+uri);
+ //throw new JSElement.Exn("Unknown XT library: "+uri);
} else if (uri.startsWith("local:")) {
Template t = parse(s.getLocalPath() + uri.substring(6), s);
if (c.size() > 0) {
// move all children from e to placeholder
XML.Element placeholder = findPlaceholder(t);
- if (placeholder == null) throw new RuntimeException(
+ if (placeholder == null) throw new JSElement.Exn(
"<"+e.getQName()+"> attempted to include children into a " +
"template which does not contain an <xt:children /> tag.");
try {
Object varIf = get("if"); if (varIf != null) undeclare("if");
if (varIf != null && !"true".equals(varIf)) return;
- } catch (JSExn e) { throw new RuntimeException(e); }
+ } catch (JSExn e) { throw new JSElement.Exn(e); }
wrapped.out(w);
}
super(e);
List c = getChildren();
for (int i=0; i < c.size(); i++)
- if (c.get(i) instanceof XML.Element) throw new RuntimeException(
+ if (c.get(i) instanceof XML.Element) throw new JSElement.Exn(
"<"+getPrefix()+":js> tags may not have child elements");
}
Object varPut = get("put"); if (varPut != null) undeclare("put");
varIn = exec("return (" + varIn + ");");
- if (varIn == null || (varIn instanceof JSArray)) throw new RuntimeException(
+ if (varIn == null || (varIn instanceof JSArray)) throw new JSElement.Exn(
"<"+getPrefix()+":foreach> requires attribute 'in' to specify " +
"the name of a valid js array in the current scope, not in='"+varIn+"'.");
if (varPut == null) varPut = "x";
else if (!(varPut instanceof String) || get(varPut) != null)
- throw new RuntimeException(
+ throw new JSElement.Exn(
"<"+getPrefix()+":foreach> 'put' attribute requires the name of "+
"an undeclared variable, not put='"+varPut+"'.");
- if (get(varPut) != null) throw new RuntimeException(
+ if (get(varPut) != null) throw new JSElement.Exn(
"<"+getPrefix()+":foreach> has no 'put' attribute defined and the "+
"default variable 'x' already exists in the current scope.");
put(varPut, it.next());
for (int i=0; i < c.size(); i++) ((Tree.Leaf)c.get(i)).out(w);
}
- } catch (JSExn e) { throw new RuntimeException(e); }
+ } catch (JSExn e) { throw new JSElement.Exn(e); }
}
}
}
}
- public static final class Java extends JSElement {
- // TODO what exactly?
- public Java(XML.Element w) { super(w); }
- }
-
public abstract static class Scope extends JSScope {
public Scope(JSScope j) { super(j); }
public abstract void transaction(JS t);
}
+ public static class Signal extends RuntimeException {}
+ public static class ReturnSignal extends Signal { }
+ public static class RedirectSignal extends Signal {
+ protected String target;
+ public RedirectSignal(String target) { super(); this.target = target; }
+ public String getTarget() { return target; }
+ }
}