Author: tcurdt
Date: Tue Dec 14 11:01:29 2004
New Revision: 111860

URL: http://svn.apache.org/viewcvs?view=rev&rev=111860
Log:
javaflow: auto-compilation for javaflow.
factored out javaflow and the auto-compilation (jci)
into separate projects.


Added:
   cocoon/trunk/lib/optional/commons-io-1.0.jar   (contents, props changed)
   cocoon/trunk/lib/optional/javaflow-20041213.jar   (contents, props changed)
   cocoon/trunk/lib/optional/jci-20041213.jar   (contents, props changed)
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java
      - copied, changed from r111431, 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationContext.java
   cocoon/trunk/src/blocks/javaflow/javaflow-20041213.tgz   (contents, props 
changed)
   cocoon/trunk/src/blocks/javaflow/jci-20041213.tgz   (contents, props changed)
   cocoon/trunk/src/webapp/WEB-INF/src/
   cocoon/trunk/src/webapp/WEB-INF/src/org/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/components/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/components/flow/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/components/flow/java/
   
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/components/flow/java/AbstractContinuable.java
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/forms/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/forms/flow/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/forms/flow/java/
   
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/forms/flow/java/FormInstance.java
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/
   cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/
   
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/CalculatorFlow.java
   
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/FormFlow.java
   
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/PersistenceFlow.java
Removed:
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/AbstractContinuable.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/Continuable.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/Continuation.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationCapable.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationClassLoader.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationContext.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationHelper.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationStack.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/DecompilingVisitor.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/analyser/
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/javascript/
   cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/forms/
   cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/samples/
   cocoon/trunk/src/blocks/javaflow/test/org/
   
cocoon/trunk/src/blocks/scratchpad/java/org/apache/cocoon/components/flow/groovy/
Modified:
   cocoon/trunk/lib/jars.xml
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMap.java
   
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMapHandler.java
   cocoon/trunk/src/blocks/javaflow/samples/sitemap.xmap
   
cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidClassLoader.java
   
cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java
   cocoon/trunk/src/webapp/WEB-INF/web.xml
   cocoon/trunk/status.xml
   cocoon/trunk/tools/targets/webapp-build.xml

Modified: cocoon/trunk/lib/jars.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/lib/jars.xml?view=diff&rev=111860&p1=cocoon/trunk/lib/jars.xml&r1=111859&p2=cocoon/trunk/lib/jars.xml&r2=111860
==============================================================================
--- cocoon/trunk/lib/jars.xml   (original)
+++ cocoon/trunk/lib/jars.xml   Tue Dec 14 11:01:29 2004
@@ -1070,4 +1070,33 @@
     <homepage>http://jakarta.apache.org/tomcat/</homepage>
   </file>
 
+  <file>
+    <title>Java Compilation Interface API</title>
+    <description>
+      API for compiling java
+    </description>
+    <used-by>javaflow</used-by>
+    <lib>optional/jci-20041213.jar</lib>
+    <homepage></homepage>
+  </file>
+
+  <file>
+    <title>Javaflow API</title>
+    <description>
+      API java continuations
+    </description>
+    <used-by>javaflow</used-by>
+    <lib>optional/javaflow-20041213.jar</lib>
+    <homepage></homepage>
+  </file>
+
+  <file>
+    <title>Jakarta Commons io</title>
+    <description>
+    </description>
+    <used-by>jci</used-by>
+    <lib>optional/commons-io-1.0.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/io/</homepage>
+  </file>
+
 </jars>

Added: cocoon/trunk/lib/optional/commons-io-1.0.jar
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/lib/optional/commons-io-1.0.jar?view=auto&rev=111860
==============================================================================
Binary file. No diff available.

Added: cocoon/trunk/lib/optional/javaflow-20041213.jar
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/lib/optional/javaflow-20041213.jar?view=auto&rev=111860
==============================================================================
Binary file. No diff available.

Added: cocoon/trunk/lib/optional/jci-20041213.jar
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/lib/optional/jci-20041213.jar?view=auto&rev=111860
==============================================================================
Binary file. No diff available.

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/AbstractContinuable.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/AbstractContinuable.java?view=auto&rev=111859
==============================================================================

Copied: 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java
 (from r111431, 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationContext.java)
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java?view=diff&rev=111860&p1=cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationContext.java&r1=111431&p2=cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java&r2=111860
==============================================================================
--- 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationContext.java
       (original)
+++ 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/CocoonContinuationContext.java
 Tue Dec 14 11:01:29 2004
@@ -15,25 +15,21 @@
  */
 package org.apache.cocoon.components.flow.java;
 
-import java.lang.reflect.Method;
-
 import org.apache.avalon.framework.context.Context;
 import org.apache.avalon.framework.logger.Logger;
 import org.apache.avalon.framework.parameters.Parameters;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.cocoon.environment.Redirector;
+import org.apache.javaflow.ContinuationContext;
 
 /**
  * Helper class to associate cocoon flow informations to the continuation.
  *
  * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a>
  * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
- * @version CVS $Id: ContinuationContext.java,v 1.2 2004/06/23 09:16:31 
stephan Exp $
+ * @version CVS $Id$
  */
-public class ContinuationContext {
-
-    private Object object;
-    private Method method;
+public class CocoonContinuationContext extends ContinuationContext {
 
     private Logger logger;
     private Context avalonContext;
@@ -41,25 +37,6 @@
     private Redirector redirector;
     
     private Parameters parameters;
-
-    public ContinuationContext() {
-    }
-
-    public void setObject(Object object) {
-        this.object = object;
-    }
-
-    public Object getObject() {
-        return object;
-    }
-
-    public void setMethod(Method method) {
-        this.method = method;
-    }
-
-    public Method getMethod() {
-        return method;
-    }
 
     public void setAvalonContext(Context avalonContext) {
         this.avalonContext = avalonContext;

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/Continuable.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/Continuable.java?view=auto&rev=111859
==============================================================================

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/Continuation.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/Continuation.java?view=auto&rev=111859
==============================================================================

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationCapable.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationCapable.java?view=auto&rev=111859
==============================================================================

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationClassLoader.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationClassLoader.java?view=auto&rev=111859
==============================================================================

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationContext.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationContext.java?view=auto&rev=111859
==============================================================================

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationHelper.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationHelper.java?view=auto&rev=111859
==============================================================================

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationStack.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/ContinuationStack.java?view=auto&rev=111859
==============================================================================

Deleted: 
/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/DecompilingVisitor.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/DecompilingVisitor.java?view=auto&rev=111859
==============================================================================

Modified: 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java?view=diff&rev=111860&p1=cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java&r1=111859&p2=cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java&r2=111860
==============================================================================
--- 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java
   (original)
+++ 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/JavaInterpreter.java
   Tue Dec 14 11:01:29 2004
@@ -26,19 +26,19 @@
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.avalon.framework.service.ServiceException;
 import org.apache.cocoon.ProcessingException;
 import org.apache.cocoon.components.ContextHelper;
 import org.apache.cocoon.components.flow.AbstractInterpreter;
 import org.apache.cocoon.components.flow.FlowHelper;
 import org.apache.cocoon.components.flow.InvalidContinuationException;
 import org.apache.cocoon.components.flow.WebContinuation;
-import 
org.apache.cocoon.components.flow.javascript.JavaScriptCompilingClassLoader;
 import org.apache.cocoon.environment.Redirector;
 import org.apache.cocoon.environment.Request;
 import org.apache.cocoon.environment.Session;
 import org.apache.cocoon.util.ReflectionUtils;
 import org.apache.commons.jxpath.JXPathIntrospector;
+import org.apache.javaflow.Continuable;
+import org.apache.javaflow.Continuation;
 
 /**
  * Implementation of the java flow interpreter.
@@ -48,8 +48,6 @@
  */
 public class JavaInterpreter extends AbstractInterpreter implements 
Configurable {
 
-    private boolean initialized = false;
-
     private int timeToLive = 600000;
 
     /**
@@ -57,143 +55,70 @@
      */
     public static final String USER_GLOBAL_SCOPE = "JAVA GLOBAL SCOPE";
 
-    private ContinuationClassLoader continuationclassloader;
-
-    private Map methods = new HashMap();
-
-    private JavaScriptCompilingClassLoader javascriptclassloader;
-
     static {
         JXPathIntrospector.registerDynamicClass(VarMap.class, 
VarMapHandler.class);
     }
 
     public void configure(Configuration config) throws ConfigurationException {
         super.configure(config);
-        
-        javascriptclassloader = new 
JavaScriptCompilingClassLoader(Thread.currentThread().getContextClassLoader());
-        try {
-            javascriptclassloader.service(this.manager);
-        } catch (ServiceException e) {
-            throw new ConfigurationException(e.getMessage());
-        }
-        continuationclassloader = new 
ContinuationClassLoader(javascriptclassloader);
-        continuationclassloader.setDebug(config.getAttributeAsBoolean("debug", 
true));
-
-        Configuration[] includes = config.getChildren("include");
-        for (int i = 0; i < includes.length; i++)
-            
continuationclassloader.addIncludeClass(includes[i].getAttribute("class"));
     }
 
-    public synchronized void initialize() throws Exception {
-
-        if (initialized) {
-            return;
-        }
-        if (getLogger().isDebugEnabled())
-            getLogger().debug("initialize java flow interpreter");
-
-        for (Iterator scripts = needResolve.iterator(); scripts.hasNext();) {
-
-            String name = (String) scripts.next();
-
-            if (name.endsWith(".js")) {
-                javascriptclassloader.addSource(name);
-                name = JavaScriptCompilingClassLoader.getClassName(name);
-            }
-
-            System.out.println("registered java class \"" + name + "\" for 
flow");
-            if (getLogger().isDebugEnabled())
-                getLogger().debug("registered java class \"" + name + "\" for 
flow");
-            
-            Class clazz = continuationclassloader.loadClass(name);
-
-            if (!ContinuationCapable.class.isAssignableFrom(clazz)) {
-                getLogger().error("java class \"" + name + "\" doesn't 
implement Continuable");
-                continue;
-            }
-
-            //Class clazz = continuationclassloader.loadClass(name);
-
-            try {
-                final Map m = ReflectionUtils.discoverMethods(clazz);
-                methods.putAll(m);
-            } catch (Exception e) {
-                throw new ConfigurationException("cannot get methods by 
reflection", e);
-            }
-
-        }
-        
-        initialized = true;
+    public void initialize() throws Exception {
     }
 
-    /**
-     * Calls a Java function, passing <code>params</code> as its
-     * arguments. In addition to this, it makes available the parameters
-     * through the <code>cocoon.parameters</code> Java array
-     * (indexed by the parameter names).
-     *
-     * @param function a <code>String</code> value
-     * @param params a <code>List</code> value
-     * @param redirector
-     * @exception Exception if an error occurs
-     */
-    public void callFunction(String function, List params, Redirector 
redirector) throws Exception {
-
-        if (!initialized)
-            initialize();
+    public void continueFlow( final WebContinuation parentwk, final List 
params, final Redirector redirector, final Continuation parentContinuation, 
final CocoonContinuationContext context) throws Exception {
 
-        Method method = (Method) methods.get(function);
-
-        if (method == null) {
-            throw new ProcessingException("No method '" + function + "' found. 
" + methods);
-        }
-
-        if (getLogger().isDebugEnabled())
-            getLogger().debug("calling method \"" + method + "\"");
-
-        Request request = ContextHelper.getRequest(this.avalonContext);
-        Session session = request.getSession(true);
-        HashMap userScopes = (HashMap) session.getAttribute(USER_GLOBAL_SCOPE);
-        if (userScopes == null)
-            userScopes = new HashMap();
-
-        ContinuationCapable flow = (ContinuationCapable) 
userScopes.get(method.getDeclaringClass());
-
-        ContinuationContext context = new ContinuationContext();
-        context.setObject(flow);
-        context.setMethod(method);
         context.setAvalonContext(avalonContext);
         context.setLogger(getLogger());
         context.setServiceManager(manager);
         context.setRedirector(redirector);
-        Parameters parameters = new Parameters();
-        for(Iterator i=params.iterator(); i.hasNext();) {
-               Argument argument = (Argument)i.next();
-               parameters.setParameter(argument.name, argument.value);
+
+        final Parameters parameters = new Parameters();
+        for(Iterator i = params.iterator(); i.hasNext();) {
+            final Argument argument = (Argument)i.next();
+            parameters.setParameter(argument.name, argument.value);
         }
         context.setParameters(parameters);
 
-        Continuation continuation = new Continuation(context);
+        final Continuation continuation = (parentContinuation != null)
+        ? new Continuation(parentContinuation, context)
+        : new Continuation(context);
 
-        WebContinuation wk = continuationsMgr.createWebContinuation(
-                continuation, null, timeToLive, getInterpreterID(), null);
-        
FlowHelper.setWebContinuation(ContextHelper.getObjectModel(this.avalonContext), 
wk);
+        System.out.println("created new continuation " + continuation);
+        if (getLogger().isDebugEnabled()) { 
+            getLogger().debug("created new continuation " + continuation);
+        }
 
+        final WebContinuation wk = continuationsMgr.createWebContinuation(
+                continuation, parentwk, timeToLive, getInterpreterID(), null);
+
+        
FlowHelper.setWebContinuation(ContextHelper.getObjectModel(this.avalonContext), 
wk);
+                
         continuation.registerThread();
-        try {
-            if (flow == null) {
-                if (getLogger().isDebugEnabled())
-                    getLogger().debug("create new instance of \"" + 
method.getDeclaringClass() + "\"");
 
-                flow = (ContinuationCapable) 
method.getDeclaringClass().newInstance();
-                context.setObject(flow);
+        if (parentContinuation != null) {
+            System.out.println("resuming continuation " + continuation + 
continuation.getStack());
+            if (getLogger().isDebugEnabled()) { 
+                getLogger().debug("resuming continuation " + continuation + 
continuation.getStack());
+            }            
+        }
+        
+        try {
+            System.out.println("calling " + context.getMethod());
+            if (getLogger().isDebugEnabled()) { 
+                getLogger().debug("calling " + context.getMethod());
             }
 
-            method.invoke(flow, new Object[0]);
+            context.getMethod().invoke(context.getObject(), new Object[0]);
+
+            System.out.println("back from " + context.getMethod());
+            if (getLogger().isDebugEnabled()) { 
+                getLogger().debug("back from " + context.getMethod());
+            }
 
         } catch (InvocationTargetException ite) {
             if (ite.getTargetException() != null) {
-                if (ite.getTargetException() instanceof Exception)
+                if (ite.getTargetException() instanceof Exception) 
                     throw (Exception) ite.getTargetException();
                 else if (ite.getTargetException() instanceof Error)
                     throw new ProcessingException("An internal error occured", 
ite.getTargetException());
@@ -207,83 +132,109 @@
         } finally {
             // remove last object reference, which is not needed to
             // reconstruct the invocation path
-            if (continuation.isCapturing())
+
+            if (continuation.isCapturing()) {
                 continuation.getStack().popReference();
+            }
+
             continuation.deregisterThread();
+
+            System.out.println("state saved in continuation" + continuation + 
continuation.getStack());                
+            if (getLogger().isDebugEnabled()) { 
+                getLogger().debug("state saved in continuation" + continuation 
+ continuation.getStack());
+            }
         }
-        userScopes.put(method.getDeclaringClass(), flow);
-        session.setAttribute(USER_GLOBAL_SCOPE, userScopes);
+        
     }
+    
+    public void callFunction(String function, List params, Redirector 
redirector) throws Exception {
+
+        final Map methods = new HashMap();
 
-    public void handleContinuation(String id, List params, Redirector 
redirector) throws Exception {
-        if (!initialized)
-            initialize();
+        // REVISIT: this is ugly as hell!
+        // but something better would require an
+        // imcompatible change of the flow handling.
+        // Make sure you don't have overlapping method
+        // names you want to call
+        
+        for (Iterator it = needResolve.iterator(); it.hasNext();) {
+            final String clazzName = (String) it.next();
 
-        WebContinuation parentwk = continuationsMgr.lookupWebContinuation(id, 
getInterpreterID());
+            System.out.println("loading " + clazzName);
+            if (getLogger().isDebugEnabled()) { 
+                getLogger().debug("loading " + clazzName);
+            }        
 
-        if (parentwk == null) {
-        /*
-         * Throw an InvalidContinuationException to be handled inside the
-         * <map:handle-errors> sitemap element.
-         */
-        throw new InvalidContinuationException("The continuation ID " + id + " 
is invalid."); }
-
-        Continuation parentContinuation = (Continuation) 
parentwk.getContinuation();
-        ContinuationContext parentContext = (ContinuationContext) 
parentContinuation.getContext();
-        ContinuationContext context = new ContinuationContext();
-        context.setObject(parentContext.getObject());
-        context.setMethod(parentContext.getMethod());
-        context.setAvalonContext(avalonContext);
-        context.setLogger(getLogger());
-        context.setServiceManager(manager);
-        context.setRedirector(redirector);
-        Parameters parameters = new Parameters();
-        for(Iterator i=params.iterator(); i.hasNext();) {
-               Argument argument = (Argument)i.next();
-               parameters.setParameter(argument.name, argument.value);
+            final Class clazz = 
Thread.currentThread().getContextClassLoader().loadClass(clazzName);
+            final Map m = ReflectionUtils.discoverMethods(clazz);
+            methods.putAll(m);
         }
-        context.setParameters(parameters);
-        
-        Continuation continuation = new Continuation(parentContinuation, 
context);
 
-        Request request = ContextHelper.getRequest(this.avalonContext);
-        Session session = request.getSession(true);
-        HashMap userScopes = (HashMap) session.getAttribute(USER_GLOBAL_SCOPE);
+        final Method method = (Method) methods.get(function);
 
-        ContinuationCapable flow = (ContinuationCapable) context.getObject();
-        Method method = context.getMethod();
+        if (method == null) {
+            throw new ProcessingException("no method '" + function + "' found. 
" + methods);
+        }
 
-        WebContinuation wk = continuationsMgr.createWebContinuation(
-                continuation, parentwk, timeToLive, getInterpreterID(), null);
-        
FlowHelper.setWebContinuation(ContextHelper.getObjectModel(this.avalonContext), 
wk);
+        if (getLogger().isDebugEnabled()) { 
+            getLogger().debug("setting up continuation context");
+        }
 
-        continuation.registerThread();
-        try {
+        final Request request = ContextHelper.getRequest(this.avalonContext);
+        final Session session = request.getSession(true);
 
-            method.invoke(flow, new Object[0]);
+        HashMap userScopes = (HashMap) session.getAttribute(USER_GLOBAL_SCOPE);
+        if (userScopes == null) {
+            userScopes = new HashMap();
+        }
 
-        } catch (InvocationTargetException ite) {
-            if (ite.getTargetException() != null) {
-                if (ite.getTargetException() instanceof Exception)
-                    throw (Exception) ite.getTargetException();
-                else if (ite.getTargetException() instanceof Error)
-                    throw new ProcessingException("An internal error occured", 
ite.getTargetException());
-                else if (ite.getTargetException() instanceof RuntimeException)
-                    throw (RuntimeException) ite.getTargetException();
-                else
-                    throw ite;
-            } else {
-                throw ite;
+        final CocoonContinuationContext context = new 
CocoonContinuationContext();
+        
+        Continuable flow = null; //(Continuable) 
userScopes.get(method.getDeclaringClass());
+
+        if (flow == null) {
+            
+            if (getLogger().isDebugEnabled()) { 
+                getLogger().debug("creating flow class " + 
method.getDeclaringClass().getName());
             }
-        } finally {
-            // remove last object reference, which is not needed to reconstruct
-            // the invocation path
-            if (continuation.isCapturing())
-                continuation.getStack().popReference();
-            continuation.deregisterThread();
+
+            flow = (Continuable) method.getDeclaringClass().newInstance();
+
+            userScopes.put(method.getDeclaringClass(), flow);
+            //session.setAttribute(USER_GLOBAL_SCOPE, userScopes);
+        }
+
+        context.setObject(flow);
+        context.setMethod(method);
+
+        continueFlow(null, params, redirector, null, context);
+    }
+
+    public void handleContinuation(String id, List params, Redirector 
redirector)
+            throws Exception {
+
+        final WebContinuation parentwk = 
continuationsMgr.lookupWebContinuation(id, getInterpreterID());
+
+        if (parentwk == null) {
+            /*
+             * Throw an InvalidContinuationException to be handled inside the
+             * <map:handle-errors> sitemap element.
+             */
+            throw new InvalidContinuationException("Invalid continuation id " 
+ id);
         }
 
-        userScopes.put(method.getDeclaringClass(), flow);
-        session.setAttribute(USER_GLOBAL_SCOPE, userScopes);
+        if (getLogger().isDebugEnabled()) { 
+            getLogger().debug("continue with continuation " + id);
+        }
+
+        final CocoonContinuationContext context = new 
CocoonContinuationContext();
+
+        final Continuation parentContinuation = (Continuation) 
parentwk.getContinuation();
+        final CocoonContinuationContext parentContext = 
(CocoonContinuationContext) parentContinuation.getContext();
+        context.setObject(parentContext.getObject());
+        context.setMethod(parentContext.getMethod());
+
+        continueFlow(parentwk, params, redirector, parentContinuation, 
context);
     }
+        
 }

Modified: 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMap.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMap.java?view=diff&rev=111860&p1=cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMap.java&r1=111859&p2=cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMap.java&r2=111860
==============================================================================
--- 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMap.java
    (original)
+++ 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMap.java
    Tue Dec 14 11:01:29 2004
@@ -22,7 +22,7 @@
  * Simplified version of a map.
  *
  * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
- * @version CVS $Id: VarMap.java,v 1.2 2004/04/04 06:35:08 antonio Exp $
+ * @version CVS $Id$
  */
 public class VarMap {
     private HashMap map = new HashMap();

Modified: 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMapHandler.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMapHandler.java?view=diff&rev=111860&p1=cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMapHandler.java&r1=111859&p2=cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMapHandler.java&r2=111860
==============================================================================
--- 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMapHandler.java
     (original)
+++ 
cocoon/trunk/src/blocks/javaflow/java/org/apache/cocoon/components/flow/java/VarMapHandler.java
     Tue Dec 14 11:01:29 2004
@@ -26,7 +26,7 @@
  * JXPath handler for VarMap.
  *
  * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
- * @version CVS $Id: VarMapHandler.java,v 1.1 2004/03/29 17:47:21 stephan Exp $
+ * @version CVS $Id$
  */
 public class VarMapHandler implements DynamicPropertyHandler {
 

Added: cocoon/trunk/src/blocks/javaflow/javaflow-20041213.tgz
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/javaflow-20041213.tgz?view=auto&rev=111860
==============================================================================
Binary file. No diff available.

Added: cocoon/trunk/src/blocks/javaflow/jci-20041213.tgz
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/jci-20041213.tgz?view=auto&rev=111860
==============================================================================
Binary file. No diff available.

Modified: cocoon/trunk/src/blocks/javaflow/samples/sitemap.xmap
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/javaflow/samples/sitemap.xmap?view=diff&rev=111860&p1=cocoon/trunk/src/blocks/javaflow/samples/sitemap.xmap&r1=111859&p2=cocoon/trunk/src/blocks/javaflow/samples/sitemap.xmap&r2=111860
==============================================================================
--- cocoon/trunk/src/blocks/javaflow/samples/sitemap.xmap       (original)
+++ cocoon/trunk/src/blocks/javaflow/samples/sitemap.xmap       Tue Dec 14 
11:01:29 2004
@@ -33,7 +33,9 @@
  <map:flow language="java">
   <map:script src="org.apache.cocoon.samples.flow.java.CalculatorFlow"/>
   <map:script src="org.apache.cocoon.samples.flow.java.FormFlow"/>
+<!--
   <map:script src="org.apache.cocoon.samples.flow.java.PersistenceFlow"/>
+-->
  </map:flow>
 
  <map:pipelines>

Modified: 
cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidClassLoader.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidClassLoader.java?view=diff&rev=111860&p1=cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidClassLoader.java&r1=111859&p2=cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidClassLoader.java&r2=111860
==============================================================================
--- 
cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidClassLoader.java
    (original)
+++ 
cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidClassLoader.java
    Tue Dec 14 11:01:29 2004
@@ -21,13 +21,13 @@
 import java.net.URLClassLoader;
 import java.net.URLStreamHandlerFactory;
 
-/**
+/*
  * The <code>ParanoidClassLoader</code> reverses the search order for
  * classes.  It checks this classloader before it checks its parent.
  *
  * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
  * @author <a href="http://www.apache.org/~sylvain/";>Sylvain Wallez</a>
- * @version CVS $Id: ParanoidClassLoader.java,v 1.2 2004/03/05 13:02:02 
bdelacretaz Exp $
+ * @version CVS $Id$
  */
 
 public class ParanoidClassLoader extends URLClassLoader {
@@ -54,33 +54,32 @@
     }
 
     /**
-     * Alternate constructor to define a parent and initial
-     * <code>URL</code>s.
+     * Alternate constructor to define a parent and initial <code>URL</code>
+     * s.
      */
     public ParanoidClassLoader(final URL[] urls, final ClassLoader parent) {
         this(urls, parent, null);
     }
 
     /**
-     * Alternate constructor to define a parent, initial
-     * <code>URL</code>s, and a default
-     * <code>URLStreamHandlerFactory</code>.
+     * Alternate constructor to define a parent, initial <code>URL</code>s,
+     * and a default <code>URLStreamHandlerFactory</code>.
      */
     public ParanoidClassLoader(final URL[] urls, final ClassLoader parent, 
final URLStreamHandlerFactory factory) {
         super(urls, parent, factory);
     }
 
     /**
-     * Extends <code>URLClassLoader</code>'s initialization methods so
-     * we return a <code>ParanoidClassLoad</code> instead.
+     * Extends <code>URLClassLoader</code>'s initialization methods so we
+     * return a <code>ParanoidClassLoad</code> instead.
      */
     public static final URLClassLoader newInstance(final URL[] urls) {
         return new ParanoidClassLoader(urls);
     }
 
     /**
-     * Extends <code>URLClassLoader</code>'s initialization methods so
-     * we return a <code>ParanoidClassLoad</code> instead.
+     * Extends <code>URLClassLoader</code>'s initialization methods so we
+     * return a <code>ParanoidClassLoad</code> instead.
      */
     public static final URLClassLoader newInstance(final URL[] urls, final 
ClassLoader parent) {
         return new ParanoidClassLoader(urls, parent);
@@ -98,21 +97,19 @@
      * @return    the resulting <code>Class</code> object
      * @exception ClassNotFoundException if the class could not be found
      */
-    public final Class loadClass(String name, boolean resolve)
-      throws ClassNotFoundException
-    {
+    public final Class loadClass(String name, boolean resolve) throws 
ClassNotFoundException {
         // First check if it's already loaded
         Class clazz = findLoadedClass(name);
-        
+
         if (clazz == null) {
-            
+
             try {
                 clazz = findClass(name);
                 //System.err.println("Paranoid load : " + name);
             } catch (ClassNotFoundException cnfe) {
                 ClassLoader parent = getParent();
                 if (parent != null) {
-                     // Ask to parent ClassLoader (can also throw a CNFE).
+                    // Ask to parent ClassLoader (can also throw a CNFE).
                     clazz = parent.loadClass(name);
                 } else {
                     // Propagate exception
@@ -120,14 +117,14 @@
                 }
             }
         }
-        
+
         if (resolve) {
             resolveClass(clazz);
         }
-        
+
         return clazz;
     }
-    
+
     /**
      * Gets a resource from this <code>ClassLoader</class>.  If the
      * resource does not exist in this one, we check the parent.
@@ -150,19 +147,20 @@
 
     /**
      * Adds a new directory of class files.
-     *
-     * @param file for jar or directory
+     * 
+     * @param file
+     *            for jar or directory
      * @throws IOException
      */
     public final void addDirectory(File file) throws IOException {
         this.addURL(file.getCanonicalFile().toURL());
     }
-    
+
     /**
      * Adds a new URL
      */
-    
+
     public void addURL(URL url) {
-       super.addURL(url);
+        super.addURL(url);
     }
 }

Modified: 
cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java?view=diff&rev=111860&p1=cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java&r1=111859&p2=cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java&r2=111860
==============================================================================
--- 
cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java
  (original)
+++ 
cocoon/trunk/src/blocks/paranoid/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java
  Tue Dec 14 11:01:29 2004
@@ -20,6 +20,8 @@
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.LineNumberReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
@@ -33,18 +35,20 @@
 import javax.servlet.http.HttpServlet;
 
 /**
- * This servlet builds a classloading sandbox and runs another servlet inside 
that
- * sandbox. The purpose is to shield the libraries and classes shipped with 
the web
- * application from any other classes with the same name that may exist in the 
system,
- * such as Xerces and Xalan versions included in JDK 1.4.
+ * This servlet builds a classloading sandbox and runs another servlet inside
+ * that sandbox. The purpose is to shield the libraries and classes shipped 
with
+ * the web application from any other classes with the same name that may exist
+ * in the system, such as Xerces and Xalan versions included in JDK 1.4.
  * <p>
- * This servlet propagates all initialisation parameters to the sandboxed 
servlet, and
- * accepts the parameters <code>servlet-class</code> and 
<code>paranoid-classpath</code>.
+ * This servlet propagates all initialisation parameters to the sandboxed
+ * servlet, and accepts the parameters <code>servlet-class</code> and
+ * <code>paranoid-classpath</code>.
  * <ul>
- *  <li><code>servlet-class</code> defines the sandboxed servlet class, the 
default is 
- *      [EMAIL PROTECTED] CocoonServlet}
- *  <li><code>paranoid-classpath</code> expects the name of a text file that 
can contain 
- *      lines begining with <code>class-dir:<code> (directory containing 
classes),
+ * <li><code>servlet-class</code> defines the sandboxed servlet class, the
+ * default is [EMAIL PROTECTED] CocoonServlet}
+ * <li><code>paranoid-classpath</code> expects the name of a text file that
+ * can contain lines begining with
+ * <code>class-dir:<code> (directory containing classes),
  *      <code>lib-dir:<code> (directory containing JAR or ZIP libraries) and 
<code>#</code>
  *      (for comments). <br/>
  *      All other lines are considered as URLs.
@@ -55,166 +59,167 @@
  *
  * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
  * @author <a href="http://www.apache.org/~sylvain/";>Sylvain Wallez</a>
- * @version CVS $Id: ParanoidCocoonServlet.java,v 1.4 2004/06/18 15:27:36 
sylvain Exp $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a>
+ * @version CVS $Id$
  */
 
 public class ParanoidCocoonServlet extends HttpServlet {
 
-       /**
-        * The name of the actual servlet class.
-        */
-       public static final String DEFAULT_SERVLET_CLASS = 
"org.apache.cocoon.servlet.CocoonServlet";
-    
+    /**
+     * The name of the actual servlet class.
+     */
+    public static final String DEFAULT_SERVLET_CLASS = 
"org.apache.cocoon.servlet.CocoonServlet";
+
     protected static final String CONTEXT_PREFIX = "context:";
-    
+
     protected static final String FILE_PREFIX = "file:";
-    
-       protected Servlet servlet;
-    
+
+    protected Servlet servlet;
+
     protected ClassLoader classloader;
-    
-       public void init(ServletConfig config) throws ServletException {
-               
-               super.init(config);
 
-               // Create the classloader in which we will load the servlet
+    public void init(ServletConfig config) throws ServletException {
+
+        super.init(config);
+
+        // Create the classloader in which we will load the servlet
         // this can either be specified by an external file configured
-        // as a parameter in web.xml or (the default) all jars and 
+        // as a parameter in web.xml or (the default) all jars and
         // classes from WEB-INF/lib and WEB-INF/classes are used.
         final String externalClasspath = 
config.getInitParameter("paranoid-classpath");
-        if ( externalClasspath == null ) {
-            this.classloader = this.getClassLoader(this.getContextDir());
-        } else {
-            this.classloader = this.getClassLoader(externalClasspath, 
this.getContextDir());
+        final URL[] classPath = (externalClasspath == null)
+            ? getClassPath(getContextDir())
+            : getClassPath(externalClasspath, getContextDir());
+
+            
+        final String classLoaderName = 
config.getInitParameter("classloader-class");
+        if (classLoaderName != null) {
+            log("Using classloader " + classLoaderName);
         }
+        this.classloader = createClassLoader(classLoaderName, getContextDir(), 
classPath);
+
         
         String servletName = config.getInitParameter("servlet-class");
         if (servletName == null) {
             servletName = DEFAULT_SERVLET_CLASS;
         }
+        log("Loading servlet class " + servletName);
+
         
         // Create the servlet
-               try {
-                       Class servletClass = 
this.classloader.loadClass(servletName);
-            
-                       this.servlet = (Servlet)servletClass.newInstance();
+        try {
 
-               } catch(Exception e) {
-                       throw new ServletException("Cannot load servlet " + 
servletName, e);
-               }
-        
-               // Always set the context classloader. JAXP uses it to find a 
ParserFactory,
-               // and thus fails if it's not set to the webapp classloader.
+            Class servletClass = this.classloader.loadClass(servletName);
+            this.servlet = (Servlet) servletClass.newInstance();
+
+        } catch (Exception e) {
+            throw new ServletException("Cannot load servlet " + servletName, 
e);
+        }
+
+        // Always set the context classloader. JAXP uses it to find a
+        // ParserFactory,
+        // and thus fails if it's not set to the webapp classloader.
         final ClassLoader old = Thread.currentThread().getContextClassLoader();
         try {
             Thread.currentThread().setContextClassLoader(this.classloader);
-        
+
             // Inlitialize the actual servlet
             this.initServlet();
         } finally {
             Thread.currentThread().setContextClassLoader(old);
         }
-        
-       }
-       
-       /**
-        * Initialize the wrapped servlet. Subclasses (see [EMAIL PROTECTED] 
BootstrapServlet} change the
-        * <code>ServletConfig</code> given to the servlet.
-        * 
-        * @throws ServletException
-        */
-       protected void initServlet() throws ServletException {
-               this.servlet.init(this.getServletConfig());
-       }
-       
-       /**
-        * Get the web application context directory.
-        * 
-        * @return the context dir
-        * @throws ServletException
-        */
-       protected File getContextDir() throws ServletException {
-               String result = getServletContext().getRealPath("/");
-               if (result == null) {
-                       throw new ServletException(this.getClass().getName() + 
" cannot run in an undeployed WAR file");
-               }
-               return new File(result);
-       }
-    
-       /**
-        * Get the classloader that will be used to create the actual servlet. 
Its classpath is defined
-        * by the WEB-INF/classes and WEB-INF/lib directories in the context 
dir.
-        */
-       protected ClassLoader getClassLoader(File contextDir) throws 
ServletException {
-               List urlList = new ArrayList();
-        
-               try {
-                       File classDir = new File(contextDir + 
"/WEB-INF/classes");
-                       if (classDir.exists()) {
-                               if (!classDir.isDirectory()) {
-                                       throw new ServletException(classDir + " 
exists but is not a directory");
-                               }
-            
-                               URL classURL = classDir.toURL();
-                               log("Adding class directory " + classURL);
-                               urlList.add(classURL);
-                
-                       }
-            
-            // List all .jar and .zip
-                       File libDir = new File(contextDir + "/WEB-INF/lib");
-                       File[] libraries = libDir.listFiles(new 
JarFileFilter());
 
-                       for (int i = 0; i < libraries.length; i++) {
-                               URL lib = libraries[i].toURL();
-                               log("Adding class library " + lib);
-                               urlList.add(lib);
-                       }
-               } catch (MalformedURLException mue) {
-                       throw new ServletException(mue);
-               }
-        
-               URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
-        
-               return ParanoidClassLoader.newInstance(urls, 
this.getClass().getClassLoader());
-       }
-    
+    }
+
     /**
-     * Get the classloader that will be used to create the actual servlet. Its 
classpath is defined
-     * by an external file.
+     * Initialize the wrapped servlet. Subclasses (see [EMAIL PROTECTED] 
BootstrapServlet}
+     * change the <code>ServletConfig</code> given to the servlet.
+     * 
+     * @throws ServletException
      */
-    protected ClassLoader getClassLoader(String externalClasspath, File 
contextDir) 
-    throws ServletException {
+    protected void initServlet() throws ServletException {
+        this.servlet.init(this.getServletConfig());
+    }
+
+    /**
+     * Get the web application context directory.
+     * 
+     * @return the context dir
+     * @throws ServletException
+     */
+    protected File getContextDir() throws ServletException {
+        String result = getServletContext().getRealPath("/");
+        if (result == null) {
+            throw new ServletException(this.getClass().getName() + " cannot 
run in an undeployed WAR file");
+        }
+        return new File(result);
+    }
+
+    protected URL[] getClassPath(final File contextDir) throws 
ServletException {
+        List urlList = new ArrayList();
+
+        try {
+            File classDir = new File(contextDir + "/WEB-INF/classes");
+            if (classDir.exists()) {
+                if (!classDir.isDirectory()) {
+                    throw new ServletException(classDir + " exists but is not 
a directory");
+                }
+
+                URL classURL = classDir.toURL();
+                log("Adding class directory " + classURL);
+                urlList.add(classURL);
+
+            }
+
+            // List all .jar and .zip
+            File libDir = new File(contextDir + "/WEB-INF/lib");
+            File[] libraries = libDir.listFiles(new JarFileFilter());
+
+            for (int i = 0; i < libraries.length; i++) {
+                URL lib = libraries[i].toURL();
+                log("Adding class library " + lib);
+                urlList.add(lib);
+            }
+        } catch (MalformedURLException mue) {
+            throw new ServletException(mue);
+        }
+
+        URL[] urls = (URL[]) urlList.toArray(new URL[urlList.size()]);
+
+        return urls;
+    }
+    
+    protected URL[] getClassPath(final String externalClasspath, final File 
contextDir) throws ServletException {
         final List urlList = new ArrayList();
 
         File file = new File(externalClasspath);
         if (!file.isAbsolute()) {
-            file = new File(contextDir,externalClasspath);
+            file = new File(contextDir, externalClasspath);
         }
 
         log("Adding classpath from " + file);
         try {
             FileReader fileReader = new FileReader(file);
             LineNumberReader lineReader = new LineNumberReader(fileReader);
-        
+
             String line;
             do {
-                line = lineReader.readLine();                
-                if ( line != null ) {
+                line = lineReader.readLine();
+                if (line != null) {
                     if (line.startsWith("class-dir:")) {
                         line = line.substring("class-dir:".length()).trim();
-                        if( line.startsWith(CONTEXT_PREFIX)) {
+                        if (line.startsWith(CONTEXT_PREFIX)) {
                             line = contextDir + 
line.substring(CONTEXT_PREFIX.length());
                         }
                         URL url = new File(line).toURL();
                         log("Adding class directory " + url);
                         urlList.add(url);
-                        
+
                     } else if (line.startsWith("lib-dir:")) {
                         line = line.substring("lib-dir:".length()).trim();
-                        if( line.startsWith(CONTEXT_PREFIX)) {
-                            line = contextDir + 
line.substring(CONTEXT_PREFIX.length());                            
-                        }                        
+                        if (line.startsWith(CONTEXT_PREFIX)) {
+                            line = contextDir + 
line.substring(CONTEXT_PREFIX.length());
+                        }
                         File dir = new File(line);
                         File[] libraries = dir.listFiles(new JarFileFilter());
                         log("Adding " + libraries.length + " libraries from " 
+ dir.toURL());
@@ -222,74 +227,121 @@
                             URL url = libraries[i].toURL();
                             urlList.add(url);
                         }
-                    } else if(line.startsWith("#")) {
+                    } else if (line.startsWith("#")) {
                         // skip it (consider it as comment)
                     } else {
                         // Consider it as a URL
                         final URL lib;
-                        if( line.startsWith(CONTEXT_PREFIX)) {
-                            line = FILE_PREFIX + "/" + contextDir + 
-                                line.substring(CONTEXT_PREFIX.length()).trim();
-                        }                        
-                        if ( line.indexOf(':') == -1) {
-                            File entry = new File(line);        
-                            lib = entry.toURL();                          
+                        if (line.startsWith(CONTEXT_PREFIX)) {
+                            line = FILE_PREFIX + "/" + contextDir + 
line.substring(CONTEXT_PREFIX.length()).trim();
+                        }
+                        if (line.indexOf(':') == -1) {
+                            File entry = new File(line);
+                            lib = entry.toURL();
                         } else {
                             lib = new URL(line);
-                        }                        
+                        }
                         log("Adding class URL " + lib);
                         urlList.add(lib);
                     }
                 }
-            } while ( line != null );
+            } while (line != null);
             lineReader.close();
         } catch (IOException io) {
             throw new ServletException(io);
         }
-              
-        URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
-        
-        return ParanoidClassLoader.newInstance(urls, 
this.getClass().getClassLoader());
+
+        URL[] urls = (URL[]) urlList.toArray(new URL[urlList.size()]);
+
+        return urls;
+    }
+
+    protected ClassLoader createClassLoader(final String className, final File 
contextDir, final URL[] classPath) throws ServletException {
+        if (className != null) {
+            try {
+                final Class classLoaderClass = Class.forName(className);
+                final Class[] parameterClasses = new Class[] { 
ClassLoader.class, File.class };
+                final Constructor constructor = 
classLoaderClass.getConstructor(parameterClasses);
+                final Object[] parameters = new Object[] { 
this.getClass().getClassLoader(), new File(contextDir, "WEB-INF/src") };
+                final ClassLoader classloader = (ClassLoader) 
constructor.newInstance(parameters);
+                return classloader;
+            } catch (InstantiationException e) {
+                throw new ServletException("", e);
+            } catch (IllegalAccessException e) {
+                throw new ServletException("", e);
+            } catch (ClassNotFoundException e) {
+                throw new ServletException("", e);
+            } catch (SecurityException e) {
+                throw new ServletException("", e);
+            } catch (NoSuchMethodException e) {
+                throw new ServletException("", e);
+            } catch (IllegalArgumentException e) {
+                throw new ServletException("", e);
+            } catch (InvocationTargetException e) {
+                throw new ServletException("", e);
+            }
+        } else {
+            return ParanoidClassLoader.newInstance(classPath, 
this.getClass().getClassLoader());
+        }
+    }
+
+    
+    /**
+     * Get the classloader that will be used to create the actual servlet. Its
+     * classpath is defined by the WEB-INF/classes and WEB-INF/lib directories
+     * in the context dir.
+     * @deprecated
+     */
+    protected ClassLoader getClassLoader(File contextDir) throws 
ServletException {
+        return createClassLoader(null, contextDir, getClassPath(contextDir));
+    }
+
+    /**
+     * Get the classloader that will be used to create the actual servlet. Its
+     * classpath is defined by an external file.
+     * @deprecated
+     */
+    protected ClassLoader getClassLoader(final String externalClasspath, final 
File contextDir) throws ServletException {
+        return createClassLoader(null, contextDir, 
getClassPath(externalClasspath, contextDir));
     }
 
-       /**
-        * Service the request by delegating the call to the real servlet
-        */
-       public void service(ServletRequest request, ServletResponse response)
-    throws ServletException, IOException {
+    /**
+     * Service the request by delegating the call to the real servlet
+     */
+    public void service(ServletRequest request, ServletResponse response) 
throws ServletException, IOException {
 
         final ClassLoader old = Thread.currentThread().getContextClassLoader();
         try {
-                   
Thread.currentThread().setContextClassLoader(this.classloader);
-                   this.servlet.service(request, response);
+            Thread.currentThread().setContextClassLoader(this.classloader);
+            this.servlet.service(request, response);
         } finally {
-            Thread.currentThread().setContextClassLoader(old);    
+            Thread.currentThread().setContextClassLoader(old);
         }
-       }
-    
-       /**
-        * Destroy the actual servlet
-        */
-       public void destroy() {
+    }
+
+    /**
+     * Destroy the actual servlet
+     */
+    public void destroy() {
 
-        if ( this.servlet != null ) {
+        if (this.servlet != null) {
             final ClassLoader old = 
Thread.currentThread().getContextClassLoader();
             try {
                 Thread.currentThread().setContextClassLoader(this.classloader);
                 this.servlet.destroy();
             } finally {
-                Thread.currentThread().setContextClassLoader(old);    
+                Thread.currentThread().setContextClassLoader(old);
             }
         }
 
-               super.destroy();
-       }
-    
+        super.destroy();
+    }
+
     private class JarFileFilter implements FilenameFilter {
         public boolean accept(File dir, String name) {
             return name.endsWith(".zip") || name.endsWith(".jar");
         }
     }
-   
+
 }
 

Added: 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/components/flow/java/AbstractContinuable.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/components/flow/java/AbstractContinuable.java?view=auto&rev=111860
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/components/flow/java/AbstractContinuable.java
 Tue Dec 14 11:01:29 2004
@@ -0,0 +1,192 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package org.apache.cocoon.components.flow.java;
+
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.flow.FlowHelper;
+import org.apache.cocoon.components.flow.util.PipelineUtil;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.excalibur.source.SourceUtil;
+import org.apache.javaflow.Continuable;
+import org.apache.javaflow.Continuation;
+import org.apache.javaflow.ContinuationContext;
+
+/**
+ * Abstract class to add basic methods for flow handling.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
+ * @version CVS $Id: AbstractContinuable.java 30941 2004-07-29 19:56:58Z 
vgritsenko $
+ */
+public abstract class AbstractContinuable implements Continuable {
+
+    private static CocoonContinuationContext getContext() {
+        if (Continuation.currentContinuation() == null)
+            throw new IllegalStateException("No continuation is running");
+        return (CocoonContinuationContext) 
Continuation.currentContinuation().getContext();
+    }
+
+    public AbstractContinuable() {
+        System.out.println("flow inside " + 
this.getClass().getClassLoader().getClass().getName());
+    }
+    
+    public static Logger getLogger() {
+        return getContext().getLogger();
+    }
+    
+    public static Context getAvalonContext() {
+        return getContext().getAvalonContext();
+    }
+
+    public static ServiceManager getServiceManager() {
+        return getContext().getServiceManager();
+    }
+ 
+    public static Redirector getRedirector() {
+        return getContext().getRedirector();
+    }
+
+    public static void sendPageAndWait(String uri) {
+        sendPageAndWait(uri, new VarMap());
+    }
+
+    public static void sendPageAndWait(String uri, Object bizdata) {
+       
+       System.out.println("sendPageAndWait("+uri+", "+bizdata+")");
+
+        ContinuationContext context = getContext();
+
+        
FlowHelper.setContextObject(ContextHelper.getObjectModel(getContext().getAvalonContext()),
 bizdata);
+
+        if (SourceUtil.indexOfSchemeColon(uri) == -1) {
+            uri = "cocoon:/" + uri;
+            if (getContext().getRedirector().hasRedirected()) {
+                throw new IllegalStateException("Pipeline has already been 
processed for this request");
+            }
+            try {
+                getContext().getRedirector().redirect(false, uri);
+            } catch (Exception e) {
+                throw new CascadingRuntimeException("Cannot redirect to 
'"+uri+"'", e);
+            } 
+        } else {
+            throw new IllegalArgumentException("uri is not allowed to contain 
a scheme (cocoon:/ is always automatically used)");
+        }
+
+        Continuation.suspend();
+
+        System.out.println("continuation suspended");
+    }
+
+    public static void sendPage(String uri) {
+        sendPage(uri, new VarMap());
+    }
+
+    public static void sendPage(String uri, Object bizdata) {
+
+        ContinuationContext context = getContext();
+
+        if (getContext().getLogger() != null)
+            getContext().getLogger().debug("send page '" + uri + "'");
+
+        
FlowHelper.setContextObject(ContextHelper.getObjectModel(getContext().getAvalonContext()),
 bizdata);
+
+        if (SourceUtil.indexOfSchemeColon(uri) == -1) {
+            uri = "cocoon:/" + uri;
+            if (getContext().getRedirector().hasRedirected()) {
+                throw new IllegalStateException("Pipeline has already been 
processed for this request");
+            }
+            try {
+                getContext().getRedirector().redirect(false, uri);
+            } catch (Exception e) {
+                throw new CascadingRuntimeException("Cannot redirect to 
'"+uri+"'", e);
+            }
+        } else {
+            throw new IllegalArgumentException("uri is not allowed to contain 
a scheme (cocoon:/ is always automatically used)");
+        }
+    }
+
+    public static Request getRequest() {
+       System.out.println("getRequest()");
+        return ContextHelper.getRequest(getContext().getAvalonContext());
+    }
+    
+    public static Map getObjectModel() {
+        return ContextHelper.getObjectModel(getContext().getAvalonContext());
+    }
+    
+    public static Parameters getParameters() {
+       return getContext().getParameters();
+    }
+
+    public static void processPipelineTo(String uri, Object bizdata, 
OutputStream out) {
+
+        ContinuationContext context = getContext();
+
+        PipelineUtil pipeUtil = new PipelineUtil();
+        try {          
+            pipeUtil.contextualize(getContext().getAvalonContext());
+            pipeUtil.service(getContext().getServiceManager());
+            pipeUtil.processToStream(uri, bizdata, out);
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("Cannot process pipeline to 
'"+uri+"'", e);
+        } finally {
+            pipeUtil.dispose();
+        }
+    }
+
+    public static void redirectTo(String uri) {
+        try {
+            getContext().getRedirector().redirect(false, uri);
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("Cannot redirect to 
'"+uri+"'", e);
+        }
+    }
+
+    public static void sendStatus(int sc) {
+        getContext().getRedirector().sendStatus(sc);
+    }
+
+    /**
+     * Access components.
+     */
+    public static Object getComponent(String id) {
+        try {
+            return getContext().getServiceManager().lookup(id);
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("Cannot lookup component 
'"+id+"'", e);
+        }
+    }
+
+    /**
+     * Release pooled components.
+     *
+     * @param component a component
+     */
+    public static void releaseComponent( Object component ) {
+        if (component != null) {
+            getContext().getServiceManager().release(component);
+        }
+    }
+}

Added: 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/forms/flow/java/FormInstance.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/forms/flow/java/FormInstance.java?view=auto&rev=111860
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/forms/flow/java/FormInstance.java
     Tue Dec 14 11:01:29 2004
@@ -0,0 +1,303 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+
+package org.apache.cocoon.forms.flow.java;
+
+import java.util.Locale;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.cocoon.components.flow.FlowHelper;
+import org.apache.cocoon.components.flow.java.AbstractContinuable;
+import org.apache.cocoon.components.flow.java.VarMap;
+import org.apache.cocoon.forms.FormContext;
+import org.apache.cocoon.forms.FormManager;
+import org.apache.cocoon.forms.binding.Binding;
+import org.apache.cocoon.forms.binding.BindingManager;
+import org.apache.cocoon.forms.formmodel.Form;
+import org.apache.cocoon.forms.formmodel.Widget;
+import org.apache.cocoon.forms.transformation.FormsPipelineConfig;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of the Cocoon Forms/Java Flow integration.
+ *
+ * @author <a href="http://www.apache.org/~sylvain/";>Sylvain Wallez</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
+ * @version CVS $Id: FormInstance.java 30932 2004-07-29 17:35:38Z vgritsenko $
+ */
+public class FormInstance extends AbstractContinuable {
+
+    private Form form;
+    private Binding binding;
+    private Locale locale;
+    private boolean isValid;
+    private Object validator; // Used?
+  
+    /**
+     * Create a form, given the URI of its definition file
+     */
+    public FormInstance(String uri) {
+        FormManager formMgr = null;
+        SourceResolver resolver = null;
+        Source src = null;
+        try {
+            formMgr = (FormManager)getComponent(FormManager.ROLE);
+            resolver = (SourceResolver)getComponent(SourceResolver.ROLE);
+            src = resolver.resolveURI(uri);
+            this.form = formMgr.createForm(src);
+            this.binding = null;
+            // this.validator = null;
+            // TODO : do we keep this ?
+            // this.formWidget = new Widget(this.form); could not create 
instance
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("Could not create form 
instance", e);
+        } finally {
+            releaseComponent(formMgr);
+            if (src != null) resolver.release(src);
+            releaseComponent(resolver);
+        }
+    }
+
+    /**
+     * Create a form, given the URI of its definition file, the
+     * binding file.
+     */
+    public FormInstance(String definitionFile, String bindingFile) {
+        this(definitionFile);
+        createBinding(bindingFile);
+    }
+
+    /**
+     * Create a form of an fd:form element in the form of a org.w3c.dom.Element
+     */
+    public FormInstance(Element formDefinition) {
+        FormManager formMgr = null;
+        SourceResolver resolver = null;
+        Source src = null;
+        try {
+            formMgr = (FormManager)getComponent(FormManager.ROLE);
+            resolver = (SourceResolver)getComponent(SourceResolver.ROLE);
+            this.form = formMgr.createForm(formDefinition);
+            this.binding = null;
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("Could not create form 
instance", e);
+        } finally {
+            releaseComponent(formMgr);
+            if (src != null) resolver.release(src);
+            releaseComponent(resolver);
+        }
+    }
+
+    public Widget getModel() {
+        return this.form;
+    }
+
+    /**
+     * Get a Widget (the java object) from the form.
+     * If <code>name</code> is undefined, the form widget itself is returned.
+     * Otherwise, the form's child widget of name <code>name</code> is 
returned.
+     */
+    public Widget getChild(String name) {
+        if (name == null) {
+            return this.form;
+        } else {
+            return this.form.getChild(name);
+        }
+    }
+
+               public String getSubmitId() {
+                       
+                   Widget widget = this.form.getSubmitWidget();
+           // Can be null on "normal" submit
+                               return  widget == null ? null : widget.getId();
+               }
+
+    /**
+     * Sets the point in your script that will be returned to when the form is
+     * redisplayed. If setBookmark() is not called, this is implicitly set to
+     * the beginning of showForm().
+     */
+/*    public WebContinuation setBookmark() {
+          return (this.local_.webContinuation = 
cocoon.createWebContinuation());
+    }*/
+
+    /**
+     * Returns the bookmark continuation associated with this form, or 
undefined
+     * if setBookmark() has not been called.
+     *
+     */
+/*    public WebContinuation getBookmark() {
+        return this.local_.webContinuation;
+    }  */
+
+    public void show(String uri) {
+        show(uri, new VarMap());
+    }
+    
+    /**
+     * Manages the display of a form and its validation.
+     *
+     * This uses some additionnal propertied on the form object :
+     * - "locale" : the form locale (default locale is used if not set)
+     * - "validator" : additional validation function. This function receives
+     *   the form object as parameter and should return a boolean indicating
+     *   if the form handling is finished (true) or if the form should be
+     *   redisplayed again (false)
+     *
+     * On return, the calling code can check some properties to know the form 
result :
+     * - "isValid" : true if the form was sucessfully validated
+     * - "submitId" : the id of the widget that triggered the form submit (can 
be null)
+     *
+     * @param uri the page uri (like in cocoon.sendPageAndWait())
+     * @param bizData some business data for the view (like in 
cocoon.sendPageAndWait()).
+     *            The "{FormsPipelineConfig.CFORMSKEY}" and "locale" 
properties are added to this object.
+     */
+    public void show(String uri, Object bizData) {
+
+        if (bizData==null) bizData = new VarMap();
+        ((VarMap)bizData).add(FormsPipelineConfig.CFORMSKEY, this.form);
+
+        if (this.locale == null)
+            this.locale = java.util.Locale.getDefault();
+        ((VarMap)bizData).add("locale", this.locale);
+    
+        // Keep the first continuation that will be created as the result of 
this function
+        //var result = null;
+
+        boolean finished = false;
+        this.isValid = false;
+
+        do {
+            sendPageAndWait(uri, bizData);
+        
+            FormContext formContext = new FormContext(getRequest(), locale);
+
+            // Prematurely add the bizData as a request attribute so that 
event listeners can use it
+            // (the same is done by cocoon.sendPage())
+            FlowHelper.setContextObject(AbstractContinuable.getObjectModel(), 
bizData);
+
+            finished = this.form.process(formContext);
+          
+            // Additional flow-level validation
+            if (finished) {
+                if (this.validator == null) {
+                    this.isValid = this.form.isValid();
+                } else {
+                    this.isValid = this.form.isValid() /*& 
this.validator(this.form, bizData)*/;
+                }
+                finished = this.isValid;
+            }
+        
+            // FIXME: Theoretically, we should clone the form widget 
(this.form) to ensure it keeps its
+            // value with the continuation. We don't do it since there should 
me not much pratical consequences
+            // except a sudden change of repeaters whose size changed from a 
continuation to another.
+        
+        } while(!finished);
+    }
+    /*
+    /**
+     * Manages the display of a form and its validation.
+     * @param uri the page uri (like in cocoon.sendPageAndWait())
+     * @param fun optional function which will be executed after pipeline
+     *  processing. Useful for releasing resources needed during pipeline
+     *  processing but which should not become part of the continuation
+     * @param ttl Time to live (in milliseconds) for the continuation
+     *  created
+     * @return The web continuation associated with submitting this form
+     *
+    public showForm(String uri, Object fun, ttl) {
+        if (!this.getBookmark()) {
+            this.setBookmark();
+        }
+        FormContext formContext = FormsFlowHelper.getFormContext(cocoon, 
this.locale);
+        // this is needed by the FormTemplateTransformer:
+        //var javaWidget = this.formWidget_.unwrap();;
+        //this.formWidget_["CocoonFormsInstance"] = javaWidget;
+        
getRequest().setAttribute(Packages.org.apache.cocoon.forms.transformation.CFORMSKEY,
 this.formWidget);
+        WebContinuation wk = sendPageAndWait(uri, this.formWidget, fun, ttl);
+        var formContext = new FormContext(cocoon.request, 
javaWidget.getLocale());
+        var userErrors = 0;
+        this.formWidget_.validationErrorListener = function(widget, error) {
+            if (error != null) {
+                userErrors++;
+            }
+        }
+        var finished = javaWidget.process(formContext);
+        if (this.onValidate) {
+            this.onValidate(this);
+        }
+        if (!finished || userErrors > 0) {
+            cocoon.continuation = this.local_.webContinuation;
+            
this.local_.webContinuation.continuation(this.local_.webContinuation);
+        }
+        return wk;
+    }*/
+
+    public void createBinding(String bindingURI) {
+        BindingManager bindingManager = null;
+        Source source = null;
+        SourceResolver resolver = null;
+        try {
+            bindingManager = (BindingManager)getComponent(BindingManager.ROLE);
+            resolver = (SourceResolver)getComponent(SourceResolver.ROLE);
+            source = resolver.resolveURI(bindingURI);
+            this.binding = bindingManager.createBinding(source);
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("Could not create bindinh", e);
+        } finally {
+            if (source != null)
+                resolver.release(source);
+            releaseComponent(bindingManager);
+            releaseComponent(resolver);
+        }
+    }
+
+    public void load(Object object) {
+        if (this.binding == null)
+            throw new Error("Binding not configured for this form.");
+
+        try {
+            this.binding.loadFormFromModel(this.form, object);
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("Could not load form from 
model", e);
+        }
+    }
+
+    public void save(Object object) {
+        if (this.binding == null)
+            throw new Error("Binding not configured for this form.");
+
+        try {
+            this.binding.saveFormToModel(this.form, object);
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("Could not save form into 
model", e);
+        }
+    }
+
+    public void setAttribute(String name, Object value) {
+        this.form.setAttribute(name, value);
+    }
+
+    public Object getAttribute(String name) {
+        return this.form.getAttribute(name);
+    }
+
+    public void removeAttribute(String name) {
+        this.form.removeAttribute(name);
+    }
+}

Added: 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/CalculatorFlow.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/CalculatorFlow.java?view=auto&rev=111860
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/CalculatorFlow.java
 Tue Dec 14 11:01:29 2004
@@ -0,0 +1,85 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package org.apache.cocoon.samples.flow.java;
+
+import org.apache.cocoon.components.flow.java.AbstractContinuable;
+import org.apache.cocoon.components.flow.java.VarMap;
+
+public class CalculatorFlow extends AbstractContinuable {
+
+    private int count = 1;
+
+    public void doCalculator() {
+        float a = getNumber("a", 0f, 0f);
+        float b = getNumber("b", a, 0f);
+        String op = getOperator(a, b);
+
+        if (op.equals("plus")) {
+            sendResult(a, b, op, a + b);
+        } else if (op.equals("minus")) {
+            sendResult(a, b, op, a - b);
+        } else if (op.equals("multiply")) {
+            sendResult(a, b, op, a * b);
+        } else if (op.equals("divide")) {
+            if (b==0f)
+                sendMessage("Error: Cannot divide by zero!");
+            sendResult(a, b, op, a / b);
+        } else {
+            sendMessage("Error: Unkown operator!");
+        }
+
+        count++;
+    }
+
+    private float getNumber(String name, float a, float b) {
+        String uri = "page/calculator-" + name.toLowerCase();
+        sendPageAndWait(uri, new VarMap()
+            .add("a", a)
+            .add("b", b)
+            .add("count", count + "x"));
+
+        float value = 0f;
+        try {
+            value = Float.parseFloat(getRequest().getParameter(name));
+        } catch (Exception e) {
+            sendMessage("Error: \""+getRequest().getParameter(name)+"\" is not 
a correct number!");
+        }
+        return value;
+    }
+
+    private String getOperator(float a, float b) {
+        sendPageAndWait("page/calculator-operator", new VarMap()
+            .add("a", a)
+            .add("b", b)
+            .add("count", count + "x"));
+        return getRequest().getParameter("operator");
+    }
+
+    private void sendResult(float a, float b, String op, float result) {
+        sendPage("page/calculator-result", new VarMap()
+            .add("a", a)
+            .add("b", b)
+            .add("operator", op)
+            .add("result", result)
+            .add("count", count + "x"));
+    }
+
+    private void sendMessage(String message) {
+        sendPageAndWait("page/calculator-message", new VarMap()
+            .add("message", message)
+            .add("count", count + "x"));
+    }
+}

Added: 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/FormFlow.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/FormFlow.java?view=auto&rev=111860
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/FormFlow.java
       Tue Dec 14 11:01:29 2004
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package org.apache.cocoon.samples.flow.java;
+
+import java.util.Date;
+
+import org.apache.cocoon.components.flow.java.AbstractContinuable;
+import org.apache.cocoon.components.flow.java.VarMap;
+import org.apache.cocoon.forms.binding.BindingException;
+import org.apache.cocoon.forms.flow.java.FormInstance;
+import org.apache.cocoon.forms.formmodel.BooleanField;
+import org.apache.cocoon.forms.formmodel.Field;
+import org.apache.cocoon.forms.formmodel.Repeater;
+import org.apache.cocoon.forms.samples.Contact;
+import org.apache.cocoon.forms.samples.Form2Bean;
+import org.apache.cocoon.forms.samples.Sex;
+
+public class FormFlow extends AbstractContinuable {
+
+    public void doEditForm1() {
+
+        FormInstance form = new FormInstance("forms/form1.xml");
+
+        Field birthDate = (Field) form.getChild("birthdate");
+        birthDate.setValue(new Date());
+
+        Repeater repeater = (Repeater) form.getChild("contacts");
+        repeater.addRow();
+        Field field = (Field) repeater.getWidget(0, "firstname");
+        field.setValue("Jules");
+
+        repeater.addRow();
+        field = (Field) repeater.getWidget(1, "firstname");
+        field.setValue("Lucien");
+
+       System.out.println("** start");
+        form.show("form/form1");
+       System.out.println("** continue");
+
+        sendPage("page/form1-result", new VarMap().add("email", 
((Field)form.getChild("email")).getValue())
+                                                  .add("somebool", 
((BooleanField)form.getChild("somebool")).getValue())
+                                                  .add("firstname", 
((Field)((Repeater)form.getChild("contacts")).getWidget(1, 
"firstname")).getValue()));
+    }
+
+    public void doEditForm2() throws BindingException {
+        Form2Bean bean = new Form2Bean();
+
+        // fill bean with some data to avoid users having to type to much
+        bean.setEmail("[EMAIL PROTECTED]");
+        bean.setIpAddress("10.0.0.1");
+        bean.setPhoneCountry("32");
+        bean.setPhoneZone("2");
+        bean.setPhoneNumber("123456");
+        bean.setBirthday(new java.util.Date());
+        bean.setSex(Sex.FEMALE);
+        Contact contact = new Contact();
+        contact.setId(1);
+        contact.setFirstName("Hermann");
+        bean.addContact(contact);
+
+        FormInstance form = new FormInstance("forms/form2.xml", 
"forms/form2-binding.xml");
+        form.load(bean);
+        form.show("form/form2");
+        form.save(bean);
+                                         
+        sendPage("page/form2-result", new VarMap().add("form2bean", bean));
+    }
+}

Added: 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/PersistenceFlow.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/PersistenceFlow.java?view=auto&rev=111860
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/webapp/WEB-INF/src/org/apache/cocoon/samples/flow/java/PersistenceFlow.java
        Tue Dec 14 11:01:29 2004
@@ -0,0 +1,143 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package org.apache.cocoon.samples.flow.java;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import org.apache.cocoon.components.flow.java.AbstractContinuable;
+import org.apache.cocoon.components.flow.java.VarMap;
+import org.apache.cocoon.forms.binding.BindingException;
+import org.apache.cocoon.forms.flow.java.FormInstance;
+import org.apache.cocoon.ojb.broker.components.PBFactory;
+import org.apache.cocoon.ojb.samples.bean.Employee;
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.query.Criteria;
+import org.apache.ojb.broker.query.QueryByCriteria;
+
+public class PersistenceFlow extends AbstractContinuable {
+
+    private transient PersistenceBroker broker = null;
+
+    public PersistenceFlow() {
+        PBFactory factory = (PBFactory)getComponent(PBFactory.ROLE);
+        broker = factory.defaultPersistenceBroker();
+        releaseComponent(factory);
+    }
+
+    public void doInsertEmployee() throws BindingException {
+
+        // Create a empty Bean
+        Employee employee = new Employee();
+        // Fill some initial data to the bean
+        employee.setId(1);
+        // Load form descriptor
+        FormInstance form = new FormInstance("forms/employee.xml");
+        // Load form binding
+        form.createBinding("forms/employee-binding.xml");
+        // Load the Bean to the form
+        form.load(employee);
+        // Let Cocoon Forms handle the form
+        form.show("form/employee");
+        // Update the Bean based on user input
+        form.save(employee);
+        // Update Bean in Database
+        broker.store(employee);
+        // Send response to the user
+        doShowEmployee();
+    }
+
+    public void doUpdateEmployee() throws BindingException {
+
+        // Get id as parameter
+        int id = 1;
+        if (getRequest().getParameter("id")!=null)
+            id = Integer.parseInt(getRequest().getParameter("id")); 
+        else
+            throw new IllegalStateException("No parameter 'id'");
+
+        // Create a empty Bean
+        Employee employee = new Employee();
+        // Fill some initial data to the bean
+        employee.setId(id);
+        // Load bean based on the given PrimaryKey
+        employee = (Employee) broker.getObjectByIdentity(new 
Identity(employee, broker));
+        // Load form descriptor
+        FormInstance form = new FormInstance("forms/employee.xml");
+        // Load form binding
+        form.createBinding("forms/employee-binding.xml");
+        // Load the Bean to the form
+        form.load(employee);
+        // Let Cocoon Forms handle the form
+        form.show("form/employee");
+        // Update the Bean based on user input
+        form.save(employee);
+
+        // Update Bean in Database
+        broker.store(employee);
+
+        // Send response to the user
+        doShowEmployee();
+    }
+
+    public void doRemoveEmployee() {
+
+        // Get id as parameter
+        int id = 1;
+        if (getRequest().getParameter("id")!=null)
+            id = Integer.parseInt(getRequest().getParameter("id"));
+        else
+            throw new IllegalStateException("No parameter 'id'");
+
+        // Create a empty Bean
+        Employee employee = new Employee();
+        // Fill some initial data to the bean
+        employee.setId(id);
+        // Load bean based on the given PrimaryKey
+        employee = (Employee) broker.getObjectByIdentity(new 
Identity(employee, broker));
+        // Remove bean
+        broker.delete(employee);
+        // Send response to the user
+        doShowEmployee();
+    }
+
+    public void doShowEmployee() {
+
+        // Query all objects
+        ArrayList results = new ArrayList();
+        QueryByCriteria query = new QueryByCriteria(Employee.class, new 
Criteria());
+        for(Iterator i=broker.getCollectionByQuery(query).iterator(); 
i.hasNext();) {
+            results.add(i.next());
+        }
+        // Sort result
+        Collections.sort(results, new EmployeeComparator());
+        // Send response to the user
+        sendPage("page/employee-result", new VarMap().add("employee", 
results));
+    }
+
+    public class EmployeeComparator implements Comparator {
+        public int compare(Object o1, Object o2) {
+            return ((Employee)o1).getId()-((Employee)o2).getId();
+        }
+      
+        public boolean equals(Object obj) {
+            return true;
+        }
+    }
+}

Modified: cocoon/trunk/src/webapp/WEB-INF/web.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/webapp/WEB-INF/web.xml?view=diff&rev=111860&p1=cocoon/trunk/src/webapp/WEB-INF/web.xml&r1=111859&p2=cocoon/trunk/src/webapp/WEB-INF/web.xml&r2=111860
==============================================================================
--- cocoon/trunk/src/webapp/WEB-INF/web.xml     (original)
+++ cocoon/trunk/src/webapp/WEB-INF/web.xml     Tue Dec 14 11:01:29 2004
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
+<?xml version="1.0" encoding="UTF-8"?><!--
   Copyright 1999-2004 The Apache Software Foundation
 
   Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +13,6 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-
 <!--+
     | This is the Cocoon web-app configurations file
     +-->
@@ -48,8 +46,14 @@
 
     <!--
       The regular servlet class (trusts the servlet container classloader)
-      -->
     <servlet-class>org.apache.cocoon.servlet.CocoonServlet</servlet-class>
+      -->
+
+    
<servlet-class>org.apache.cocoon.servlet.ParanoidCocoonServlet</servlet-class>
+    <init-param>
+      <param-name>classloader-class</param-name>
+      <param-value>org.apache.javaflow.ContinuationClassLoader</param-value>
+    </init-param>
 
     <!--
       This parameter tells cocoon to set the thread's context classloader to
@@ -177,6 +181,7 @@
         org.apache.cocoon.samples.parentcm.Configurator -->
         <!-- For IBM WebSphere:
         com.ibm.servlet.classloader.Handler -->
+      
       </param-value>
     </init-param>
 

Modified: cocoon/trunk/status.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/status.xml?view=diff&rev=111860&p1=cocoon/trunk/status.xml&r1=111859&p2=cocoon/trunk/status.xml&r2=111860
==============================================================================
--- cocoon/trunk/status.xml     (original)
+++ cocoon/trunk/status.xml     Tue Dec 14 11:01:29 2004
@@ -202,6 +202,14 @@
 
   <changes>
  <release version="@version@" date="@date@">
+   <action dev="TC" type="add">
+     javaflow: auto-compilation for javaflow.
+     factored out javaflow and the auto-compilation (jci)
+     into separate projects.
+   </action>
+   <action dev="TC" type="add">
+    esql: added support for derby
+   </action>
    <action dev="LG" type="add">
      ContinuationsManager default implementation can now store continuations 
in user session. 
      Continuations are not available outside user session and invalidated 
automatically 

Modified: cocoon/trunk/tools/targets/webapp-build.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/tools/targets/webapp-build.xml?view=diff&rev=111860&p1=cocoon/trunk/tools/targets/webapp-build.xml&r1=111859&p2=cocoon/trunk/tools/targets/webapp-build.xml&r2=111860
==============================================================================
--- cocoon/trunk/tools/targets/webapp-build.xml (original)
+++ cocoon/trunk/tools/targets/webapp-build.xml Tue Dec 14 11:01:29 2004
@@ -46,6 +46,7 @@
       <fileset dir="${webapp}/WEB-INF">
         <include name="entities/**"/>
         <include name="classes/**"/>
+        <include name="src/**"/>
         <include name="*.x*"/>
       </fileset>
     </copy>

Reply via email to