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