You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mr...@apache.org on 2006/12/13 07:19:45 UTC

svn commit: r486508 - in /struts/struts2/trunk: apps/showcase/ core/ core/src/main/java/org/apache/struts2/components/ core/src/main/java/org/apache/struts2/config/ core/src/main/java/org/apache/struts2/dispatcher/ core/src/main/java/org/apache/struts2...

Author: mrdon
Date: Tue Dec 12 22:19:43 2006
New Revision: 486508

URL: http://svn.apache.org/viewvc?view=rev&rev=486508
Log:
Moved continuations support into a new plugin
WW-1548 XW-453

Added:
    struts/struts2/trunk/plugins/continuations/
    struts/struts2/trunk/plugins/continuations/pom.xml
    struts/struts2/trunk/plugins/continuations/src/
    struts/struts2/trunk/plugins/continuations/src/main/
    struts/struts2/trunk/plugins/continuations/src/main/java/
    struts/struts2/trunk/plugins/continuations/src/main/java/org/
    struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/
    struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/
    struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/
    struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsActionEventListener.java
    struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsClassLoader.java
    struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsExtraParameterProvider.java
    struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/NonCloningContinuableObject.java
    struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/StrutsContinuationConfig.java
    struts/struts2/trunk/plugins/continuations/src/main/resources/
    struts/struts2/trunk/plugins/continuations/src/main/resources/struts-plugin.xml
Modified:
    struts/struts2/trunk/apps/showcase/pom.xml
    struts/struts2/trunk/core/pom.xml
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
    struts/struts2/trunk/plugins/pom.xml
    struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java

Modified: struts/struts2/trunk/apps/showcase/pom.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/apps/showcase/pom.xml?view=diff&rev=486508&r1=486507&r2=486508
==============================================================================
--- struts/struts2/trunk/apps/showcase/pom.xml (original)
+++ struts/struts2/trunk/apps/showcase/pom.xml Tue Dec 12 22:19:43 2006
@@ -64,6 +64,12 @@
 
         <dependency>
             <groupId>org.apache.struts</groupId>
+            <artifactId>struts2-continuations-plugin</artifactId>
+            <version>${pom.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.struts</groupId>
             <artifactId>struts2-codebehind-plugin</artifactId>
             <version>${pom.version}</version>
         </dependency>
@@ -120,11 +126,6 @@
          <artifactId>myfaces-api</artifactId>
          <version>1.1.2</version>
       </dependency>
-      <dependency>
-         <groupId>org.rifers</groupId>
-         <artifactId>rife-continuations</artifactId>
-         <version>0.0.2</version>
-     </dependency>
      <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>

Modified: struts/struts2/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/pom.xml?view=diff&rev=486508&r1=486507&r2=486508
==============================================================================
--- struts/struts2/trunk/core/pom.xml (original)
+++ struts/struts2/trunk/core/pom.xml Tue Dec 12 22:19:43 2006
@@ -305,12 +305,6 @@
                 </exclusion>
             </exclusions>
         </dependency-->
-      <dependency>
-         <groupId>org.rifers</groupId>
-         <artifactId>rife-continuations</artifactId>
-         <version>0.0.2</version>
-         <optional>true</optional>
-     </dependency>
  
         <dependency>
             <groupId>jmock</groupId>

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java?view=diff&rev=486508&r1=486507&r2=486508
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/URL.java Tue Dec 12 22:19:43 2006
@@ -42,7 +42,6 @@
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.XWorkContinuationConfig;
 
 /**
  * <!-- START SNIPPET: javadoc -->
@@ -141,7 +140,8 @@
     protected String portletUrlType;
     protected String anchor;
     protected String urlIncludeParams;
-
+    protected ExtraParameterProvider extraParameterProvider;
+    
     public URL(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
         super(stack);
         this.req = req;
@@ -152,6 +152,11 @@
     public void setUrlIncludeParams(String urlIncludeParams) {
         this.urlIncludeParams = urlIncludeParams;
     }
+    
+    @Inject(required=false)
+    public void setExtraParameterProvider(ExtraParameterProvider provider) {
+        this.extraParameterProvider = provider;
+    }
 
     public boolean start(Writer writer) {
         boolean result = super.start(writer);
@@ -172,14 +177,15 @@
 
             if (NONE.equalsIgnoreCase(includeParams)) {
                 mergeRequestParameters(value, parameters, Collections.EMPTY_MAP);
-                ActionContext.getContext().put(XWorkContinuationConfig.CONTINUE_KEY, null);
             } else if (ALL.equalsIgnoreCase(includeParams)) {
                 mergeRequestParameters(value, parameters, req.getParameterMap());
 
                 // for ALL also include GET parameters
                 includeGetParameters();
+                includeExtraParameters();
             } else if (GET.equalsIgnoreCase(includeParams) || (includeParams == null && value == null && action == null)) {
                 includeGetParameters();
+                includeExtraParameters();
             } else if (includeParams != null) {
                 LOG.warn("Unknown value for includeParams parameter to URL tag: " + includeParams);
             }
@@ -191,6 +197,11 @@
         return result;
     }
 
+    private void includeExtraParameters() {
+        if (extraParameterProvider != null) {
+            mergeRequestParameters(value, parameters, extraParameterProvider.getExtraParameters());
+        }
+    }
     private void includeGetParameters() {
         if(!(Dispatcher.getInstance().isPortletSupportActive() && PortletActionContext.isPortletRequest())) {
             String query = extractQueryString();
@@ -416,5 +427,9 @@
                 parameters.put(key, entry.getValue());
             }
         }
+    }
+    
+    public static interface ExtraParameterProvider {
+        public Map getExtraParameters();
     }
 }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java?view=diff&rev=486508&r1=486507&r2=486508
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java Tue Dec 12 22:19:43 2006
@@ -74,9 +74,6 @@
             if (StrutsConstants.STRUTS_DEVMODE.equals(name)) {
                 props.setProperty("devMode", settings.get(name), settings.getLocation(name));
             }
-            if (StrutsConstants.STRUTS_CONTINUATIONS_PACKAGE.equals(name)) {
-                props.setProperty("continuations.package", settings.get(name), settings.getLocation(name));
-            }
         }
         
         // Set default locale

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java?view=diff&rev=486508&r1=486507&r2=486508
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java Tue Dec 12 22:19:43 2006
@@ -73,7 +73,6 @@
 import com.opensymphony.xwork2.util.ObjectTypeDeterminerFactory;
 import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.util.ValueStackFactory;
-import com.opensymphony.xwork2.util.XWorkContinuationConfig;
 import com.opensymphony.xwork2.util.location.Location;
 import com.opensymphony.xwork2.util.location.LocationUtils;
 import com.opensymphony.xwork2.util.location.LocatableProperties;
@@ -463,17 +462,6 @@
             String namespace = mapping.getNamespace();
             String name = mapping.getName();
             String method = mapping.getMethod();
-
-            String id = request.getParameter(XWorkContinuationConfig.CONTINUE_PARAM);
-            if (id != null) {
-                // remove the continue key from the params - we don't want to bother setting
-                // on the value stack since we know it won't work. Besides, this breaks devMode!
-                Map params = (Map) extraContext.get(ActionContext.PARAMETERS);
-                params.remove(XWorkContinuationConfig.CONTINUE_PARAM);
-
-                // and now put the key in the context to be picked up later by XWork
-                extraContext.put(XWorkContinuationConfig.CONTINUE_KEY, id);
-            }
 
             Configuration config = configurationManager.getConfiguration();
             ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java?view=diff&rev=486508&r1=486507&r2=486508
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java Tue Dec 12 22:19:43 2006
@@ -41,7 +41,6 @@
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.util.TextParseUtil;
 import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.XWorkContinuationConfig;
 
 
 /**
@@ -164,16 +163,6 @@
             }
 
             link.append(requestURI);
-        }
-
-        // tie in the continuation parameter
-        String continueId = (String) ActionContext.getContext().get(XWorkContinuationConfig.CONTINUE_KEY);
-        if (continueId != null) {
-            if (params == null) {
-                params = Collections.singletonMap(XWorkContinuationConfig.CONTINUE_PARAM, continueId);
-            } else {
-                params.put(XWorkContinuationConfig.CONTINUE_PARAM, continueId);
-            }
         }
 
         //if the action was not explicitly set grab the params from the request

Added: struts/struts2/trunk/plugins/continuations/pom.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/continuations/pom.xml?view=auto&rev=486508
==============================================================================
--- struts/struts2/trunk/plugins/continuations/pom.xml (added)
+++ struts/struts2/trunk/plugins/continuations/pom.xml Tue Dec 12 22:19:43 2006
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.struts</groupId>
+        <artifactId>struts2-plugins</artifactId>
+        <version>2.0.2-SNAPSHOT</version>
+    </parent>
+    <groupId>org.apache.struts</groupId>
+    <artifactId>struts2-continuations-plugin</artifactId>
+    <packaging>jar</packaging>
+    <name>Struts 2 Continuations Plugin</name>
+    
+    <scm>
+       <connection>scm:svn:http://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/continuations/</connection>
+       <developerConnection>scm:svn:https://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/continuations/</developerConnection>
+       <url>http://svn.apache.org/viewcvs.cgi/struts/struts2/trunk/plugins/continuations/</url>
+    </scm>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.rifers</groupId>
+            <artifactId>rife-continuations</artifactId>
+            <version>0.0.2</version>
+        </dependency>
+       <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+            <version>3.8.1</version>
+        </dependency>
+
+
+   </dependencies>
+</project>

Added: struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsActionEventListener.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsActionEventListener.java?view=auto&rev=486508
==============================================================================
--- struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsActionEventListener.java (added)
+++ struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsActionEventListener.java Tue Dec 12 22:19:43 2006
@@ -0,0 +1,98 @@
+/*
+ * $Id: Dispatcher.java 484733 2006-12-08 20:16:16Z mrdon $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.continuations;
+
+import java.util.Map;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionEventListener;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.uwyn.rife.continuations.ContinuableObject;
+import com.uwyn.rife.continuations.ContinuationConfig;
+import com.uwyn.rife.continuations.ContinuationContext;
+import com.uwyn.rife.continuations.ContinuationManager;
+import com.uwyn.rife.continuations.exceptions.PauseException;
+
+/**
+ * Hooks Rife continuations into key events in the Action instance lifecycle
+ */
+public class ContinuationsActionEventListener implements ActionEventListener {
+    ContinuationManager cm;
+    
+    public ContinuationsActionEventListener() {
+        if (ContinuationConfig.getInstance() != null) {
+            cm = new ContinuationManager();
+        }
+    }
+    
+    /**
+     * Sets the continuation context and loads the proper continuation action
+     */
+    public Object prepare(Object action, ValueStack stack) {
+        Map params = ActionContext.getContext().getParameters();
+        String contId = (String) params.get(StrutsContinuationConfig.CONTINUE_PARAM);
+        if (contId != null) {
+            // remove the continue key from the params - we don't want to bother setting
+            // on the value stack since we know it won't work. Besides, this breaks devMode!
+            params.remove(StrutsContinuationConfig.CONTINUE_PARAM);
+        }
+        
+        
+        if (action instanceof ContinuableObject) {
+            ContinuationContext ctx = ContinuationContext.createInstance((ContinuableObject) action);
+            if (action instanceof NonCloningContinuableObject) {
+                ctx.setShouldClone(false);
+            }
+        }
+
+        try {
+            if (contId != null) {
+                ContinuationContext context = cm.getContext(contId);
+                if (context != null) {
+                    ContinuationContext.setContext(context);
+                    // use the original action instead
+                    Object original = context.getContinuable();
+                    action = original;
+                }
+            }
+        } catch (CloneNotSupportedException e) {
+            e.printStackTrace();
+        }
+        return action;
+    }
+    
+    /**
+     * Handles the normal continuation exception
+     */
+    public String handleException(Throwable t, ValueStack stack) {
+        if (t instanceof PauseException) {
+            // continuations in effect!
+            PauseException pe = ((PauseException) t);
+            ContinuationContext context = pe.getContext();
+            String result = (String) pe.getParameters();
+            stack.getContext().put(StrutsContinuationConfig.CONTINUE_KEY, context.getId());
+            cm.addContext(context);
+
+            return result;
+        }
+        return null;
+    }
+}

Added: struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsClassLoader.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsClassLoader.java?view=auto&rev=486508
==============================================================================
--- struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsClassLoader.java (added)
+++ struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsClassLoader.java Tue Dec 12 22:19:43 2006
@@ -0,0 +1,110 @@
+/*
+ * $Id: Dispatcher.java 484733 2006-12-08 20:16:16Z mrdon $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.continuations;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.StrutsConstants;
+
+import com.opensymphony.xwork2.XWorkException;
+import com.opensymphony.xwork2.inject.Inject;
+
+/**
+ * Uses the Rife continuations classloader to bytecode enhance actions.  Only
+ * enhances actions in the configured package.
+ */
+public class ContinuationsClassLoader extends ClassLoader {
+    
+    private String base;
+    private ClassLoader parent;
+    
+    private static final Log LOG = LogFactory.getLog(ContinuationsClassLoader.class);
+
+    @Inject(value=StrutsConstants.STRUTS_CONTINUATIONS_PACKAGE, required=false)
+    public void setContinuationPackage(String continuationPackage) {
+        
+        // This reflection silliness is to ensure Rife is optional
+        Class contConfig = null;
+        try {
+            contConfig = Class.forName("com.uwyn.rife.continuations.ContinuationConfig");
+        } catch (ClassNotFoundException ex) {
+            throw new XWorkException("Unable to use continuations package, as the Rife " +
+                    "continuations jar is missing", ex);
+        }
+        try {
+            Method m = contConfig.getMethod("setInstance", contConfig);
+            m.invoke(contConfig, new StrutsContinuationConfig());
+        } catch (NoSuchMethodException ex) {
+            throw new XWorkException("Incorrect version of the Rife continuation library", ex);
+        } catch (IllegalAccessException ex) {
+            throw new XWorkException("Incorrect version of the Rife continuation library", ex);
+        } catch (InvocationTargetException ex) {
+            throw new XWorkException("Unable to initialize the Rife continuation library", ex);
+        }
+        this.base = continuationPackage;
+        this.parent = Thread.currentThread().getContextClassLoader();
+    }
+
+    public Class loadClass(String name) throws ClassNotFoundException {
+        if (validName(name)) {
+            Class clazz = findLoadedClass(name);
+            if (clazz == null) {
+                try {
+                    byte[] bytes = com.uwyn.rife.continuations.util.ClassByteUtil.getBytes(name, parent);
+                    if (bytes == null) {
+                        throw new ClassNotFoundException(name);
+                    }
+
+                    byte[] resume_bytes = null;
+                    try {
+                        resume_bytes = com.uwyn.rife.continuations.ContinuationInstrumentor.instrument(bytes, name, false);
+                    } catch (ClassNotFoundException e) {
+                        // this can happen when the Rife Continuations code gets broken (there are bugs in it still, ya know!)
+                        // rather than making a big deal, we'll quietly log this and move on
+                        // when more people are using continuations, perhaps we'll raise the log level
+                        LOG.debug("Error instrumenting with RIFE/Continuations, " +
+                                "loading class normally without continuation support", e);
+                    }
+
+                    if (resume_bytes == null) {
+                        return parent.loadClass(name);
+                    } else {
+                        return defineClass(name, resume_bytes, 0, resume_bytes.length);
+                    }
+                } catch (IOException e) {
+                    throw new XWorkException("Continuation error", e);
+                }
+            } else {
+                return clazz;
+            }
+        } else {
+            return parent.loadClass(name);
+        }
+    }
+
+    private boolean validName(String name) {
+        return name.startsWith(base + ".");
+    }
+}

Added: struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsExtraParameterProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsExtraParameterProvider.java?view=auto&rev=486508
==============================================================================
--- struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsExtraParameterProvider.java (added)
+++ struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/ContinuationsExtraParameterProvider.java Tue Dec 12 22:19:43 2006
@@ -0,0 +1,44 @@
+/*
+ * $Id: URL.java 474191 2006-11-13 08:30:40Z mrdon $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.continuations;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.struts2.components.URL.ExtraParameterProvider;
+
+import com.opensymphony.xwork2.ActionContext;
+
+/**
+ * Injects the continuation id into the url parameters
+ */
+public class ContinuationsExtraParameterProvider implements ExtraParameterProvider {
+
+    public Map getExtraParameters() {
+        // tie in the continuation parameter
+        String continueId = (String) ActionContext.getContext().get(StrutsContinuationConfig.CONTINUE_KEY);
+        if (continueId != null) {
+            return Collections.singletonMap(StrutsContinuationConfig.CONTINUE_PARAM, continueId);
+        }
+        return Collections.EMPTY_MAP;
+    }
+
+}

Added: struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/NonCloningContinuableObject.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/NonCloningContinuableObject.java?view=auto&rev=486508
==============================================================================
--- struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/NonCloningContinuableObject.java (added)
+++ struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/NonCloningContinuableObject.java Tue Dec 12 22:19:43 2006
@@ -0,0 +1,32 @@
+/*
+ * $Id: URL.java 474191 2006-11-13 08:30:40Z mrdon $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.continuations;
+
+import com.uwyn.rife.continuations.ContinuableObject;
+
+/**
+ * Implementing this interface indicates that the action should not be cloned, but instead should be re-used. This is
+ * needed when you are using objects, fields, and method variables that cannot be cloned. The downside to using this is
+ * that the advanced forward/backward historical support that normally automatically comes with continuations is no
+ * longer available.
+ */
+public interface NonCloningContinuableObject extends ContinuableObject {
+}

Added: struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/StrutsContinuationConfig.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/StrutsContinuationConfig.java?view=auto&rev=486508
==============================================================================
--- struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/StrutsContinuationConfig.java (added)
+++ struts/struts2/trunk/plugins/continuations/src/main/java/org/apache/struts2/continuations/StrutsContinuationConfig.java Tue Dec 12 22:19:43 2006
@@ -0,0 +1,51 @@
+/*
+ * $Id: URL.java 474191 2006-11-13 08:30:40Z mrdon $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.continuations;
+
+import com.uwyn.rife.continuations.ContinuationConfig;
+
+/**
+ * RIFE Continuation configuration.
+ */
+public class StrutsContinuationConfig extends ContinuationConfig {
+    public static final String CONTINUE_PARAM = "__continue";
+    public static final String CONTINUE_KEY = "__continue";
+
+    public String getContinuableClassInternalName() {
+        return "com.opensymphony.xwork2.ActionSupport";
+    }
+
+    public String getContinuableInterfaceInternalName() {
+        return "com.opensymphony.xwork2.Action";
+    }
+
+    public String getEntryMethod() {
+        return "execute()Ljava/lang/String;";
+    }
+
+    public String getContinuableClassOrInterfaceName() {
+        return "com.opensymphony.xwork2.ActionSupport";
+    }
+
+    public String getPauseSignature() {
+        return "(Ljava/lang/String;)V";
+    }
+}

Added: struts/struts2/trunk/plugins/continuations/src/main/resources/struts-plugin.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/continuations/src/main/resources/struts-plugin.xml?view=auto&rev=486508
==============================================================================
--- struts/struts2/trunk/plugins/continuations/src/main/resources/struts-plugin.xml (added)
+++ struts/struts2/trunk/plugins/continuations/src/main/resources/struts-plugin.xml Tue Dec 12 22:19:43 2006
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!DOCTYPE struts PUBLIC
+    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
+    "http://struts.apache.org/dtds/struts-2.0.dtd">
+    
+<struts>
+    <bean type="java.lang.ClassLoader" name="objectFactory.classloader" class="org.apache.struts2.continuations.ContinuationsClassLoader" />
+    <bean type="org.apache.struts2.components.URL$ExtraParameterProvider" class="org.apache.struts2.continuations.ContinuationsExtraParameterProvider" />
+    <bean type="com.opensymphony.xwork2.ActionEventListener" class="org.apache.struts2.continuations.ContinuationsActionEventListener" />
+    
+</struts>

Modified: struts/struts2/trunk/plugins/pom.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/pom.xml?view=diff&rev=486508&r1=486507&r2=486508
==============================================================================
--- struts/struts2/trunk/plugins/pom.xml (original)
+++ struts/struts2/trunk/plugins/pom.xml Tue Dec 12 22:19:43 2006
@@ -21,6 +21,7 @@
     <modules>
         <module>codebehind</module>
         <module>config-browser</module>
+        <module>continuations</module>
         <module>jasperreports</module>
         <module>jfreechart</module>
         <module>jsf</module>

Modified: struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java?view=diff&rev=486508&r1=486507&r2=486508
==============================================================================
--- struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java (original)
+++ struts/struts2/trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java Tue Dec 12 22:19:43 2006
@@ -36,6 +36,7 @@
 import com.opensymphony.module.sitemesh.Page;
 import com.opensymphony.module.sitemesh.filter.PageFilter;
 import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionEventListener;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ActionProxy;
 import com.opensymphony.xwork2.ActionSupport;
@@ -177,6 +178,9 @@
 
         public String invokeActionOnly() throws Exception {
             return null;
+        }
+
+        public void setActionEventListener(ActionEventListener listener) {
         }
     }
 }