2bfbfb191c165c7c7ae3b26ac114d53bb1ee65fd
[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.XmlSnapshotManager;
17
18 public class Prevalence {
19
20     public static abstract class PrevalentServlet extends HttpServlet {
21         protected Hashtable prevalent;
22         protected Prevayler prevayler;
23         protected ServletContext cx = null;
24         public void destroy() { try {
25             synchronized(this.getClass()) {
26                 Prevayler privatePrevayler = prevayler;
27                 if (prevayler == null) return;
28                 prevayler = null;
29                 Prevalence.destroy(cx, prevayler);
30             }
31         } catch (Exception e) { e.printStackTrace(); } }
32         
33         public void init(ServletConfig sc) throws ServletException {
34             cx = sc.getServletContext();
35             prevayler = Prevalence.getPrevayler(cx);
36             prevalent = (Hashtable)prevayler.prevalentSystem();
37         }
38     }
39
40     static final Hashtable prevaylers = new Hashtable();
41
42     public static void destroy(ServletContext cx, Prevayler prevayler) { try {
43         prevaylers.remove(cx);
44         prevayler.takeSnapshot();
45         prevayler.close();
46     } catch (Exception e) { e.printStackTrace(); } }
47
48     private static class SnapshotThread extends Thread {
49         ServletContext cx;
50         public SnapshotThread(ServletContext cx) { this.cx = cx; }
51         public void run() {
52             try {
53                 Thread.sleep(10000);
54                 Prevayler privatePrevayler = (Prevayler)prevaylers.get(cx);
55                 if (privatePrevayler == null) return;
56                 privatePrevayler.takeSnapshot();
57             } catch (Exception e) {
58                 e.printStackTrace();
59             }
60         }
61     }
62
63     public static Prevayler getPrevayler(ServletContext cx) {
64         try {
65             Prevayler prevayler;
66             synchronized(cx) {
67                 prevayler = (Prevayler)prevaylers.get(cx);
68                 if (prevayler == null) {
69                     PrevaylerFactory pf = new PrevaylerFactory();
70                     String base = cx.getRealPath("/") + File.separatorChar + "WEB-INF" + File.separatorChar + "prevalent";
71                     System.err.println("prevayling to " + base);
72                     pf.configurePrevalenceBase(base);
73                     XmlSnapshotManager manager = new XmlSnapshotManager(new Hashtable(), base);
74                     System.err.println("configuring with " + manager);
75                     pf.configureSnapshotManager(manager);
76                     prevayler = pf.create();
77                     prevaylers.put(cx, prevayler);
78                     new SnapshotThread(cx).start();
79                 }
80             }
81             return prevayler;
82         } catch (Exception e) { throw new RuntimeException(e); } }
83
84     public static class JSTransaction implements Transaction {
85         public static final long serialVersionUid = 0xfb2aa281;
86         private JS js;
87         Scope newscope;
88         String[] v;
89         public JSTransaction(JS js) throws JSExn {
90             newscope = new Scope(null);
91             this.js = JSU.cloneWithNewGlobalScope(js, newscope);
92             v = this.js.getFormalArgs();
93             for(int i=0; i<v.length; i++) {
94                 if (JSU.S("prevalent").equals(v[i])) continue;
95                 newscope.put(JSU.S(v[i]), js.get(JSU.S(v[i])));
96             }
97         }
98         public void executeOn(Object o, Date now) {
99             try {
100                 newscope.put(JSU.S("prevalent"), (JS)o);
101                 newscope.put(JSU.S("now"), new JSDate(now.getTime()));
102                 JS[] args = new JS[v.length];
103                 for(int i=0; i<v.length; i++) args[i] = JSU.S(v[i]);
104                 js.call(null, args);
105             } catch (Exception e) { throw new RuntimeException(e); }
106         }
107     }
108
109     public static class JSQuery implements Query {
110         public static final long serialVersionUid = 0xfb2aa282;
111         private JS js;
112         private Object a;
113         public JSQuery(JS js, Object a) { this.js = JSU.cloneWithNewGlobalScope(js, null); this.a = a; }
114         public Object query(Object o, Date now) {
115             try {
116                 return js.call(null, new JS[] { (JS)o, (JS)a, new JSDate(now.getTime()) });
117             } catch (Exception e) { throw new RuntimeException(e); }
118         }
119     }
120 }