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>