From aa4748b4f5c375bedcfac257b684a59906c6f03a Mon Sep 17 00:00:00 2001 From: crawshaw Date: Wed, 24 Nov 2004 22:00:47 +0000 Subject: [PATCH] introduce a signalling exception and improve error messages darcs-hash:20041124220047-2eb37-3e02150c6258dcc816ca174af821f1b46c093bc2.gz --- src/java/org/ibex/xt/JSElement.java | 21 +++++++++++++++------ src/java/org/ibex/xt/Servlet.java | 29 +++++++++++++++++++++++------ src/java/org/ibex/xt/Template.java | 28 +++++++++++++++------------- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/java/org/ibex/xt/JSElement.java b/src/java/org/ibex/xt/JSElement.java index cfa1a1f..c6eee6e 100644 --- a/src/java/org/ibex/xt/JSElement.java +++ b/src/java/org/ibex/xt/JSElement.java @@ -9,6 +9,7 @@ import java.util.*; 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; @@ -42,7 +43,7 @@ public class JSElement extends JSScope implements XML.Element { 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) { @@ -58,9 +59,9 @@ public class JSElement extends JSScope implements XML.Element { 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()); } @@ -72,9 +73,11 @@ public class JSElement extends JSScope implements XML.Element { 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); } } @@ -147,4 +150,10 @@ public class JSElement extends JSScope implements XML.Element { 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(); } + } } diff --git a/src/java/org/ibex/xt/Servlet.java b/src/java/org/ibex/xt/Servlet.java index 7402dd2..53eb197 100644 --- a/src/java/org/ibex/xt/Servlet.java +++ b/src/java/org/ibex/xt/Servlet.java @@ -13,7 +13,6 @@ import org.prevayler.*; public class Servlet extends HttpServlet { - private String path; private Prevayler prevayler; private JS prevalent; private ServletContext cx = null; @@ -35,12 +34,30 @@ public class Servlet extends HttpServlet { 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 { diff --git a/src/java/org/ibex/xt/Template.java b/src/java/org/ibex/xt/Template.java index 445a6ee..8456f61 100644 --- a/src/java/org/ibex/xt/Template.java +++ b/src/java/org/ibex/xt/Template.java @@ -36,7 +36,7 @@ public class Template extends JSElement { //#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); @@ -45,7 +45,7 @@ public class Template extends JSElement { 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 tag."); @@ -102,7 +102,7 @@ public class Template extends JSElement { 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); } @@ -113,7 +113,7 @@ public class Template extends JSElement { 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"); } @@ -138,16 +138,16 @@ public class Template extends JSElement { 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."); @@ -158,7 +158,7 @@ public class Template extends JSElement { 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); } } } @@ -184,11 +184,6 @@ public class Template extends JSElement { } } - 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); } @@ -199,4 +194,11 @@ public class Template extends JSElement { 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; } + } } -- 1.7.10.4