added Form, other minor changes
authoradam <adam@megacz.com>
Fri, 25 Mar 2005 02:03:26 +0000 (02:03 +0000)
committeradam <adam@megacz.com>
Fri, 25 Mar 2005 02:03:26 +0000 (02:03 +0000)
darcs-hash:20050325020326-5007d-7b9ee0c03695ee61b9f1b5376021d664b89e3a54.gz

src/org/ibex/xt/Form.java [new file with mode: 0644]
src/org/ibex/xt/Prevalence.java
src/org/ibex/xt/Servlet.java
src/org/ibex/xt/Template.java

diff --git a/src/org/ibex/xt/Form.java b/src/org/ibex/xt/Form.java
new file mode 100644 (file)
index 0000000..c315f92
--- /dev/null
@@ -0,0 +1,234 @@
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
+package org.ibex.xt;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.io.*;
+import java.lang.reflect.*;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+// tabbing order?  accessability key?
+// the 'name' property is taken from the field name, with underscores converted to spaces
+// the way I'm doing Radio() { ... } right now is how multi-select menus ought to work
+// autogenerate <LABEL> elements?
+//     <TD><LABEL for="fname">First Name</LABEL>
+//     <TD><INPUT type="text" name="firstname" id="fname">
+
+public abstract class Form extends HttpServlet {
+
+    final String action;
+    public Form(String action) { this.action = action; }
+
+    public static class TestForm extends Form {
+        public TestForm() { super("/foo"); }
+        public boolean[]  poo        = new boolean[] { true, false, true, true };
+        public String[]   poo3       = new String[] { "a", "b", "c" };
+        public boolean    poo2       = true;
+        public String     myName     = "blarg";
+        public Radio      day        = new Radio() { public boolean sun, mon, tue, wed, thu, fri, sat; };
+        public CheckBox   vegetarian = new CheckBox();                     // label taken from field name
+        public CheckBox   vegan      = new CheckBox("are you vegan?");
+        public Text       firstName  = new Text("First Name");
+        public Text       lastName   = new Text();
+        public Password   pass;
+        public CheckBox[] checkboxes = new CheckBox[] {
+            new CheckBox("foo"),
+            new CheckBox("bar"),
+            new CheckBox("baz")
+        };
+        //public Option[] options    = new Option[] { new Option("foo"); }
+    }
+    public static void main(String[] s) throws Exception {
+        Form sample = new TestForm();
+        System.out.println(sample.emit());
+    }
+
+    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { doGet(request, response); }
+    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        Field[] fields = this.getClass().getFields();
+        for(int i=0; i<fields.length; i++) {
+            Field f     = fields[i];
+            Class c     = f.getType();
+            String name = f.getName();
+            Log.warn("param", name + " = " + request.getParameter(name));
+        }        
+    }
+
+    //public abstract void validate(HttpServletRequest req);
+    //public abstract void go(HttpServletRequest req, HttpServletResponse resp);
+
+    public JS fields() {
+        JSArray ret = new JSArray();
+        Field[] fields = this.getClass().getFields();
+        for(int i=0; i<fields.length; i++) {
+            Field f     = fields[i];
+            String name = f.getName();
+            ret.add(JSU.S(name));
+        }
+        return ret;
+    }
+
+    public String emit() throws Exception { return emit(null); }
+    public String emit(String fieldName) throws Exception {
+        Field[] fields = this.getClass().getFields();
+        StringBuffer ret = new StringBuffer();
+        if (fieldName==null) ret.append("<form xmlns='http://www.w3.org/1999/xhtml'"+q("action",action)+">\n");
+        for(int i=0; i<fields.length; i++) {
+            Field f     = fields[i];
+            Class c     = f.getType();
+            String name = f.getName();
+            if (fieldName != null && !fieldName.equals(name)) continue;
+            if (c == Boolean.TYPE) {
+                boolean b = ((Boolean)f.get(this)).booleanValue();
+                ret.append("    <input type='checkbox'"+q("name",name)+(b?" checked='on'":"")+"/>\n");
+            } else if (c == String.class) {
+                ret.append("    ");
+                Text t = new Text(f.getName());
+                t.value = ((String)f.get(this));
+                ret.append(t.emit());
+                ret.append('\n');
+            } else if (c.isArray()) {
+                Class c2 = c.getComponentType();
+                int len = Array.getLength(f.get(this));
+                for(int j=0; j<len; j++) {
+                    ret.append("      ");
+                    if (c2 == Boolean.TYPE) {
+                        boolean b = ((Boolean)Array.get(f.get(this),j)).booleanValue();
+                        ret.append("    <input type='checkbox'"+q("name",name+"_"+j)+(b?" checked='on'":"")+"/>\n");
+                    } else if (c2 == String.class) {
+                        Text t = new Text(f.getName()+"_"+j);
+                        t.value = (String)Array.get(f.get(this),j);
+                        ret.append(t.emit());
+                    } else {
+                        Element[] o = (Element[])f.get(this);
+                        o[j].name = name+"_"+j;
+                        ret.append(o[j].emit());
+                    }
+                    ret.append('\n');
+                }
+            } else if (!Element.class.isAssignableFrom(c)) {  // nothing
+            } else {
+                Element e = (Element)f.get(this);
+                if (e==null) {
+                    e = (Element)c.newInstance();
+                    f.set(this, e);
+                }
+                if (e.name==null) e.name = name;
+                ret.append("    ");
+                ret.append(e.emit());
+                ret.append('\n');
+            }
+        }
+        if (fieldName==null) ret.append("</form>\n");
+        return ret.toString();
+    }
+
+    public static String q(String key, String val)  { return val==null ? "" : " "+key+"='"+val+"'"; }
+    public static String q(String key, int val)     { return key+" ='"+val+"'"; }
+    public static String q(String key, boolean val) { return val ? " "+key+"=true" : ""; }
+    public static String escape(String s) { return s.replaceAll("&","&amp;").replaceAll("<","&gt;").replaceAll("'","&apos;"); }
+
+    public static abstract class Element {
+        public String  name     = null;
+        public boolean disabled = false;
+        public String  id       = null;
+        public int     size     = -1;
+        public String  alt      = null;
+        public Element() { }
+        public Element(String name) { this.name = name; }
+        public String fields() { return q("id",id)+q("disabled", disabled)+q("alt", alt); }
+        public String emit() { return "<input"+q("name",name)+q("type",type())+fields()+"/>"; }
+        public String type() {
+            String t = this.getClass().getName().toLowerCase();
+            if (t.indexOf('.') != -1) t = t.substring(t.lastIndexOf('.')+1);
+            if (t.indexOf('$') != -1) t = t.substring(t.lastIndexOf('$')+1);
+            return t;
+        }
+    }
+
+    public static class Text extends Element{
+        public String  value     = null;
+        public boolean ro        = false;
+        public char    maxLength = 0;
+        public String  fields(){return super.fields()+q("value",value)+q("readonly",ro)+(maxLength>0?q("maxlength",maxLength):"");}
+        public Text()                { super(); }
+        public Text(String name)     { super(name); }
+    }
+    public static class Password extends Text { }
+    public static class Hidden   extends Text { }
+    public static class TextArea extends Text {
+        int rows; // relation to 'size'?
+        int cols;
+        private TextArea() { }
+        public  TextArea(int rows, int cols) { this.rows=rows; this.cols=cols; }
+        public  String fields() { return super.fields()+q("rows",rows)+q("cols",cols); }
+        public  String emit()   { return "<textarea"+fields()+">\n"+escape(value)+"</textarea>"; }
+    }
+
+    public static class Radio extends Element {
+        public String emit() {
+            StringBuffer ret = new StringBuffer();
+            try {
+                Class c = this.getClass();
+                Field[] f = c.getFields();
+                for(int i=0; i<f.length; i++) {
+                    if (f[i].getType() != Boolean.TYPE) continue;
+                    if (f[i].getDeclaringClass().isAssignableFrom(Radio.class)) continue;
+                    boolean b = ((Boolean)f[i].get(this)).booleanValue();
+                    ret.append("        ");
+                    ret.append("<input type='radio'"+q("name",name)+q("value",f[i].getName())+(b?" checked='true'":"")+"/>");
+                    ret.append('\n');
+                }
+            } catch (Exception e) { e.printStackTrace(); }
+            return ret.toString();
+        }
+    }
+
+    public static class Submit extends Element { public Submit(String label) { super(label); } }
+    public static class Reset extends Element  { public Reset(String label)  { super(label); } }
+    public static class Upload extends Element {
+        String filename;
+        public Upload(String label) { super(label); }
+        public Upload(String label, String filename) { super(label); this.filename=filename; }
+    }
+
+    public static class CheckBox extends Element {
+        boolean on = false;
+        public String fields()        { return super.fields()+q("on",on); }
+        public CheckBox()             { super(); }
+        public CheckBox(String label) { super(label); }
+    }
+
+    /*
+    public static class Image extends Element {
+        // usemap, ismap
+        private Image() { }
+        public  Image(String url, String alt) { }
+        public  String url;
+        public  int x;
+        public  int y;
+    }
+
+
+    // Option[] -> Menu
+
+    // size == number of visible rows
+    public static class Menu extends Element {
+        // force a pre-selected option
+        public static class Item {
+            String label;
+            String value;
+            boolean selected = false;
+        }
+        public static class Group extends Item { }
+        public Menu(Item[] items) { }
+        public boolean multipleSelect;
+    }
+    */
+}
index cd7546f..2bfbfb1 100644 (file)
@@ -13,10 +13,30 @@ import javax.servlet.*;
 import javax.servlet.http.*;
 import com.thoughtworks.xstream.*;
 import org.prevayler.*;
 import javax.servlet.http.*;
 import com.thoughtworks.xstream.*;
 import org.prevayler.*;
-import org.prevayler.implementation.snapshot.*;
+import org.prevayler.implementation.snapshot.XmlSnapshotManager;
 
 public class Prevalence {
 
 
 public class Prevalence {
 
+    public static abstract class PrevalentServlet extends HttpServlet {
+       protected Hashtable prevalent;
+       protected Prevayler prevayler;
+       protected 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);
+           prevalent = (Hashtable)prevayler.prevalentSystem();
+       }
+    }
+
     static final Hashtable prevaylers = new Hashtable();
 
     public static void destroy(ServletContext cx, Prevayler prevayler) { try {
     static final Hashtable prevaylers = new Hashtable();
 
     public static void destroy(ServletContext cx, Prevayler prevayler) { try {
@@ -47,23 +67,12 @@ public class Prevalence {
                 prevayler = (Prevayler)prevaylers.get(cx);
                 if (prevayler == null) {
                     PrevaylerFactory pf = new PrevaylerFactory();
                 prevayler = (Prevayler)prevaylers.get(cx);
                 if (prevayler == null) {
                     PrevaylerFactory pf = new PrevaylerFactory();
-                    String base = cx.getRealPath("/") + "WEB-INF" + File.separatorChar + "prevalent";
+                    String base = cx.getRealPath("/") + File.separatorChar + "WEB-INF" + File.separatorChar + "prevalent";
                     System.err.println("prevayling to " + base);
                     pf.configurePrevalenceBase(base);
                     System.err.println("prevayling to " + base);
                     pf.configurePrevalenceBase(base);
-                    /*
-                    XmlSnapshotManager manager = new XmlSnapshotManager(new JS(), base, null); {
-                            protected XStream createXStream() {
-                                XStream xstream = new XStream();
-                                xstream.alias("js", JS.class);
-                                xstream.alias("jsdate", JSDate.class);
-                                return xstream;
-                            }
-                            };
+                    XmlSnapshotManager manager = new XmlSnapshotManager(new Hashtable(), base);
                     System.err.println("configuring with " + manager);
                     pf.configureSnapshotManager(manager);
                     System.err.println("configuring with " + manager);
                     pf.configureSnapshotManager(manager);
-                    */
-                    pf.configureSnapshotManager(new SnapshotManager(new JS.Obj(), base));
-                    //pf.configureClassLoader(JSTransaction.class.getClassLoader());
                     prevayler = pf.create();
                     prevaylers.put(cx, prevayler);
                     new SnapshotThread(cx).start();
                     prevayler = pf.create();
                     prevaylers.put(cx, prevayler);
                     new SnapshotThread(cx).start();
index 0265e23..80545be 100644 (file)
@@ -15,29 +15,11 @@ import com.thoughtworks.xstream.*;
 import org.prevayler.*;
 import org.prevayler.implementation.snapshot.*;
 
 import org.prevayler.*;
 import org.prevayler.implementation.snapshot.*;
 
-public class Servlet extends HttpServlet {
+public class Servlet extends Prevalence.PrevalentServlet {
 
     public static final JS METHOD = new JS.Method();
     private ServletScope servletscope = null;
     private String path;
 
     public static final JS METHOD = new JS.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);
-        prevalent = (JS)prevayler.prevalentSystem();
-    }
 
     public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { doGet(request, response); }
     public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
 
     public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { doGet(request, response); }
     public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
index e941364..f8c4e8d 100644 (file)
@@ -134,6 +134,7 @@ public class Template extends Node.Stream.Filter implements Node.Stream.Functor
                 JSArray a = ((JSArray)exec("return (" + n.attr("in").toString() + ");", this.scope = s));
                 while(true) {
                     JS o = a.call(JSU.S("pop"), new JS[] { });
                 JSArray a = ((JSArray)exec("return (" + n.attr("in").toString() + ");", this.scope = s));
                 while(true) {
                     JS o = a.call(JSU.S("pop"), new JS[] { });
+                   System.out.println("called pop on a "+a.getClass().getName()+" of length " +a.size()+" , got " + (o==null ? null : o.getClass().getName()));
                     if (o == null) break;
                     array.push(o);
                 }
                     if (o == null) break;
                     array.push(o);
                 }