4904bbd3db53591e1043fa32623ee8835e086881
[org.ibex.xt-crawshaw.git] / src / ibex / xt / Prevalence.java
1 package ibex.xt;
2
3 import org.ibex.js.*;
4 import ibex.util.*;
5 //import org.ibex.io.*;
6 import java.io.*;
7 import java.net.*;
8 import java.util.*;
9 import javax.servlet.*;
10 import javax.servlet.http.*;
11 //import com.thoughtworks.xstream.*;
12 import org.prevayler.*;
13 import org.prevayler.implementation.snapshot.*;
14
15 public class Prevalence {
16
17     static final Hashtable prevaylers = new Hashtable();
18
19     public static void destroy(ServletContext cx, Prevayler prevayler) { try {
20         prevaylers.remove(cx);
21         prevayler.takeSnapshot();
22         prevayler.close();
23     } catch (Exception e) { e.printStackTrace(); } }
24
25     private static class SnapshotThread extends Thread {
26         ServletContext cx;
27         public SnapshotThread(ServletContext cx) { this.cx = cx; }
28         public void run() {
29             try {
30                 Thread.sleep(10000);
31                 Prevayler privatePrevayler = (Prevayler)prevaylers.get(cx);
32                 if (privatePrevayler == null) return;
33                 privatePrevayler.takeSnapshot();
34             } catch (Exception e) {
35                 e.printStackTrace();
36             }
37         }
38     }
39
40     public static Prevayler getPrevayler(ServletContext cx) {
41         try {
42             Prevayler prevayler;
43             synchronized(cx) {
44                 prevayler = (Prevayler)prevaylers.get(cx);
45                 if (prevayler == null) {
46                     PrevaylerFactory pf = new PrevaylerFactory();
47                     String base = cx.getRealPath("/") + "WEB-INF" + File.separatorChar + "prevalent";
48                     System.err.println("prevayling to " + base);
49                     pf.configurePrevalenceBase(base);
50                     /*
51                     XStreamSnapshotManager manager = new XStreamSnapshotManager(new JS(), base, null) {
52                             protected XStream createXStream() {
53                                 XStream xstream = new XStream();
54                                 xstream.alias("js", JS.class);
55                                 xstream.alias("jsdate", JSDate.class);
56                                 return xstream;
57                             }
58                         };
59                     System.err.println("configuring with " + manager);
60                     pf.configureSnapshotManager(manager);
61                     */
62                     pf.configureSnapshotManager(new SnapshotManager(new JS(), base));
63                     //pf.configureClassLoader(JSTransaction.class.getClassLoader());
64                     prevayler = pf.create();
65                     prevaylers.put(cx, prevayler);
66                     new SnapshotThread(cx).start();
67                 }
68             }
69             return prevayler;
70         } catch (Exception e) { throw new RuntimeException(e); } }
71
72     public static class JSTransaction implements Transaction {
73         public static final long serialVersionUid = 0xfb2aa281;
74         private JS js;
75         JSScope newscope;
76         Vec v;
77         public JSTransaction(JS js) throws JSExn {
78             newscope = new JSScope(null);
79             this.js = JS.cloneWithNewParentScope(js, newscope);
80             v = JS.getFormalArgs(this.js);
81             for(int i=0; i<v.size(); i++) {
82                 if ("prevalent".equals(v.elementAt(i))) continue;
83                 newscope.put(v.elementAt(i), JS.getParentScope(js).get(v.elementAt(i)));
84             }
85         }
86         public void executeOn(Object o, Date now) {
87             try {
88                 newscope.put("prevalent", o);
89                 newscope.put("now", new JSDate(now.getTime()));
90                 Object a = v.size() <= 0 ? null : newscope.get(v.elementAt(0));
91                 Object b = v.size() <= 1 ? null : newscope.get(v.elementAt(1));
92                 Object c = v.size() <= 2 ? null : newscope.get(v.elementAt(2));
93                 Object[] rest = v.size() <= 3 ? null : new Object[v.size() - 3];
94                 for(int i=3; i<v.size(); i++) rest[i-3] = v.elementAt(i);
95                 js.call(a, b, c, rest, v.size());
96             } catch (Exception e) { throw new RuntimeException(e); }
97         }
98     }
99
100     public static class JSQuery implements Query {
101         public static final long serialVersionUid = 0xfb2aa282;
102         private JS js;
103         private Object a;
104         public JSQuery(JS js, Object a) { this.js = JS.cloneWithNewParentScope(js, null); this.a = a; }
105         public Object query(Object o, Date now) {
106             try {
107                 return js.call(o, a, new JSDate(now.getTime()), null, 3);
108             } catch (Exception e) { throw new RuntimeException(e); }
109         }
110     }
111 }