--- /dev/null
+package ibex.xt;
+
+import java.io.*;
+
+import java.net.*;
+import javax.servlet.ServletContext; // FIXME: remove references
+
+import java.util.*;
+import ibex.util.*;
+import ibex.js.*;
+
+import org.prevayler.*;
+import org.prevayler.implementation.snapshot.*;
+//import com.thoughtworks.xstream.*; // FIXME find
+
+public class Prevalence {
+
+ static final Hashtable prevaylers = new Hashtable();
+
+ public static void destroy(ServletContext cx, Prevayler prevayler) { try {
+ prevaylers.remove(cx);
+ prevayler.takeSnapshot();
+ prevayler.close();
+ } catch (Exception e) { e.printStackTrace(); } }
+
+ private static class SnapshotThread extends Thread {
+ ServletContext cx;
+ public SnapshotThread(ServletContext cx) { this.cx = cx; }
+ public void run() {
+ try {
+ Thread.sleep(10000);
+ Prevayler privatePrevayler = (Prevayler)prevaylers.get(cx);
+ if (privatePrevayler == null) return;
+ privatePrevayler.takeSnapshot();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static Prevayler getPrevayler(ServletContext cx) {
+ try {
+ Prevayler prevayler;
+ synchronized(cx) {
+ prevayler = (Prevayler)prevaylers.get(cx);
+ if (prevayler == null) {
+ PrevaylerFactory pf = new PrevaylerFactory();
+ String base = cx.getRealPath("/") + "WEB-INF" + File.separatorChar + "prevalent";
+ System.err.println("prevayling to " + base);
+ pf.configurePrevalenceBase(base);
+ /*
+ XStreamSnapshotManager manager = new XStreamSnapshotManager(new JS(), base, null) {
+ protected XStream createXStream() {
+ XStream xstream = new XStream();
+ xstream.alias("js", JS.class);
+ xstream.alias("jsdate", JSDate.class);
+ return xstream;
+ }
+ };
+ System.err.println("configuring with " + manager);
+ pf.configureSnapshotManager(manager);
+ */
+ pf.configureSnapshotManager(new SnapshotManager(new JS(), base));
+ //pf.configureClassLoader(JSTransaction.class.getClassLoader());
+ prevayler = pf.create();
+ prevaylers.put(cx, prevayler);
+ new SnapshotThread(cx).start();
+ }
+ }
+ return prevayler;
+ } catch (Exception e) { throw new RuntimeException(e); } }
+
+ public static class JSTransaction implements Transaction {
+ public static final long serialVersionUid = 0xfb2aa281;
+ private JS js;
+ JSScope newscope;
+ List v;
+ public JSTransaction(JS js) throws JSExn {
+ newscope = new JSScope(null);
+ this.js = JS.cloneWithNewParentScope(js, newscope);
+ v = JS.getFormalArgs(this.js);
+ for(int i=0; i<v.size(); i++) {
+ if ("prevalent".equals(v.get(i))) continue;
+ newscope.put(v.get(i), JS.getParentScope(js).get(v.get(i)));
+ }
+ }
+ public void executeOn(Object o, Date now) {
+ try {
+ newscope.put("prevalent", o);
+ newscope.put("now", new JSDate(now.getTime()));
+ Object a = v.size() <= 0 ? null : newscope.get(v.get(0));
+ Object b = v.size() <= 1 ? null : newscope.get(v.get(1));
+ Object c = v.size() <= 2 ? null : newscope.get(v.get(2));
+ Object[] rest = v.size() <= 3 ? null : new Object[v.size() - 3];
+ for(int i=3; i<v.size(); i++) rest[i-3] = v.get(i);
+ js.call(a, b, c, rest, v.size());
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+ }
+
+ public static class JSQuery implements Query {
+ public static final long serialVersionUid = 0xfb2aa282;
+ private JS js;
+ private Object a;
+ public JSQuery(JS js, Object a) { this.js = JS.cloneWithNewParentScope(js, null); this.a = a; }
+ public Object query(Object o, Date now) {
+ try {
+ return js.call(o, a, new JSDate(now.getTime()), null, 3);
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+ }
+}