add redirect tag support
[org.ibex.xt-crawshaw.git] / src / java / org / ibex / xt / Servlet.java
index fcdbde2..c05101a 100644 (file)
@@ -1,21 +1,17 @@
 package org.ibex.xt;
 
 import java.io.*;
-import java.net.*;
 import java.util.*;
 import javax.servlet.*;
 import javax.servlet.http.*;
 
-import org.ibex.util.*;
 import org.ibex.util.Collections;
 import org.ibex.js.*;
 
 import org.prevayler.*;
-import org.prevayler.implementation.snapshot.*;
 
 public class Servlet extends HttpServlet {
 
-    private String path;
     private Prevayler prevayler;
     private JS prevalent;
     private ServletContext cx = null;
@@ -37,12 +33,39 @@ 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.");
+        PrintWriter w = new PrintWriter(rs.getWriter());
+        try {
+            while (src != null) {
+                try {
+                    StringWriter buffer = new StringWriter();
+                    Template t = Template.parse(cx.getRealPath(src), scope);
+                    Template.wrap(t, scope).out(buffer);
+                    w.write(buffer.toString());
+                    src = null;
+                } catch (Template.RedirectSignal r) {
+                    src = r.getTarget();
+                }
+            }
+        } catch (Template.Signal s) {
+            // exit silently
+        } catch (JSElement.Exn e) {
+            w.print("\n"+src+": ");
+            w.println(e.getMessage());
+            System.out.println(e);
+        } catch (FileNotFoundException e) {
+            w.print("\nfile not found: ");
+            w.println(e.getMessage());
+            System.out.println(e);
+        } catch (IOException e) {
+            w.print("\nio error: ");
+            w.println(e.getMessage());
+            e.printStackTrace();
+        } catch (Exception e) {
+            System.out.println("Unexpected Exception:");
+            e.printStackTrace();
+        }
     }
 
     public static class Scope extends Template.Scope {
@@ -61,6 +84,31 @@ public class Servlet extends HttpServlet {
             catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); }
         }
 
+        private JS session = new JS() {
+            public Object get(Object key) throws JSExn {
+                //#switch(JS.toString(key))
+                case "created":       return new JSDate(request.getSession(true).getCreationTime());
+                case "accessed":      return new JSDate(request.getSession(true).getLastAccessedTime());
+                case "invalidate":    return METHOD;
+                //#end
+                return super.get(key);
+            }
+            public void put(Object key, Object val) throws JSExn {
+                //#switch(JS.toString(key))
+                case "created":       throw new JSExn("can not set session.created");
+                case "accessed":      throw new JSExn("can not set session.accessed");
+                case "invalidate":    throw new JSExn("can not set session.invalidate");
+                //#end
+                super.put(key, val);
+            }
+            public Object callMethod(Object method, final Object a, final Object b, Object c, Object[] rest, int nargs)
+                throws JSExn {
+                //#switch(JS.toString(method))
+                case "invalidate":    request.getSession(true).invalidate(); return null;
+                //#end
+                return super.callMethod(method, a, b, c, rest, nargs);
+            }
+        };
         private JS params = new JS() {
             private List keys = null;
             public Object get(Object key) { return request.getParameter(JS.toString(key)); }
@@ -144,11 +192,7 @@ public class Servlet extends HttpServlet {
             case "request.path":          return request.getPathInfo();
             case "response":              return getSub("response");
             case "response.header":       return responseHeader;
-            case "session":               return getSub("session");
-            case "session.attr":          return sessionAttributes;
-            case "session.created":       return new JSDate(request.getSession(true).getCreationTime());
-            case "session.accessed":      return new JSDate(request.getSession(true).getLastAccessedTime());
-            case "session.invalidate":    return METHOD;
+            case "session":               return session;
             case "page":                  return getSub("page");
             //case "page.lastmodified":     return new JSDate(new File(path).lastModified()); FIXME
             case "context":               return getSub("context");