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