You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mr...@apache.org on 2009/02/04 02:06:14 UTC

svn commit: r740550 - in /ode/sandbox/simpel: ./ lang/src/main/java/org/apache/ode/ lang/src/main/java/org/apache/ode/embed/ lang/src/main/java/org/apache/ode/simpel/ server/src/main/java/org/apache/ode/ server/src/main/java/org/apache/ode/lifecycle/ s...

Author: mriou
Date: Wed Feb  4 01:06:12 2009
New Revision: 740550

URL: http://svn.apache.org/viewvc?rev=740550&view=rev
Log:
Getting started on the lightweight server environment with SimPEL and RESTful goodness injected.

Added:
    ode/sandbox/simpel/server/src/test/
    ode/sandbox/simpel/server/src/test/java/
    ode/sandbox/simpel/server/src/test/java/org.apache.ode.lifecycle/
    ode/sandbox/simpel/server/src/test/java/org.apache.ode.lifecycle/TestLifecycle.java
    ode/sandbox/simpel/server/src/test/resources/
    ode/sandbox/simpel/server/src/test/resources/log4j.properties
    ode/sandbox/simpel/server/src/test/resources/marker
Modified:
    ode/sandbox/simpel/Rakefile
    ode/sandbox/simpel/lang/src/main/java/org/apache/ode/Descriptor.java
    ode/sandbox/simpel/lang/src/main/java/org/apache/ode/EmbeddedServer.java
    ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedProcessConf.java
    ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedStore.java
    ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/ServerLifecycle.java
    ode/sandbox/simpel/lang/src/main/java/org/apache/ode/simpel/SimPELCompiler.java
    ode/sandbox/simpel/server/src/main/java/org/apache/ode/StandaloneServer.java
    ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/ScriptBasedStore.java
    ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/StandaloneLifecycle.java

Modified: ode/sandbox/simpel/Rakefile
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/Rakefile?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/Rakefile (original)
+++ ode/sandbox/simpel/Rakefile Wed Feb  4 01:06:12 2009
@@ -27,9 +27,12 @@
 ANTLR_TEMPLATE      = "org.antlr:stringtemplate:jar:3.0"
 ASM                 = "asm:asm:jar:3.1"
 COMMONS             = struct(
+  :collections      =>"commons-collections:commons-collections:jar:3.1",
+  :lang             =>"commons-lang:commons-lang:jar:2.1",
   :logging          =>"commons-logging:commons-logging:jar:1.1",
-  :lang             =>"commons-lang:commons-lang:jar:2.1"
+  :primitives       =>"commons-primitives:commons-primitives:jar:1.0"
 )
+DERBY               = "org.apache.derby:derby:jar:10.4.1.3"
 GERONIMO            = struct(
   :kernel           =>"org.apache.geronimo.modules:geronimo-kernel:jar:2.0.1",
   :transaction      =>"org.apache.geronimo.components:geronimo-transaction:jar:2.0.1",
@@ -39,14 +42,18 @@
 JAVAX               = struct(
   :transaction      =>"org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1",
   :resource         =>"org.apache.geronimo.specs:geronimo-j2ee-connector_1.5_spec:jar:1.0",
+  :persistence      =>"javax.persistence:persistence-api:jar:1.0",
   :rest             =>"javax.ws.rs:jsr311-api:jar:1.0"
 )
 JERSEY              = group("jersey-server", "jersey-client", "jersey-core", :under=>"com.sun.jersey", :version=>"1.0.1")
 JETTY               = group("jetty", "jetty-util", "servlet-api-2.5", :under=>"org.mortbay.jetty", :version=>"6.1.11")
 LOG4J               = "log4j:log4j:jar:1.2.15"
-ODE                 = group("ode-bpel-api", "ode-bpel-compiler", "ode-bpel-dao", "ode-runtimes", 
+ODE                 = group("ode-bpel-api", "ode-bpel-compiler", "ode-bpel-dao", "ode-dao-jpa", "ode-runtimes", 
                             "ode-engine", "ode-il-common", "ode-jacob", "ode-scheduler-simple", 
                             "ode-utils", :under=>"org.apache.ode", :version=>"1.3-SNAPSHOT")
+OPENJPA             = ["org.apache.openjpa:openjpa:jar:1.1.0",
+                       "net.sourceforge.serp:serp:jar:1.13.1"]
+TRANQL              = [ "tranql:tranql-connector:jar:1.1", "axion:axion:jar:1.0-M3-dev", COMMONS.primitives ]
 WSDL4J              = "wsdl4j:wsdl4j:jar:1.6.2"
 XERCES              = "xerces:xercesImpl:jar:2.8.1"
 
@@ -104,6 +111,10 @@
   define 'server' do
     compile.with projects("lang"), ODE, 
       LOG4J, JAVAX.transaction
+    test.with JAVAX.resource, COMMONS.lang, COMMONS.logging, LOG4J, WSDL4J, ASM, JERSEY, 
+      DERBY, TRANQL, OPENJPA, GERONIMO.transaction, GERONIMO.connector, JAVAX.persistence,
+      JAVAX.rest, JETTY, XERCES, ANTLR, ANTLR_TEMPLATE, local_libs, COMMONS.collections, 
+      local_libs
     package :jar
   end
 

Modified: ode/sandbox/simpel/lang/src/main/java/org/apache/ode/Descriptor.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/lang/src/main/java/org/apache/ode/Descriptor.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/lang/src/main/java/org/apache/ode/Descriptor.java (original)
+++ ode/sandbox/simpel/lang/src/main/java/org/apache/ode/Descriptor.java Wed Feb  4 01:06:12 2009
@@ -7,6 +7,7 @@
 
     private String address;
     private boolean restful = true;
+    private boolean inmem = false;
 
     /**
      * @return address of the root RESTful resource that the process implements. 
@@ -38,4 +39,16 @@
     public void setRestful(boolean restful) {
         this.restful = restful;
     }
+
+    /**
+     * True for in-memory processes. The execution of a transient process won't touch the database.
+     * @return
+     */
+    public boolean isTransient() {
+        return inmem;
+    }
+
+    public void setTransient(boolean t) {
+        inmem = t;
+    }
 }

Modified: ode/sandbox/simpel/lang/src/main/java/org/apache/ode/EmbeddedServer.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/lang/src/main/java/org/apache/ode/EmbeddedServer.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/lang/src/main/java/org/apache/ode/EmbeddedServer.java (original)
+++ ode/sandbox/simpel/lang/src/main/java/org/apache/ode/EmbeddedServer.java Wed Feb  4 01:06:12 2009
@@ -50,6 +50,7 @@
     public void start(Options options) {
         this.options = options;
         _resources = new ServerLifecycle(options);
+        _resources.start();
     }
 
     public void stop() {

Modified: ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedProcessConf.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedProcessConf.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedProcessConf.java (original)
+++ ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedProcessConf.java Wed Feb  4 01:06:12 2009
@@ -9,6 +9,7 @@
 import org.apache.ode.bpel.iapi.EndpointReference;
 import org.apache.ode.bpel.iapi.ProcessConf;
 import org.apache.ode.bpel.evt.BpelEvent;
+import org.apache.ode.Descriptor;
 import org.w3c.dom.Node;
 import org.w3c.dom.Element;
 
@@ -21,11 +22,12 @@
 public class EmbeddedProcessConf implements ProcessConf {
     private static final String SIMPEL_ENDPOINT_NS = "http://ode.apache.org/simpel/1.0/endpoint";
 
-    private OProcess _oprocess;
+    private ProcessModel _oprocess;
+    private Descriptor _desc;
 
-
-    public EmbeddedProcessConf(OProcess _oprocess) {
-        this._oprocess = _oprocess;
+    public EmbeddedProcessConf(ProcessModel oprocess, Descriptor desc) {
+        _oprocess = oprocess;
+        _desc = desc;
     }
 
     public QName getProcessId() {
@@ -43,7 +45,7 @@
     }
 
     public boolean isTransient() {
-        return true;
+        return _desc.isTransient();
     }
 
     public boolean isRestful() {

Modified: ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedStore.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedStore.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedStore.java (original)
+++ ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/EmbeddedStore.java Wed Feb  4 01:06:12 2009
@@ -44,9 +44,10 @@
  */
 public class EmbeddedStore implements ProcessStore {
 
-    private HashMap<QName, OProcess> _processes = new HashMap<QName, OProcess>();
-    private SimPELCompiler _compiler = new SimPELCompiler();
+    protected SimPELCompiler _compiler = new SimPELCompiler();
     private ArrayList<ProcessStoreListener> _listeners = new ArrayList<ProcessStoreListener>();
+    protected HashMap<QName, ProcessModel> _processes = new HashMap<QName, ProcessModel>();
+    protected HashMap<QName, Descriptor> _descriptors = new HashMap<QName, Descriptor>();
 
     public Collection<QName> deploy(String processStr, Descriptor desc) {
         OProcess op = null;
@@ -56,7 +57,8 @@
             System.err.println("There were errors during the compilation of a SimPEL process:\n" + e.toString());
         }
         _processes.put(op.getQName(), op);
-        
+        _descriptors.put(op.getQName(), desc);
+
         fireEvent(new ProcessStoreEvent(ProcessStoreEvent.Type.DEPLOYED, op.getQName(), null));        
         fireEvent(new ProcessStoreEvent(ProcessStoreEvent.Type.ACTIVATED, op.getQName(), null));
         
@@ -74,7 +76,7 @@
     }
 
     public ProcessConf getProcessConfiguration(QName processId) {
-        return new EmbeddedProcessConf(_processes.get(processId));
+        return new EmbeddedProcessConf(_processes.get(processId), _descriptors.get(processId));
     }
 
     public void registerListener(ProcessStoreListener psl) {
@@ -85,7 +87,6 @@
         _listeners.remove(psl);
     }
 
-
     // boilerplate
 
     public Collection<QName> deploy(File bpelFile) {

Modified: ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/ServerLifecycle.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/ServerLifecycle.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/ServerLifecycle.java (original)
+++ ode/sandbox/simpel/lang/src/main/java/org/apache/ode/embed/ServerLifecycle.java Wed Feb  4 01:06:12 2009
@@ -20,9 +20,7 @@
 
 import javax.sql.DataSource;
 import javax.transaction.TransactionManager;
-import java.sql.Connection;
-import java.sql.Statement;
-import java.sql.SQLException;
+import java.sql.*;
 import java.util.List;
 import java.util.Properties;
 import java.util.concurrent.ExecutorService;
@@ -49,7 +47,9 @@
         _options = options;
         if (_options.getThreadPoolMaxSize() <= 0) _executorService = Executors.newCachedThreadPool();
         else _executorService = Executors.newFixedThreadPool(_options.getThreadPoolMaxSize());
+    }
 
+    public void start() {
         __log.debug("Initializing transaction manager");
         initTxMgr();
         __log.debug("Creating data source.");
@@ -59,7 +59,7 @@
         __log.debug("Initializing BPEL process store.");
         initProcessStore();
 
-        if (options.isRestful()) initRestfulServer();
+        if (_options.isRestful()) initRestfulServer();
 
         __log.debug("Initializing BPEL server.");
         initBpelServer();
@@ -134,14 +134,39 @@
         // TODO as long as we're using HSQL that's fine, afterward...
         Connection conn = null;
         Statement stmt = null;
+        ResultSet result = null;
         try {
             conn = _ds.getConnection();
-            stmt = conn.createStatement();
-            stmt.execute(SCHEDULER_DDL);
+            DatabaseMetaData metaData = conn.getMetaData();
+            if (metaData != null) {
+                result = metaData.getTables("APP", null, "ODE_JOB", null);
+
+                if (!result.next()) {
+                    String dbProductName = metaData.getDatabaseProductName();
+                    if (dbProductName.indexOf("Derby") > 0) {
+                        stmt = conn.createStatement();
+                        stmt.execute(DERBY_SCHEDULER_DDL1);
+                        stmt.close();
+                        stmt = conn.createStatement();
+                        stmt.execute(DERBY_SCHEDULER_DDL2);
+                        stmt.close();
+                        stmt = conn.createStatement();
+                        stmt.execute(DERBY_SCHEDULER_DDL3);
+                        stmt.close();
+                    }
+                    if (dbProductName.indexOf("hsql") > 0) {
+                        stmt = conn.createStatement();
+                        stmt.execute(HSQL_SCHEDULER_DDL);
+                    }
+                }
+            }
+
         } catch (SQLException e) {
-            throw new RuntimeException("Couldn't create the scheduler schema!", e);
+            // Swallowing it, either it already exists in which case we don't care or
+            // creation failed and we'll find out soon enough
         } finally {
             try {
+                if (result != null) result.close();
                 if (stmt != null) stmt.close();
                 if (conn != null) conn.close();
             } catch (SQLException se) {
@@ -186,7 +211,7 @@
         }
     }
 
-    private class ProcessStoreListenerImpl implements ProcessStoreListener {
+    public class ProcessStoreListenerImpl implements ProcessStoreListener {
         public void onProcessStoreEvent(ProcessStoreEvent event) {
             handleEvent(event);
         }
@@ -220,59 +245,28 @@
         return _server;
     }
 
-    private static final String SCHEDULER_DDL =
+    private static final String HSQL_SCHEDULER_DDL =
             "CREATE TABLE ODE_JOB (" +
-                    "  jobid CHAR(64) DEFAULT '' NOT NULL," +
-                    "  ts BIGINT DEFAULT 0 NOT NULL ," +
-                    "  nodeid char(64)  NULL," +
-                    "  scheduled int DEFAULT 0 NOT NULL," +
-                    "  transacted int DEFAULT 0 NOT NULL," +
-                    "  details LONGVARBINARY NULL," +
-                    "  PRIMARY KEY(jobid));" +
-                    "CREATE INDEX IDX_ODE_JOB_TS ON ODE_JOB (ts);" +
+                    " jobid CHAR(64) DEFAULT '' NOT NULL," +
+                    " ts BIGINT DEFAULT 0 NOT NULL ," +
+                    " nodeid char(64)  NULL," +
+                    " scheduled int DEFAULT 0 NOT NULL," +
+                    " transacted int DEFAULT 0 NOT NULL," +
+                    " details LONGVARBINARY NULL," +
+                    " PRIMARY KEY(jobid));\n" +
+                    "CREATE INDEX IDX_ODE_JOB_TS ON ODE_JOB (ts);\n" +
                     "CREATE INDEX IDX_ODE_JOB_NODEID ON ODE_JOB (nodeid);";
 
-    // TODO MEX interceptors
-//    private void registerMexInterceptors() {
-//        String listenersStr = _options.getMessageExchangeInterceptors();
-//        if (listenersStr != null) {
-//            for (StringTokenizer tokenizer = new StringTokenizer(listenersStr, ",;"); tokenizer.hasMoreTokens();) {
-//                String interceptorCN = tokenizer.nextToken();
-//                try {
-//                    _server.registerMessageExchangeInterceptor((MessageExchangeInterceptor) Class.forName(interceptorCN).newInstance());
-//                    __log.info(__msgs.msgMessageExchangeInterceptorRegistered(interceptorCN));
-//                } catch (Exception e) {
-//                    __log.warn("Couldn't register the event listener " + interceptorCN + ", the class couldn't be "
-//                            + "loaded properly: " + e);
-//                }
-//            }
-//        }
-//    }
-//
-      // TODO extension activities
-//    private void registerExtensionActivityBundles() {
-//        String extensionsStr = _options.getExtensionActivityBundles();
-//        if (extensionsStr != null) {
-//            Map<QName, ExtensionValidator> validators = new HashMap<QName, ExtensionValidator>();
-//            for (StringTokenizer tokenizer = new StringTokenizer(extensionsStr, ",;"); tokenizer.hasMoreTokens();) {
-//                String bundleCN = tokenizer.nextToken();
-//                try {
-//                    // instantiate bundle
-//                    AbstractExtensionBundle bundle = (AbstractExtensionBundle) Class.forName(bundleCN).newInstance();
-//
-//                    // register extension bundle (BPEL server)
-//                    _server.registerExtensionBundle(bundle);
-//
-//                    //add validators
-//                    validators.putAll(bundle.getExtensionValidators());
-//                } catch (Exception e) {
-//                    __log.warn("Couldn't register the extension bundle " + bundleCN + ", the class couldn't be " +
-//                            "loaded properly.");
-//                }
-//            }
-//            // register extension bundle (BPEL store)
-//            _store.setExtensionValidators(validators);
-//        }
-//    }
+    private static final String DERBY_SCHEDULER_DDL1 =
+            "CREATE TABLE ODE_JOB (" +
+                    " jobid CHAR(64) DEFAULT '' NOT NULL," +
+                    " ts BIGINT DEFAULT 0 NOT NULL ," +
+                    " nodeid char(64)," +
+                    " scheduled int DEFAULT 0 NOT NULL," +
+                    " transacted int DEFAULT 0 NOT NULL," +
+                    " details BLOB(50K)," +
+                    " PRIMARY KEY (jobid))";
+    private static final String DERBY_SCHEDULER_DDL2 = "CREATE INDEX IDX_ODE_JOB_TS ON ODE_JOB (ts)";
+    private static final String DERBY_SCHEDULER_DDL3 = "CREATE INDEX IDX_ODE_JOB_NODEID ON ODE_JOB (nodeid)";
 
 }

Modified: ode/sandbox/simpel/lang/src/main/java/org/apache/ode/simpel/SimPELCompiler.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/lang/src/main/java/org/apache/ode/simpel/SimPELCompiler.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/lang/src/main/java/org/apache/ode/simpel/SimPELCompiler.java (original)
+++ ode/sandbox/simpel/lang/src/main/java/org/apache/ode/simpel/SimPELCompiler.java Wed Feb  4 01:06:12 2009
@@ -16,6 +16,7 @@
 import org.apache.ode.Descriptor;
 import org.mozilla.javascript.Context;
 import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.NativeObject;
 import org.mozilla.javascript.serialize.ScriptableOutputStream;
 import org.mozilla.javascript.serialize.ScriptableInputStream;
 import uk.co.badgersinfoil.e4x.antlr.*;
@@ -49,13 +50,16 @@
         String header = processDoc.substring(0, m.start());
         String processDef = processDoc.substring(m.start(), processDoc.length());
 
-        OProcess model = buildModel(processDef, desc);
+        byte[] globals = null;
         if (header.trim().length() > 0)
-            model.globalState = buildGlobalState(header);
+            globals = buildGlobalState(header, desc);
+
+        OProcess model = buildModel(processDef, desc);
+        if (globals != null) model.globalState = globals;
         return model;
     }
 
-    private byte[] buildGlobalState(String header) {
+    private byte[] buildGlobalState(String header, Descriptor desc) {
         Context cx = Context.enter();
         cx.setOptimizationLevel(-1);
         Scriptable sharedScope = cx.initStandardObjects();
@@ -64,10 +68,16 @@
         newScope.setPrototype(sharedScope);
         newScope.setParentScope(null);
 
+        // Setting the configuration hash first
+        cx.evaluateString(newScope, "var processConfig = {};", "<cmd>", 1, null);
         cx.evaluateString(newScope, header, "<cmd>", 1, null);
 
+        NativeObject processConf = (NativeObject) cx.evaluateString(newScope, "processConfig;", "<cmd>", 1, null);
+        if (desc.getAddress() == null && processConf.has("address", null)) desc.setAddress((String) processConf.get("address", null));
+        if (processConf.has("inMem", null)) desc.setTransient((Boolean) processConf.get("inMem", null));
+
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ScriptableOutputStream out = null;
+        ScriptableOutputStream out;
         try {
             out = new ScriptableOutputStream(baos, sharedScope);
             out.writeObject(newScope);

Modified: ode/sandbox/simpel/server/src/main/java/org/apache/ode/StandaloneServer.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/server/src/main/java/org/apache/ode/StandaloneServer.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/server/src/main/java/org/apache/ode/StandaloneServer.java (original)
+++ ode/sandbox/simpel/server/src/main/java/org/apache/ode/StandaloneServer.java Wed Feb  4 01:06:12 2009
@@ -4,14 +4,18 @@
 
 import org.apache.ode.lifecycle.StandaloneLifecycle;
 
+import java.io.File;
+
 public class StandaloneServer {
     private static final Logger __log = Logger.getLogger(StandaloneServer.class);
 
     public Options options;
     protected StandaloneLifecycle _resources;
+    protected File _serverRoot;
 
-    public StandaloneServer() {
+    public StandaloneServer(File serverRoot) {
         this.options = new Options();
+        _serverRoot = serverRoot;
     }
 
     public void start() {
@@ -20,7 +24,8 @@
 
     public void start(Options options) {
         this.options = options;
-        _resources = new StandaloneLifecycle(options);
+        _resources = new StandaloneLifecycle(_serverRoot, options);
+        _resources.start();
     }
 
     public void stop() {
@@ -28,7 +33,18 @@
     }
 
     public static void main(String[] args) {
-        StandaloneServer server = new StandaloneServer();
+        if (args.length == 0) {
+            System.err.println("Please pass the location of the root directory as first parameter.");
+            return;
+        }
+
+        File serverRoot = new File(args[0]);
+        if (!serverRoot.exists()) {
+            System.err.println("The provided root directory doesn't seem to exist. It's going to be hard to start.");
+            return;
+        }
+
+        StandaloneServer server = new StandaloneServer(serverRoot);
         server.start();
     }
 }

Modified: ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/ScriptBasedStore.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/ScriptBasedStore.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/ScriptBasedStore.java (original)
+++ ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/ScriptBasedStore.java Wed Feb  4 01:06:12 2009
@@ -1,21 +1,32 @@
 package org.apache.ode.lifecycle;
 
 import org.apache.ode.embed.EmbeddedStore;
+import org.apache.ode.embed.EmbeddedProcessConf;
+import org.apache.ode.bpel.rapi.Serializer;
+import org.apache.ode.bpel.rapi.ProcessModel;
+import org.apache.ode.bpel.iapi.ProcessStoreEvent;
+import org.apache.ode.bpel.iapi.ProcessConf;
+import org.apache.ode.simpel.CompilationException;
+import org.apache.ode.Descriptor;
+import org.apache.log4j.Logger;
 
-import java.io.File;
-import java.io.FileFilter;
-import java.util.HashMap;
+import javax.xml.namespace.QName;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.List;
 
 public class ScriptBasedStore extends EmbeddedStore {
+    private static final Logger __log = Logger.getLogger(ScriptBasedStore.class);
 
     private File _scriptsDir;
     private File _workDir;
 
-    public ScriptBasedStore(File _scriptsDir) {
-        this._scriptsDir = _scriptsDir;
-        new ScriptPoller();
+    public ScriptBasedStore(File scriptsDir, File workDir) {
+        _scriptsDir = scriptsDir;
+        _workDir = workDir;
+        Thread poller = new Thread(new ScriptPoller());
+        poller.setDaemon(true);
+        poller.start();
     }
 
     private class ScriptPoller implements Runnable {
@@ -31,8 +42,89 @@
         };
 
         public void run() {
-            List<File> scripts = listFilesRecursively(_scriptsDir, _scriptsFilter);
-            List<File> cbps = listFilesRecursively(_workDir, _cbpFilter);
+            while (true) {
+                try {
+                    List<File> scripts = listFilesRecursively(_scriptsDir, _scriptsFilter);
+                    List<File> cbps = listFilesRecursively(_workDir, _cbpFilter);
+
+                    // This whole mumbo jumbo is just about populating these lists
+                    List<File> newer = new ArrayList<File>();
+                    List<File> unknown = new ArrayList<File>();
+                    List<File> removed = new ArrayList<File>(cbps);
+
+                    for (File script : scripts) {
+                        String scriptRelative = noExt(relativePath(_scriptsDir, script));
+
+                        boolean found = false;
+                        for (File cbp : cbps) {
+                            String cbpRelative = noExt(relativePath(_workDir, cbp));
+                            if (scriptRelative.equals(cbpRelative)) {
+                                found = true;
+                                removed.remove(cbp);
+                                if (cbp.lastModified() < script.lastModified())
+                                    newer.add(script);
+                            }
+                        }
+
+                        if (!found) unknown.add(script);
+                    }
+
+                    ArrayList<File> toRebuild = new ArrayList<File>(unknown);
+                    toRebuild.addAll(newer);
+                    for (File p : toRebuild) {
+                        ProcessModel oprocess = compileProcess(p);
+                        fireEvent(new ProcessStoreEvent(ProcessStoreEvent.Type.DEPLOYED, oprocess.getQName(), null));
+                        fireEvent(new ProcessStoreEvent(ProcessStoreEvent.Type.ACTIVATED, oprocess.getQName(), null));
+                    }
+                    for (File p : removed) {
+                        Serializer ser = new Serializer(new FileInputStream(p));
+                        ProcessModel oprocess = ser.readPModel();
+                        fireEvent(new ProcessStoreEvent(ProcessStoreEvent.Type.UNDEPLOYED, oprocess.getQName(), null));
+                        _processes.remove(oprocess.getQName());
+                        p.delete();
+                    }
+
+                    try {
+                        Thread.sleep(2000);
+                    } catch (InterruptedException e) {
+                        // whatever
+                        e.printStackTrace();
+                    }
+                } catch (Throwable t) {
+                    __log.info(t.toString() + "\nDeployment aborted.", t);
+                }
+            }
+        }
+
+        private ProcessModel compileProcess(File pfile) throws IOException {
+            File targetCbp = new File(_workDir, noExt(relativePath(_scriptsDir, pfile)) + ".cbp");
+            targetCbp.getParentFile().mkdirs();
+
+            String thisLine;
+            StringBuffer scriptCnt = new StringBuffer();
+            BufferedReader r = new BufferedReader(new FileReader(pfile));
+            while ((thisLine = r.readLine()) != null) scriptCnt.append(thisLine).append("\n");
+            r.close();
+
+            ProcessModel oprocess;
+            try {
+                FileOutputStream cbpFos = new FileOutputStream(targetCbp, false);
+                Descriptor desc = new Descriptor();
+                oprocess = _compiler.compileProcess(scriptCnt.toString(), desc);
+                Serializer ser = new Serializer();
+                ser.writePModel(oprocess, cbpFos);
+                cbpFos.close();
+
+                _processes.put(oprocess.getQName(), oprocess);
+                _descriptors.put(oprocess.getQName(), desc);
+
+                fireEvent(new ProcessStoreEvent(ProcessStoreEvent.Type.DEPLOYED, oprocess.getQName(), null));
+                fireEvent(new ProcessStoreEvent(ProcessStoreEvent.Type.ACTIVATED, oprocess.getQName(), null));
+            } catch (CompilationException e) {
+                throw new RuntimeException("There were errors during the compilation of a SimPEL process:\n" + e.toString());
+            }
+
+            return oprocess;
         }
 
         private ArrayList<File> listFilesRecursively(File root, FileFilter filter) {
@@ -51,6 +143,20 @@
             return result;
         }
 
+        /**
+         * Path of a file relative to a directory. The file has to be (indirectly) contained
+         * in that directory.
+         */
+        private String relativePath(File toDir, File fromFile) {
+            if (!fromFile.equals(toDir)) {
+                File parent = fromFile.getParentFile();
+                return relativePath(toDir, parent) + "/" + fromFile.getName();
+            } else return "";
+        }
+
+        private String noExt(String f) {
+            return f.substring(0, f.lastIndexOf("."));
+        }
     }
 
 }

Modified: ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/StandaloneLifecycle.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/StandaloneLifecycle.java?rev=740550&r1=740549&r2=740550&view=diff
==============================================================================
--- ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/StandaloneLifecycle.java (original)
+++ ode/sandbox/simpel/server/src/main/java/org/apache/ode/lifecycle/StandaloneLifecycle.java Wed Feb  4 01:06:12 2009
@@ -8,36 +8,52 @@
 import org.apache.log4j.Logger;
 
 import java.util.Properties;
-import java.io.File;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipEntry;
+import java.io.*;
 
 public class StandaloneLifecycle extends ServerLifecycle {
+    
     private static final Logger __log = Logger.getLogger(StandaloneLifecycle.class);
 
-    protected String _scriptsDir;
-    protected String _workDir;
-    protected String _derbyZip;
+    protected File _scriptsDir;
+    protected File _workDir;
+    protected File _derbyDir;
 
-    public StandaloneLifecycle(Options options) {
+    public StandaloneLifecycle(File serverRoot, Options options) {
         super(options);
-        _scriptsDir = System.getProperty("simpel.scripts");
+
+        String sysScriptsDir = System.getProperty("simplex.script.dir");
+        _scriptsDir = sysScriptsDir != null ? new File(sysScriptsDir) : new File(serverRoot, "scripts");
+        if (!_scriptsDir.exists()) _scriptsDir.mkdirs();
+
+        String sysWorkDir = System.getProperty("simplex.work.dir");
+        _workDir = sysWorkDir != null ? new File(sysWorkDir) : new File(serverRoot, "work");
+        if (!_workDir.exists()) _workDir.mkdirs();
+
+        String sysDerbyZipDir = System.getProperty("simplex.db.dir");
+        _derbyDir = sysDerbyZipDir != null ? new File(sysDerbyZipDir) : new File(_workDir, "db");
     }
 
     protected void initDataSource() {
-        prepareDerby();
-        Properties odeProps = new Properties();
-        odeProps.setProperty(OdeConfigProperties.PROP_DB_EMBEDDED_NAME, "derby");
-
-        OdeConfigProperties odeConfig = new OdeConfigProperties(odeProps, "");
-        _db = new Database(odeConfig);
-        _db.setTransactionManager(_txMgr);
-        _db.setWorkRoot(new File(_workDir));
-
         try {
+            Properties p = new Properties();
+            if (!_derbyDir.exists()) {
+                p.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=false)");
+                p.put(OdeConfigProperties.PROP_DB_EMBEDDED_CREATE, "true");
+            }
+            p.put(OdeConfigProperties.PROP_DB_EMBEDDED_NAME, "db");
+
+            OdeConfigProperties odeConfig = new OdeConfigProperties(p, "");
+            _db = new Database(odeConfig);
+            _db.setTransactionManager(_txMgr);
+            _db.setWorkRoot(_workDir);
+
             _db.start();
+            _ds = _db.getDataSource();
         } catch (Exception ex) {
             throw new RuntimeException("Database initialization failed.", ex);
         }
-
     }
 
     protected void initDAO() {
@@ -49,9 +65,8 @@
     }
 
     protected void initProcessStore() {
+        _store = new ScriptBasedStore(_scriptsDir, _workDir);
+        _store.registerListener(new ProcessStoreListenerImpl());
     }
 
-    protected void prepareDerby() {
-        // Unzips Derby in the working directory if it isn't already
-    }
 }

Added: ode/sandbox/simpel/server/src/test/java/org.apache.ode.lifecycle/TestLifecycle.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/server/src/test/java/org.apache.ode.lifecycle/TestLifecycle.java?rev=740550&view=auto
==============================================================================
--- ode/sandbox/simpel/server/src/test/java/org.apache.ode.lifecycle/TestLifecycle.java (added)
+++ ode/sandbox/simpel/server/src/test/java/org.apache.ode.lifecycle/TestLifecycle.java Wed Feb  4 01:06:12 2009
@@ -0,0 +1,55 @@
+package org.apache.ode.lifecycle;
+
+import junit.framework.TestCase;
+import org.apache.ode.StandaloneServer;
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.ClientResponse;
+
+public class TestLifecycle extends TestCase {
+
+    private static final String HELLO_WORLD =
+            "processConfig.address = \"/hello\";\n" +
+
+            "process HelloWorld { \n" +
+            "   receive(self) { |name| \n" +
+            "       helloXml = <hello>{\"Hello \" + name}</hello>; \n" +
+            "       reply(helloXml); \n" +
+            "   }\n" +
+            "}";
+
+    public void testFSDeploy() throws Exception {
+        String rootDir = new File(getClass().getClassLoader().getResource("marker").getFile()).getParent();
+        StandaloneServer.main(new String[] { rootDir });
+
+        File pfile = new File(rootDir, "scripts/helloworld.simpel");
+        FileOutputStream fos = new FileOutputStream(pfile);
+        fos.write(HELLO_WORLD.getBytes());
+        fos.close();
+
+        Thread.sleep(3000);
+        ClientConfig cc = new DefaultClientConfig();
+        Client c = Client.create(cc);
+
+        WebResource wr = c.resource("http://localhost:3434/hello");
+        ClientResponse resp = wr.path("/").accept("application/xml").type("application/xml")
+                .post(ClientResponse.class, "<wrapper>foo</wrapper>");
+        String response = resp.getEntity(String.class);
+        System.out.println("=> " + response);
+        assertTrue(response.indexOf("Hello foo") > 0);
+        assertTrue(resp.getMetadata().get("Location").get(0), resp.getMetadata().get("Location").get(0).matches(".*/hello/[0-9]*"));
+        assertTrue(resp.getStatus() == 201);
+
+        pfile.delete();
+        Thread.sleep(3000);
+
+        assertTrue(!new File(rootDir, "work/helloworld.cbp").exists());
+    }
+
+}
\ No newline at end of file

Added: ode/sandbox/simpel/server/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/server/src/test/resources/log4j.properties?rev=740550&view=auto
==============================================================================
--- ode/sandbox/simpel/server/src/test/resources/log4j.properties (added)
+++ ode/sandbox/simpel/server/src/test/resources/log4j.properties Wed Feb  4 01:06:12 2009
@@ -0,0 +1,30 @@
+#
+#    Licensed to the Apache Software Foundation (ASF) under one or more
+#    contributor license agreements.  See the NOTICE file distributed with
+#    this work for additional information regarding copyright ownership.
+#    The ASF licenses this file to You under the Apache License, Version 2.0
+#    (the "License"); you may not use this file except in compliance with
+#    the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+
+# Set root logger level to WARN and its only appender to CONSOLE
+log4j.rootLogger=WARN, CONSOLE
+
+# log4j properties to work with commandline tools.
+log4j.category.org.mortbay=ERROR
+log4j.category.org.hibernate.type=WARN
+log4j.category.org.objectweb=ERROR
+log4j.category.org.apache.ode=DEBUG
+
+# Console appender
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%p - %C{1}.%M(%L) | %m%n

Added: ode/sandbox/simpel/server/src/test/resources/marker
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/server/src/test/resources/marker?rev=740550&view=auto
==============================================================================
    (empty)