Updated Branches:
  refs/heads/master 2a8b6d0a5 -> 9133bc44b

Prototype for DELTASPIKE-454

Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/c156d05d
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/c156d05d
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/c156d05d

Branch: refs/heads/master
Commit: c156d05d8a9cad30a0d3860749091a36d2d9926c
Parents: 2a8b6d0
Author: andraschko <andrasc...@dev-4.ifvuf.de>
Authored: Wed Jan 8 18:23:30 2014 +0100
Committer: andraschko <andrasc...@dev-4.ifvuf.de>
Committed: Wed Jan 8 18:23:30 2014 +0100

----------------------------------------------------------------------
 .../jsf/spi/scope/window/ClientWindow.java      |  74 +++++++++++-
 .../spi/scope/window/ClientWindowConfig.java    |   2 +
 .../DeltaSpikeExternalContextWrapper.java       |   4 +-
 .../impl/scope/window/ClientWindowHelper.java   |  99 ++++++++++++++++
 .../impl/scope/window/DefaultClientWindow.java  | 117 +++++++++++++++++--
 .../deltaspike/jsf/impl/util/JsfUtils.java      |  96 ++++++++++++++-
 .../jsf/impl/view/DeltaSpikeViewHandler.java    |   7 ++
 7 files changed, 383 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/c156d05d/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindow.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindow.java
 
b/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindow.java
index d272f33..dba12c9 100644
--- 
a/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindow.java
+++ 
b/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindow.java
@@ -18,6 +18,7 @@
  */
 package org.apache.deltaspike.jsf.spi.scope.window;
 
+import java.util.Map;
 import javax.faces.context.FacesContext;
 
 /**
@@ -33,8 +34,10 @@ import javax.faces.context.FacesContext;
  * ClientWindow instances are most likely &#064;ApplicationScoped.
  * </p>
  */
-public interface ClientWindow
+public abstract class ClientWindow
 {
+    private static final String 
PER_USE_CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED_KEY =
+            ClientWindow.class.getName() + ".ClientWindowRenderModeEnablement";
 
     /**
      * Extract the windowId for the current request.
@@ -47,5 +50,72 @@ public interface ClientWindow
      * @param facesContext for the request
      * @return the extracted WindowId of the Request, or <code>null</code> if 
there is no window assigned.
      */
-    String getWindowId(FacesContext facesContext);
+    public abstract String getWindowId(FacesContext facesContext);
+
+    /**
+     * <p>Components that permit per-use disabling
+     * of the appending of the ClientWindow in generated URLs must call this 
method
+     * first before rendering those URLs.  The caller must call
+     * {@link #enableClientWindowRenderMode(javax.faces.context.FacesContext)}
+     * from a <code>finally</code> block after rendering the URL.  If
+     * {@link #CLIENT_WINDOW_MODE_PARAM_NAME} is "url" without the quotes, all 
generated
+     * URLs that cause a GET request must append the ClientWindow by default.
+     * This is specified as a static method because callsites need to access it
+     * without having access to an actual {@code ClientWindow} instance.</p>
+     *
+     * @param context the {@link FacesContext} for this request.
+     */
+    public void disableClientWindowRenderMode(FacesContext context)
+    {
+        Map<Object, Object> attrMap = context.getAttributes();
+        attrMap.put(PER_USE_CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED_KEY, 
Boolean.TRUE);
+    }
+
+    /**
+     * <p>Components that permit per-use disabling
+     * of the appending of the ClientWindow in generated URLs must call this 
method
+     * first after rendering those URLs.  If
+     * {@link #CLIENT_WINDOW_MODE_PARAM_NAME} is "url" without the quotes, all 
generated
+     * URLs that cause a GET request must append the ClientWindow by default.
+     * This is specified as a static method because callsites need to access it
+     * without having access to an actual {@code ClientWindow} instance.</p>
+     *
+     * @param context the {@link FacesContext} for this request.
+     */
+    public void enableClientWindowRenderMode(FacesContext context)
+    {
+        Map<Object, Object> attrMap = context.getAttributes();
+        attrMap.remove(PER_USE_CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED_KEY);
+    }
+
+    /**
+     * <p>Methods that append the ClientWindow to generated
+     * URLs must call this method to see if they are permitted to do so.  If
+     * {@link #CLIENT_WINDOW_MODE_PARAM_NAME} is "url" without the quotes, all 
generated
+     * URLs that cause a GET request must append the ClientWindow by default.
+     * This is specified as a static method because callsites need to access it
+     * without having access to an actual {@code ClientWindow} instance.</p>
+     *
+     * @param context the {@link FacesContext} for this request.
+     */
+    public boolean isClientWindowRenderModeEnabled(FacesContext context)
+    {
+        Map<Object, Object> attrMap = context.getAttributes();
+        boolean result = 
!attrMap.containsKey(PER_USE_CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED_KEY);
+        return result;
+    }
+
+    /**
+     * <p>This method will be called whenever a URL
+     * is generated by the runtime where client window related parameters need
+     * to be inserted into the URL.  This guarantees custom {@code 
ClientWindow} implementations
+     * that they will have the opportunity to insert any additional client 
window specific
+     * information in any case where a URL is generated, such as the rendering
+     * of hyperlinks.  The returned map must be immutable.  The default 
implementation of this method returns
+     * the empty map.</p>
+
+     * @param context the {@code FacesContext} for this request.
+     * @return {@code null} or a map of parameters to insert into the URL 
query string.
+     */
+    public abstract Map<String, String> getQueryURLParameters(FacesContext 
context);
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/c156d05d/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindowConfig.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindowConfig.java
 
b/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindowConfig.java
index 2828bd4..d9aa688 100644
--- 
a/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindowConfig.java
+++ 
b/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindowConfig.java
@@ -53,6 +53,8 @@ public interface ClientWindowConfig
          */
         DELEGATED,
 
+        URL,
+
         /**
          * If you set this mode, you also need to provide an own {@link 
ClientWindow} implementation.
          */

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/c156d05d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeExternalContextWrapper.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeExternalContextWrapper.java
 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeExternalContextWrapper.java
index afa9782..c67bbff 100644
--- 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeExternalContextWrapper.java
+++ 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeExternalContextWrapper.java
@@ -24,6 +24,8 @@ import org.apache.deltaspike.jsf.impl.util.JsfUtils;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.ExternalContextWrapper;
 import java.io.IOException;
+import javax.faces.context.FacesContext;
+import org.apache.deltaspike.jsf.impl.scope.window.ClientWindowHelper;
 
 public class DeltaSpikeExternalContextWrapper extends ExternalContextWrapper 
implements Deactivatable
 {
@@ -38,7 +40,7 @@ public class DeltaSpikeExternalContextWrapper extends 
ExternalContextWrapper imp
     public void redirect(String url) throws IOException
     {
         JsfUtils.saveFacesMessages(this.wrapped);
-        this.wrapped.redirect(url);
+        
this.wrapped.redirect(ClientWindowHelper.appendWindowId(FacesContext.getCurrentInstance(),
 url));
     }
 
     public ExternalContext getWrapped()

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/c156d05d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/ClientWindowHelper.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/ClientWindowHelper.java
 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/ClientWindowHelper.java
new file mode 100644
index 0000000..5137054
--- /dev/null
+++ 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/ClientWindowHelper.java
@@ -0,0 +1,99 @@
+/*
+ * 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.deltaspike.jsf.impl.scope.window;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.jsf.impl.util.JsfUtils;
+import org.apache.deltaspike.jsf.spi.scope.window.ClientWindow;
+
+public final class ClientWindowHelper
+{
+    private ClientWindowHelper()
+    {
+
+    }
+
+    /**
+     * Handles the initial redirect for the URL modus, if no windowId is 
available in the current request URL.
+     *
+     * @param facesContext the {@link FacesContext}
+     */
+    public static void handleInitialRedirect(FacesContext facesContext)
+    {
+        ExternalContext externalContext = facesContext.getExternalContext();
+
+        // send initial redirect to add the windowId to the current request URL
+        String viewId = 
facesContext.getApplication().getViewHandler().deriveViewId(
+                facesContext, externalContext.getRequestServletPath());
+
+        // The NavigationHandler tries to access the UIViewRoot but it isn't 
available because our
+        // ClientWindow will be initialized before the normal JSF lifecycle
+        UIViewRoot viewRoot = new UIViewRoot();
+        viewRoot.setViewId(viewId);
+        facesContext.setViewRoot(viewRoot);
+
+        String outcome = viewId + 
"?faces-redirect=true&includeViewParams=true";
+        // append it manually - includeViewParams doesn't work here because of 
the not fully initialized UIViewRoot
+        outcome = JsfUtils.addRequestParameters(externalContext, outcome, 
true);
+
+        
facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext,
 null, outcome);
+    }
+
+    /**
+     * Appends the current windowIf to the given url, if enabled via
+     * {@link 
ClientWindow#isClientWindowRenderModeEnabled(javax.faces.context.FacesContext)}
+     *
+     * @param facesContext the {@link FacesContext}
+     * @param url the url
+     * @return if enabled, the url with windowId, otherwise the umodified url
+     */
+    public static String appendWindowId(FacesContext facesContext, String url)
+    {
+        ClientWindow clientWindow = 
BeanProvider.getContextualReference(ClientWindow.class);
+        if (clientWindow != null && 
clientWindow.isClientWindowRenderModeEnabled(FacesContext.getCurrentInstance()))
+        {
+            Map<String, String> parameters = 
clientWindow.getQueryURLParameters(facesContext);
+
+            if (parameters != null && !parameters.isEmpty())
+            {
+                String targetUrl = url;
+
+                for (Entry<String, String> entry : parameters.entrySet())
+                {
+                    // NOTE: each call will instantiate a new StringBuilder
+                    // i didn't optimized this call because it's unlikely that 
there will be multiple parameters
+                    targetUrl = 
JsfUtils.addParameter(facesContext.getExternalContext(),
+                            targetUrl,
+                            true,
+                            entry.getKey(),
+                            entry.getValue());
+                }
+
+                return targetUrl;
+            }
+        }
+
+        return url;
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/c156d05d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
index 725007e..a34c84f 100644
--- 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
+++ 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
@@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.Random;
 import java.util.logging.Logger;
@@ -50,7 +51,7 @@ import static 
org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig.Clie
  *
  */
 @ApplicationScoped
-public class DefaultClientWindow implements ClientWindow
+public class DefaultClientWindow extends ClientWindow
 {
 
     /**
@@ -65,6 +66,11 @@ public class DefaultClientWindow implements ClientWindow
     public static final String DELTASPIKE_WINDOW_ID_POST_PARAM = 
"dsPostWindowId";
     public static final String JSF_WINDOW_ID_POST_PARAM = 
"javax.faces.ClientWindow";
 
+    /**
+     * GET request parameter
+     */
+    public static final String DELTASPIKE_WINDOW_ID_URL_PARAM = "dswid";
+
     private static final Logger logger = 
Logger.getLogger(DefaultClientWindow.class.getName());
 
 
@@ -75,6 +81,7 @@ public class DefaultClientWindow implements ClientWindow
     private static final String WINDOW_ID_REPLACE_PATTERN = 
"$$windowIdValue$$";
     private static final String NOSCRIPT_URL_REPLACE_PATTERN = 
"$$noscriptUrl$$";
 
+    private static final String NEW_WINDOW_ID = 
DefaultClientWindow.class.getName() + ".NEW_WINDOW_ID";
 
     /**
      * Use this parameter to force a 'direct' request from the clients without 
any windowId detection
@@ -110,6 +117,29 @@ public class DefaultClientWindow implements ClientWindow
             return ClientWindowAdapter.getWindowIdFromJsf(facesContext);
         }
 
+        if (ClientWindowRenderMode.URL.equals(clientWindowRenderMode))
+        {
+            ExternalContext externalContext = 
facesContext.getExternalContext();
+
+            if (facesContext.getAttributes().containsKey(NEW_WINDOW_ID))
+            {
+                return (String) 
facesContext.getAttributes().get(NEW_WINDOW_ID);
+            }
+            else if 
(externalContext.getRequestParameterMap().containsKey(DELTASPIKE_WINDOW_ID_URL_PARAM))
+            {
+                return 
externalContext.getRequestParameterMap().get(DELTASPIKE_WINDOW_ID_URL_PARAM);
+            }
+            else
+            {
+                // store the new windowId as context attribute to prevent 
infinite loops
+                // the #sendRedirect will append the windowId (from 
#getWindowId again) to the redirectUrl
+                facesContext.getAttributes().put(NEW_WINDOW_ID, 
generateNewWindowId());
+                ClientWindowHelper.handleInitialRedirect(facesContext);
+                facesContext.responseComplete();
+                return null;
+            }
+        }
+
         if (facesContext.isPostback())
         {
             return getPostBackWindowId(facesContext);
@@ -237,17 +267,7 @@ public class DefaultClientWindow implements ClientWindow
 
         // add request parameter
         url = JsfUtils.addPageParameters(externalContext, url, true);
-
-        // add noscript parameter
-        if (url.contains("?"))
-        {
-            url = url + "&";
-        }
-        else
-        {
-            url = url + "?";
-        }
-        url = url + NOSCRIPT_PARAMETER + "=true";
+        url = JsfUtils.addParameter(externalContext, url, false, 
NOSCRIPT_PARAMETER, "true");
 
         // NOTE that the url could contain data for an XSS attack
         // like e.g. ?"></a><a href%3D"http://hacker.org/attack.html?a
@@ -287,4 +307,77 @@ public class DefaultClientWindow implements ClientWindow
         return "";
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void disableClientWindowRenderMode(FacesContext context)
+    {
+        ClientWindowRenderMode clientWindowRenderMode = 
clientWindowConfig.getClientWindowRenderMode(context);
+
+        if (ClientWindowRenderMode.DELEGATED.equals(clientWindowRenderMode))
+        {
+            
context.getExternalContext().getClientWindow().disableClientWindowRenderMode(context);
+        }
+        else if (ClientWindowRenderMode.URL.equals(clientWindowRenderMode))
+        {
+            super.disableClientWindowRenderMode(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void enableClientWindowRenderMode(FacesContext context)
+    {
+        ClientWindowRenderMode clientWindowRenderMode = 
clientWindowConfig.getClientWindowRenderMode(context);
+
+        if (ClientWindowRenderMode.DELEGATED.equals(clientWindowRenderMode))
+        {
+            
context.getExternalContext().getClientWindow().enableClientWindowRenderMode(context);
+        }
+        else if (ClientWindowRenderMode.URL.equals(clientWindowRenderMode))
+        {
+            super.enableClientWindowRenderMode(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isClientWindowRenderModeEnabled(FacesContext context)
+    {
+        ClientWindowRenderMode clientWindowRenderMode = 
clientWindowConfig.getClientWindowRenderMode(context);
+
+        if (ClientWindowRenderMode.URL.equals(clientWindowRenderMode))
+        {
+            return super.isClientWindowRenderModeEnabled(context);
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Map<String, String> getQueryURLParameters(FacesContext context)
+    {
+        ClientWindowRenderMode clientWindowRenderMode = 
clientWindowConfig.getClientWindowRenderMode(context);
+
+        if (ClientWindowRenderMode.URL.equals(clientWindowRenderMode))
+        {
+            String windowId = getWindowId(context);
+            if (windowId != null)
+            {
+                Map<String, String> params = new HashMap<String, String>();
+                params.put(DELTASPIKE_WINDOW_ID_URL_PARAM, 
getWindowId(context));
+                return params;
+            }
+        }
+
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/c156d05d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/JsfUtils.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/JsfUtils.java
 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/JsfUtils.java
index 63a752a..f5aea23 100644
--- 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/JsfUtils.java
+++ 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/JsfUtils.java
@@ -76,7 +76,7 @@ public abstract class JsfUtils
     }
 
     /**
-     * Adds the current request-parameters to the given url
+     * Adds the current page-parameters to the given url
      *
      * @param externalContext current external-context
      * @param url             current url
@@ -124,6 +124,100 @@ public abstract class JsfUtils
     }
 
     /**
+     * Adds a paramter to the given url.
+     *
+     * @param externalContext   current external-context
+     * @param url               current url
+     * @param encodeValues      flag which indicates if parameter values 
should be encoded or not
+     * @param name              the paramter name
+     * @param value             the paramter value
+     * @return url with appended parameter
+     */
+    public static String addParameter(ExternalContext externalContext, String 
url, boolean encodeValues,
+            String name, String value)
+    {
+        // don't append if already available
+        if (url.contains(name + "=" + value)
+                || url.contains(name + "=" + encodeURLParameterValue(value, 
externalContext)))
+        {
+            return url;
+        }
+
+        StringBuilder finalUrl = new StringBuilder(url);
+
+        if (url.contains("?"))
+        {
+            finalUrl.append("&");
+        }
+        else
+        {
+            finalUrl.append("?");
+        }
+
+        finalUrl.append(name);
+        finalUrl.append("=");
+
+        if (encodeValues)
+        {
+            finalUrl.append(JsfUtils.encodeURLParameterValue(value, 
externalContext));
+        }
+        else
+        {
+            finalUrl.append(value);
+        }
+
+        return finalUrl.toString();
+    }
+
+    /**
+     * Adds the current request-parameters to the given url
+     *
+     * @param externalContext current external-context
+     * @param url             current url
+     * @param encodeValues    flag which indicates if parameter values should 
be encoded or not
+     * @return url with request-parameters
+     */
+    public static String addRequestParameters(ExternalContext externalContext, 
String url, boolean encodeValues)
+    {
+        StringBuilder finalUrl = new StringBuilder(url);
+        boolean existingParameters = url.contains("?");
+
+        for (Map.Entry<String, String[]> entry : 
externalContext.getRequestParameterValuesMap().entrySet())
+        {
+            for (String value : entry.getValue())
+            {
+                if (!url.contains(entry.getKey() + "=" + value) &&
+                        !url.contains(entry.getKey() + "=" + 
encodeURLParameterValue(value, externalContext)))
+                {
+                    if (!existingParameters)
+                    {
+                        finalUrl.append("?");
+                        existingParameters = true;
+                    }
+                    else
+                    {
+                        finalUrl.append("&");
+                    }
+
+                    finalUrl.append(entry.getKey());
+                    finalUrl.append("=");
+
+                    if (encodeValues)
+                    {
+                        
finalUrl.append(JsfUtils.encodeURLParameterValue(value, externalContext));
+                    }
+                    else
+                    {
+                        finalUrl.append(value);
+                    }
+                }
+            }
+        }
+
+        return finalUrl.toString();
+    }
+
+    /**
      * Encodes the given value using URLEncoder.encode() with the charset 
returned
      * from ExternalContext.getResponseCharacterEncoding().
      * This is exactly how the ExternalContext impl encodes URL parameter 
values.

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/c156d05d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/view/DeltaSpikeViewHandler.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/view/DeltaSpikeViewHandler.java
 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/view/DeltaSpikeViewHandler.java
index 7c10c30..234a50e 100644
--- 
a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/view/DeltaSpikeViewHandler.java
+++ 
b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/view/DeltaSpikeViewHandler.java
@@ -26,6 +26,7 @@ import javax.faces.application.ViewHandler;
 import javax.faces.application.ViewHandlerWrapper;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
+import org.apache.deltaspike.jsf.impl.scope.window.ClientWindowHelper;
 
 /**
  * Aggregates all {@link ViewHandler} implementations provided by DeltaSpike
@@ -72,6 +73,12 @@ public class DeltaSpikeViewHandler extends 
ViewHandlerWrapper implements Deactiv
     }
 
     @Override
+    public String getActionURL(FacesContext context, String viewId)
+    {
+        return ClientWindowHelper.appendWindowId(context, 
this.wrapped.getActionURL(context, viewId));
+    }
+
+    @Override
     public ViewHandler getWrapped()
     {
         return this.wrapped;

Reply via email to