first alpha release
[org.ibex.xt.git] / src / org / ibex / xt / Servlet.java
similarity index 55%
rename from src/org/ibex/xml/Servlet.java
rename to src/org/ibex/xt/Servlet.java
index 833f8fc..be36ac8 100644 (file)
@@ -1,4 +1,4 @@
-package org.ibex.xml;
+package org.ibex.xt;
 import org.ibex.js.*;
 import org.ibex.util.*;
 import org.ibex.io.*;
@@ -11,42 +11,46 @@ import com.thoughtworks.xstream.*;
 import org.prevayler.*;
 import org.prevayler.implementation.snapshot.*;
 
-
 public class Servlet extends HttpServlet {
 
-    private ServletResolver resolver = new ServletResolver();
-    private class ServletResolver implements XML.Node.Stream.Resolver {
-        public XML.Node.Stream.Functor resolve(String uri) {
-            if (uri.indexOf(':') == -1) throw new RuntimeException("uri does not contain an method: " + uri);
-            String method = uri.substring(0, uri.indexOf(':'));
-            String rest = uri.substring(uri.indexOf(':'))+1;
-            //case "xtree":  return XTree.tag(rest);
-            //#switch(method)
-            case "webinf": return new Template(cx.getRealPath(rest));
-            case "java":   try { return (XML.Node.Stream.Functor)Class.forName(rest).newInstance(); }
-                           catch (Exception e) { throw new RuntimeException(e); }
-            //#end
-            throw new RuntimeException("unknown method " + method);    
+    private ServletScope servletscope = null;
+    private String path;
+    private Prevayler prevayler;
+    private JS prevalent;
+    private ServletContext cx = null;
+
+    public void destroy() { try {
+        synchronized(this.getClass()) {
+            Prevayler privatePrevayler = prevayler;
+            if (prevayler == null) return;
+            prevayler = null;
+            Prevalence.destroy(cx, prevayler);
         }
+    } catch (Exception e) { e.printStackTrace(); } }
+
+    public void init(ServletConfig sc) throws ServletException {
+        cx = sc.getServletContext();
+        prevayler = Prevalence.getPrevayler(cx);
     }
 
+    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { doGet(request, response); }
     public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
-        JSScope scope = new ServletScope(request, response);
-        String path = cx.getRealPath(((HttpServletRequest)request).getServletPath());
+        servletscope = new ServletScope(request, response, cx);
+        path = cx.getRealPath(((HttpServletRequest)request).getServletPath());
         Reader xmlreader = new InputStreamReader(new FileInputStream(path));
-        XML.Node.Stream s = new JSRewriter(XML.Node.Stream.in(xmlreader), scope);
-        s.out(response.getWriter());
+        new Template(servletscope, new JSScope(servletscope), xmlreader).wrap(null).toXML(response.getWriter());
     }
 
-    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { doGet(request, response); }
-
     public class ServletScope extends JSScope {
         HttpServletRequest request;
         HttpServletResponse response;
-        public ServletScope(ServletRequest request, ServletResponse response) {
+        ServletContext cx;
+        public String getRealPath(String s) { return cx.getRealPath(s); }
+        public ServletScope(ServletRequest request, ServletResponse response, ServletContext cx) {
             super(null);
             this.request = (HttpServletRequest)request;
             this.response = (HttpServletResponse)response;
+            this.cx = cx;
         }
         private JS params = new JS() {
                 public Object get(Object key) { return request.getParameter(JS.toString(key)); }
@@ -96,19 +100,21 @@ public class Servlet extends HttpServlet {
             //#switch(method)
             case "prevalent.query":
                 try {
-                    return prevayler.execute(new JSQuery(JS.cloneWithNewParentScope((JS)a, null)));
+                    return prevayler.execute(new Prevalence.JSQuery(JS.cloneWithNewParentScope((JS)a, null)));
                 } catch (Exception e) {
                     e.printStackTrace();
                     throw new RuntimeException(e); }
 
-            case "prevalent.execute":
-                try {
-                    prevayler.execute(new JSTransaction(JS.cloneWithNewParentScope((JS)a, null)));
-                } catch (Exception e) { 
-                    e.printStackTrace();
-                    throw new RuntimeException(e); }
-
             case "session.invalidate":    request.getSession(true).invalidate(); return null;
+            case "context.list":
+                String path = JS.toString(a);
+                if (path.indexOf("..") != -1) throw new JSExn("cannot use .. in paths");
+                File f = new File(cx.getRealPath("/") + File.separatorChar + path);
+                if (!f.isDirectory()) return null;
+                String[] contents = f.list();
+                JSArray ret = new JSArray(contents.length);
+                for(int i=0; i<contents.length; i++) ret.addElement(contents[i]);
+                return ret;
             //#end
             return null;
         }
@@ -116,9 +122,7 @@ public class Servlet extends HttpServlet {
             //#switch(key)
             case "body":
             case "arg":                   return null;
-            case "prevalent":             return getSub("prevalent");
-            case "prevalent.query":       return METHOD;
-            case "prevalent.execute":     return METHOD;
+            case "prevalent":             return prevalent;
             case "request":               return getSub("request");
             case "request.user":          return request.getRemoteUser();
             case "request.header":        return requestHeader;
@@ -135,6 +139,10 @@ public class Servlet extends HttpServlet {
             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 "page":                  return getSub("page");
+            case "page.lastmodified":     return new JSDate(new File(path).lastModified());
+            case "context":               return getSub("context");
+            case "context.list":          return METHOD;
             case "params":                return params;
             case "cookie":                return cookies;
             //#end
@@ -146,6 +154,9 @@ public class Servlet extends HttpServlet {
             case "response.code":         response.setStatus(JS.toInt(val));
             case "response.redirect":     response.sendRedirect(JS.toString(val));
             case "response.contentType":  response.setContentType(JS.toString(val));
+            case "prevalent":             
+                try { prevayler.execute(new Prevalence.JSTransaction(JS.cloneWithNewParentScope((JS)val, null)));
+                } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); }
             //#end
             } catch (IOException e) {
                 throw new JSExn(e);
@@ -153,92 +164,4 @@ public class Servlet extends HttpServlet {
         }
     }
 
-    // Prevalence //////////////////////////////////////////////////////////////////////////////
-    
-    static final Hashtable prevaylers = new Hashtable();
-    private Prevayler prevayler;
-    private JS prevalent;
-    private ServletContext cx = null;
-    public void destroy() {
-        try {
-            synchronized(this.getClass()) {
-                Prevayler privatePrevayler = prevayler;
-                if (prevayler == null) return;
-                prevayler = null;
-                prevaylers.remove(cx);
-                prevayler.takeSnapshot();
-                prevayler.close();
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private static class SnapshotThread extends Thread {
-        ServletContext cx;
-        public SnapshotThread(ServletContext cx) { this.cx = cx; }
-        public void run() {
-            try {
-                Thread.sleep(10000);
-                Prevayler privatePrevayler = (Prevayler)prevaylers.get(cx);
-                if (privatePrevayler == null) return;
-                privatePrevayler.takeSnapshot();
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    public void init(ServletConfig sc) throws ServletException {
-        try {
-            cx = sc.getServletContext();
-            synchronized(cx) {
-                prevayler = (Prevayler)prevaylers.get(cx);
-                if (prevalent == null) {
-                    PrevaylerFactory pf = new PrevaylerFactory();
-                    String base = cx.getRealPath("/") + "WEB-INF" + File.separatorChar + "prevalent";
-                    System.err.println("prevayling to " + base);
-                    pf.configurePrevalenceBase(base);
-                    XStreamSnapshotManager manager = new XStreamSnapshotManager(new JS(), base, null) {
-                            protected XStream createXStream() {
-                                XStream xstream = new XStream();
-                                xstream.alias("js", JS.class);
-                                xstream.alias("jsdate", JSDate.class);
-                                return xstream;
-                            }
-                        };
-                    System.err.println("configuring with " + manager);
-                    pf.configureSnapshotManager(manager);
-                    //pf.configureClassLoader(JSTransaction.class.getClassLoader());
-                    prevayler = pf.create();
-                    prevaylers.put(cx, prevayler);
-                    new SnapshotThread(cx).start();
-                }
-            }
-            prevalent = (JS)prevayler.prevalentSystem();
-        } catch (Exception e) {
-            throw new ServletException(e);
-        }
-    }
-
-    public static class JSTransaction implements Transaction {
-        private JS js;
-        public JSTransaction(JS js) { this.js = js; }
-        public void executeOn(Object o, Date now) {
-            try {
-                js.call(o, new JSDate(now.getTime()), null, null, 2);
-            } catch (Exception e) { throw new RuntimeException(e); }
-        }
-    }
-
-    public static class JSQuery implements Query {
-        private JS js;
-        public JSQuery(JS js) { this.js = js; }
-        public Object query(Object o, Date now) {
-            try {
-                return js.call(o, new JSDate(now.getTime()), null, null, 2);
-            } catch (Exception e) { throw new RuntimeException(e); }
-        }
-    }
-
 }