724538623dada971b6b36e54695e79ff018dd29b
[org.ibex.xt.git] / src / org / ibex / xt / Prevalence.java
1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
4
5 package org.ibex.xt;
6 import org.ibex.js.*;
7 import org.ibex.util.*;
8 import org.ibex.io.*;
9 import java.io.*;
10 import java.net.*;
11 import java.util.*;
12 import javax.servlet.*;
13 import javax.servlet.http.*;
14 import com.thoughtworks.xstream.*;
15 import org.prevayler.*;
16 import org.prevayler.implementation.snapshot.*;
17
18 public class Prevalence {
19
20     static final Hashtable prevaylers = new Hashtable();
21
22     public static void destroy(ServletContext cx, Prevayler prevayler) { try {
23         prevaylers.remove(cx);
24         prevayler.takeSnapshot();
25         prevayler.close();
26     } catch (Exception e) { e.printStackTrace(); } }
27
28     private static class SnapshotThread extends Thread {
29         ServletContext cx;
30         public SnapshotThread(ServletContext cx) { this.cx = cx; }
31         public void run() {
32             try {
33                 Thread.sleep(10000);
34                 Prevayler privatePrevayler = (Prevayler)prevaylers.get(cx);
35                 if (privatePrevayler == null) return;
36                 privatePrevayler.takeSnapshot();
37             } catch (Exception e) {
38                 e.printStackTrace();
39             }
40         }
41     }
42
43     public static Prevayler getPrevayler(ServletContext cx) {
44         try {
45             Prevayler prevayler;
46             synchronized(cx) {
47                 prevayler = (Prevayler)prevaylers.get(cx);
48                 if (prevayler == null) {
49                     PrevaylerFactory pf = new PrevaylerFactory();
50                     String base = cx.getRealPath("/") + "WEB-INF" + File.separatorChar + "prevalent";
51                     System.err.println("prevayling to " + base);
52                     pf.configurePrevalenceBase(base);
53                     /*
54                     XmlSnapshotManager manager = new XmlSnapshotManager(new JS(), base, null); {
55                             protected XStream createXStream() {
56                                 XStream xstream = new XStream();
57                                 xstream.alias("js", JS.class);
58                                 xstream.alias("jsdate", JSDate.class);
59                                 return xstream;
60                             }
61                             };
62                     System.err.println("configuring with " + manager);
63                     pf.configureSnapshotManager(manager);
64                     */
65                     pf.configureSnapshotManager(new SnapshotManager(new JS.Obj(), base));
66                     //pf.configureClassLoader(JSTransaction.class.getClassLoader());
67                     prevayler = pf.create();
68                     prevaylers.put(cx, prevayler);
69                     new SnapshotThread(cx).start();
70                 }
71             }
72             return prevayler;
73         } catch (Exception e) { throw new RuntimeException(e); } }
74
75     public static class JSTransaction implements Transaction {
76         public static final long serialVersionUid = 0xfb2aa281;
77         private JS js;
78         Template.Scope newscope;
79         String[] v;
80         public JSTransaction(JS js) throws JSExn {
81             newscope = new Template.Scope(null);
82             this.js = JSU.cloneWithNewGlobalScope(js, newscope);
83             v = this.js.getFormalArgs();
84             for(int i=0; i<v.length; i++) {
85                 if (JSU.S("prevalent").equals(v[i])) continue;
86                 newscope.put(JSU.S(v[i]), js.get(JSU.S(v[i])));
87             }
88         }
89         public void executeOn(Object o, Date now) {
90             try {
91                 newscope.put(JSU.S("prevalent"), (JS)o);
92                 newscope.put(JSU.S("now"), new JSDate(now.getTime()));
93                 JS[] args = new JS[v.length];
94                 for(int i=0; i<v.length; i++) args[i] = JSU.S(v[i]);
95                 js.call(null, args);
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 = JSU.cloneWithNewGlobalScope(js, null); this.a = a; }
105         public Object query(Object o, Date now) {
106             try {
107                 return js.call(null, new JS[] { (JS)o, (JS)a, new JSDate(now.getTime()) });
108             } catch (Exception e) { throw new RuntimeException(e); }
109         }
110     }
111 }