Revision: 465
Author: lincolnbaxter
Date: Sun Nov 7 15:01:05 2010
Log: * Updated URLEncoding for Redirects. Added tests to verify.
http://code.google.com/p/prettyfaces/source/detail?r=465
Added:
/prettyfaces/trunk/tests-jsf2/src/test/java/com/ocpsoft/pretty/faces/test/redirect
/prettyfaces/trunk/tests-jsf2/src/test/java/com/ocpsoft/pretty/faces/test/redirect/RedirectBean.java
/prettyfaces/trunk/tests-jsf2/src/test/java/com/ocpsoft/pretty/faces/test/redirect/URLRedirectTest.java
/prettyfaces/trunk/tests-jsf2/src/test/resources/redirect
/prettyfaces/trunk/tests-jsf2/src/test/resources/redirect/redirect-pretty-config.xml
/prettyfaces/trunk/tests-jsf2/src/test/resources/redirect/redirect.xhtml
Deleted:
/prettyfaces/trunk/tests-jsf2/src/test/resources/redirect/encoding-pretty-config.xml
/prettyfaces/trunk/tests-jsf2/src/test/resources/redirect/encoding.xhtml
Modified:
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/application/PrettyRedirector.java
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/beans/ExtractedValuesURLBuilder.java
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/event/PrettyPhaseListener.java
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/url/QueryString.java
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/application/PrettyRedirector.java
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/application/PrettyViewHandler.java
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/component/LocationBehavior.java
/prettyfaces/trunk/tests-jsf2/src/test/java/com/ocpsoft/pretty/faces/test/encoding/URLEncodingTest.java
=======================================
--- /dev/null
+++
/prettyfaces/trunk/tests-jsf2/src/test/java/com/ocpsoft/pretty/faces/test/redirect/RedirectBean.java
Sun Nov 7 15:01:05 2010
@@ -0,0 +1,42 @@
+package com.ocpsoft.pretty.faces.test.redirect;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.RequestScoped;
+
+@ManagedBean
+@RequestScoped
+public class RedirectBean
+{
+ public static final String PATH_VALUE = " ? ";
+ public static final String QUERY_VALUE = "ora. es";
+
+ public String value;
+ public String queryValue;
+
+ public String redirect()
+ {
+ value = PATH_VALUE;
+ queryValue = QUERY_VALUE;
+ return "pretty:valued";
+ }
+
+ public String getValue()
+ {
+ return value;
+ }
+
+ public void setValue(final String value)
+ {
+ this.value = value;
+ }
+
+ public String getQueryValue()
+ {
+ return queryValue;
+ }
+
+ public void setQueryValue(final String queryValue)
+ {
+ this.queryValue = queryValue;
+ }
+}
=======================================
--- /dev/null
+++
/prettyfaces/trunk/tests-jsf2/src/test/java/com/ocpsoft/pretty/faces/test/redirect/URLRedirectTest.java
Sun Nov 7 15:01:05 2010
@@ -0,0 +1,104 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * 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 com.ocpsoft.pretty.faces.test.redirect;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URLEncoder;
+
+import javax.faces.context.FacesContext;
+
+import org.jboss.arquillian.MavenArtifactResolver;
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.jsfunit.jsfsession.JSFClientSession;
+import org.jboss.jsfunit.jsfsession.JSFServerSession;
+import org.jboss.jsfunit.jsfsession.JSFSession;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.ocpsoft.pretty.PrettyContext;
+
+@RunWith(Arquillian.class)
+public class URLRedirectTest
+{
+ @Deployment
+ public static Archive<?> createDeployment()
+ {
+ return ShrinkWrap.create(WebArchive.class, "test.war")
+ .addClass(RedirectBean.class)
+ .addResource("redirect/redirect.xhtml", "redirect.xhtml")
+ .addWebResource("redirect/redirect-pretty-config.xml", "pretty-config.xml")
+ .addWebResource("faces-config.xml")
+ .addLibrary(MavenArtifactResolver.resolve(
+ "com.ocpsoft:prettyfaces-jsf2:3.1.1-SNAPSHOT"
+ ))
+ .setWebXML("jsf-web.xml");
+ }
+
+ @Test
+ public void testRefreshEncodesValuesPropertly() throws Exception
+ {
+ String expected = "/1 1/2 2";
+
+ JSFSession jsfSession = new JSFSession(expected);
+ JSFServerSession server = jsfSession.getJSFServerSession();
+
+ JSFClientSession client = jsfSession.getJSFClientSession();
+
+ FacesContext context = server.getFacesContext();
+ PrettyContext prettyContext =
PrettyContext.getCurrentInstance(context);
+
+ client.click("refresh");
+
+ String actual = prettyContext.getRequestURL().toString();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testRedirectEncodesValuesPropertly() throws Exception
+ {
+ String requestURL = "/foo/" +
URLEncoder.encode(RedirectBean.PATH_VALUE, "UTF-8") + "?que="
+ + URLEncoder.encode(RedirectBean.QUERY_VALUE, "UTF-8");
+
+ JSFSession jsfSession = new JSFSession(requestURL);
+ JSFServerSession server = jsfSession.getJSFServerSession();
+
+ JSFClientSession client = jsfSession.getJSFClientSession();
+
+ FacesContext context = server.getFacesContext();
+ PrettyContext prettyContext =
PrettyContext.getCurrentInstance(context);
+
+ client.click("redirect");
+
+ String browserURL = client.getContentPage().getUrl().toString();
+ assertTrue(browserURL.contains(requestURL));
+
+ String expected = "/foo/" + RedirectBean.PATH_VALUE;
+ String actual = prettyContext.getRequestURL().toString();
+ assertEquals(expected, actual);
+
+ // TODO QueryString should probably separate encoding from default
behavior
+ // String expectedQuery = "?que=" + RedirectBean.QUERY_VALUE;
+ // String actualQuery =
prettyContext.getRequestQueryString().toString();
+ // assertEquals(expectedQuery, actualQuery);
+ }
+}
=======================================
--- /dev/null
+++
/prettyfaces/trunk/tests-jsf2/src/test/resources/redirect/redirect-pretty-config.xml
Sun Nov 7 15:01:05 2010
@@ -0,0 +1,16 @@
+<pretty-config xmlns="
http://ocpsoft.com/prettyfaces/3.1.1"
+ xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
http://ocpsoft.com/prettyfaces/3.1.1
+
http://ocpsoft.com/xml/ns/prettyfaces/ocpsoft-pretty-faces-3.1.1.xsd">
+
+ <url-mapping id="value">
+ <pattern value="/#{one}/#{two}"></pattern>
+ <view-id>/redirect.jsf</view-id>
+ </url-mapping>
+ <url-mapping id="valued">
+ <pattern value="/foo/#{redirectBean.value}"></pattern>
+ <query-param name="que">#{redirectBean.queryValue}</query-param>
+ <view-id>/redirect.jsf</view-id>
+ </url-mapping>
+
+</pretty-config>
=======================================
--- /dev/null
+++
/prettyfaces/trunk/tests-jsf2/src/test/resources/redirect/redirect.xhtml
Sun Nov 7 15:01:05 2010
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xml:lang="en" lang="en" xmlns="
http://www.w3.org/1999/xhtml"
+ xmlns:f="
http://java.sun.com/jsf/core"
+ xmlns:h="
http://java.sun.com/jsf/html"
+ xmlns:ui="
http://java.sun.com/jsf/facelets">
+
+<f:metadata>
+ <f:viewParam name="dis" value="#{p}" />
+</f:metadata>
+
+<head>
+<title>Encoding Test</title>
+</head>
+
+<body>
+<h1>Encoding Test</h1>
+ <h1><h:outputText value="Pretty Decode Page" /></h1>
+ <h:form id="form" prependId="false">
+ <h:commandButton id="refresh" action="pretty:" value="Submit" /><br />
+ <h:commandButton id="redirect" action="#{redirectBean.redirect}"
value="Submit" /><br />
+ </h:form>
+</body>
+</html>
+
=======================================
---
/prettyfaces/trunk/tests-jsf2/src/test/resources/encoding/encoding-pretty-config.xml
Tue Oct 19 09:11:21 2010
+++ /dev/null
@@ -1,31 +0,0 @@
-<pretty-config xmlns="
http://ocpsoft.com/prettyfaces/3.1.1"
- xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
http://ocpsoft.com/prettyfaces/3.1.1
-
http://ocpsoft.com/xml/ns/prettyfaces/ocpsoft-pretty-faces-3.1.1.xsd">
-
- <rewrite match="/URL ENCODED" substitute="/url decoded"
toCase="lowercase" />
-
- <url-mapping id="form">
- <pattern value="/custom/form"></pattern>
- <view-id>/encoding.jsf</view-id>
- </url-mapping>
- <url-mapping id="encoding">
- <pattern value="/encoding/#{encodingBean.pathText}" />
- <query-param name="dis">#{encodingBean.queryText}</query-param>
- <view-id> /encoding.jsf </view-id>
- </url-mapping>
- <url-mapping id="urldecoded">
- <pattern value="/url decoded" />
- <view-id> /encoding.jsf </view-id>
- </url-mapping>
- <url-mapping id="hardencoding">
- <pattern value="/hard encoding/Vračar" />
- <view-id> /encoding.jsf </view-id>
- </url-mapping>
-
- <url-mapping id="formencoding">
- <pattern value="/#{/.*/ encodingBean.pathText}/" />
- <view-id> /encoding.jsf </view-id>
- </url-mapping>
-
-</pretty-config>
=======================================
---
/prettyfaces/trunk/tests-jsf2/src/test/resources/encoding/encoding.xhtml
Mon Oct 18 10:53:27 2010
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xml:lang="en" lang="en" xmlns="
http://www.w3.org/1999/xhtml"
- xmlns:f="
http://java.sun.com/jsf/core"
- xmlns:h="
http://java.sun.com/jsf/html"
- xmlns:ui="
http://java.sun.com/jsf/facelets">
-
-<f:metadata>
- <f:viewParam name="dis" value="#{p}" />
-</f:metadata>
-
-<head>
-<title>Encoding Test</title>
-</head>
-
-<body>
-<h1>Encoding Test</h1>
- <h1><h:outputText value="Pretty Decode Page" /></h1>
- <h:form id="form" prependId="false">
- <h:outputText value="Enter a value: will be decoded" /><br />
- <h:inputText id="input0" value="#{exampleBean.param0}" /><br /><br />
-
- <h:outputText value="Enter a value: will not be decoded" /><br />
- <h:inputText id="input1" value="#{exampleBean.param1}" />
- <h:commandButton id="submit" action="#{exampleBean.handleDecode}"
value="Submit" /><br />
- </h:form>
-</body>
-</html>
-
=======================================
---
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/application/PrettyRedirector.java
Mon Oct 18 10:53:27 2010
+++
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/application/PrettyRedirector.java
Sun Nov 7 15:01:05 2010
@@ -51,13 +51,13 @@
PrettyContext prettyContext =
PrettyContext.getCurrentInstance(context);
PrettyConfig config = prettyContext.getConfig();
ExternalContext externalContext = context.getExternalContext();
+ String contextPath = prettyContext.getContextPath();
if (PrettyContext.PRETTY_PREFIX.equals(action) &&
prettyContext.isPrettyRequest())
{
URL url = prettyContext.getRequestURL();
QueryString query = prettyContext.getRequestQueryString();
- String contextPath = prettyContext.getContextPath();
-
- String target = contextPath + url.toURL() +
query.toQueryString();
+
+ String target = contextPath + url.encode() +
query.toQueryString();
log.trace("Refreshing requested page [" + url + "]");
String redirectUrl = externalContext.encodeActionURL(target);
externalContext.redirect(redirectUrl);
@@ -68,7 +68,8 @@
UrlMapping mapping = config.getMappingById(action);
if (mapping != null)
{
- String url = builder.build(mapping);
+ String url = contextPath +
builder.buildURL(mapping).encode()
+ + builder.buildQueryString(mapping);
log.trace("Redirecting to mappingId [" + mapping.getId()
+ "], [" + url + "]");
String redirectUrl = externalContext.encodeActionURL(url);
externalContext.redirect(redirectUrl);
=======================================
---
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/beans/ExtractedValuesURLBuilder.java
Tue Oct 19 09:11:21 2010
+++
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/beans/ExtractedValuesURLBuilder.java
Sun Nov 7 15:01:05 2010
@@ -25,12 +25,12 @@
import javax.el.ELException;
import javax.faces.context.FacesContext;
-import com.ocpsoft.pretty.PrettyContext;
import com.ocpsoft.pretty.PrettyException;
import com.ocpsoft.pretty.faces.config.mapping.PathParameter;
import com.ocpsoft.pretty.faces.config.mapping.QueryParameter;
import com.ocpsoft.pretty.faces.config.mapping.UrlMapping;
import com.ocpsoft.pretty.faces.url.QueryString;
+import com.ocpsoft.pretty.faces.url.URL;
import com.ocpsoft.pretty.faces.url.URLPatternParser;
import com.ocpsoft.pretty.faces.util.FacesElUtils;
@@ -42,25 +42,21 @@
private static final FacesElUtils elUtils = new FacesElUtils();
/**
- * For all required values of the given PrettyUrlMapping, extract
values from
- * their mapped backing beans and create a URL based on the url-pattern
and
- * any mapped query-parameters.
+ * For all required values of the given PrettyUrlMapping, extract
values from their mapped backing beans and create a
+ * URL based on the url-pattern.
*
* @param mapping Mapping for which to extract values and generate URL
* @return The fully constructed URL
*/
- // TODO Test ME!!!
- // TODO Divide into two methods, getURL and getQueryString
- public String build(final UrlMapping mapping)
- {
- String result = "";
+ public URL buildURL(final UrlMapping mapping)
+ {
+ URL result = null;
String expression = "";
Object value = null;
try
{
FacesContext context = FacesContext.getCurrentInstance();
- PrettyContext prettyContext = PrettyContext.getCurrentInstance();
URLPatternParser parser = new
URLPatternParser(mapping.getPattern());
List<PathParameter> parameters = parser.getPathParameters();
@@ -71,10 +67,33 @@
value = elUtils.getValue(context, expression);
if (value == null)
{
- throw new PrettyException("PrettyFaces: Exception occurred
while building URL for MappingId < " + mapping.getId() + " >, Required
value " + " < " + expression + " > was null");
+ throw new PrettyException("PrettyFaces: Exception occurred
while building URL for MappingId < "
+ + mapping.getId() + " >, Required value " + " < "
+ expression + " > was null");
}
parameterValues.add(value.toString());
}
+
+ result = parser.getMappedURL(parameterValues);
+ }
+ catch (ELException e)
+ {
+ throw new PrettyException("PrettyFaces: Exception occurred while
building URL for MappingId < "
+ + mapping.getId() + " >, Error occurred while extracting
values from backing bean" + " < "
+ + expression + ":" + value + " >", e);
+ }
+
+ return result;
+ }
+
+ public QueryString buildQueryString(final UrlMapping mapping)
+ {
+ QueryString result = new QueryString();
+
+ String expression = "";
+ Object value = null;
+ try
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
List<QueryParameter> queryParams = mapping.getQueryParams();
List<QueryParameter> queryParameterValues = new
ArrayList<QueryParameter>();
@@ -103,11 +122,13 @@
}
}
- result = prettyContext.getContextPath() +
parser.getMappedURL(parameterValues).toURL() +
QueryString.build(queryParameterValues);
+ result = QueryString.build(queryParameterValues);
}
catch (ELException e)
{
- throw new PrettyException("PrettyFaces: Exception occurred while
building URL for MappingId < " + mapping.getId() + " >, Error occurred
while extracting values from backing bean" + " < " + expression + ":" +
value + " >", e);
+ throw new PrettyException("PrettyFaces: Exception occurred while
building QueryString for MappingId < "
+ + mapping.getId() + " >, Error occurred while extracting
values from backing bean" + " < "
+ + expression + ":" + value + " >", e);
}
return result;
=======================================
---
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/event/PrettyPhaseListener.java
Tue Oct 19 09:11:21 2010
+++
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/event/PrettyPhaseListener.java
Sun Nov 7 15:01:05 2010
@@ -86,8 +86,8 @@
{
// TODO Test that validation occurs before injection
/*
- * Parameter validation and injection must occur after
RESTORE_VIEW in
- * order to participate in faces-navigation.
+ * Parameter validation and injection must occur after
RESTORE_VIEW in order to participate in
+ * faces-navigation.
*/
validator.validateParameters(event.getFacesContext());
injector.injectParameters(event.getFacesContext());
@@ -135,15 +135,12 @@
}
/**
- * Calculate the Faces ViewId to which this request URI resolves. This
method
- * will recursively call any dynamic mapping viewId functions as needed
until
- * a String viewId is returned, or supplied by a static mapping.
+ * Calculate the Faces ViewId to which this request URI resolves. This
method will recursively call any dynamic
+ * mapping viewId functions as needed until a String viewId is
returned, or supplied by a static mapping.
* <p>
- * This phase does not support FacesNavigation or PrettyRedirecting.
Its SOLE
- * purpose is to resolve a viewId.
+ * This phase does not support FacesNavigation or PrettyRedirecting.
Its SOLE purpose is to resolve a viewId.
* <p>
- * <i><b>Note:</b> Precondition - parameter injection must take place
before
- * this</i>
+ * <i><b>Note:</b> Precondition - parameter injection must take place
before this</i>
* <p>
* <i>Postcondition - currentViewId is set to computed View Id</i>
*
@@ -181,7 +178,9 @@
{
urlMapping = context.getConfig().getMappingById(viewId);
viewId = urlMapping.getViewId();
- result = new ExtractedValuesURLBuilder().build(urlMapping);
+ ExtractedValuesURLBuilder builder = new
ExtractedValuesURLBuilder();
+ result = context.getContextPath() +
builder.buildURL(urlMapping).encode()
+ + builder.buildQueryString(urlMapping);
}
else
{
=======================================
---
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/url/QueryString.java
Thu May 13 09:52:33 2010
+++
/prettyfaces/trunk/core/src/main/java/com/ocpsoft/pretty/faces/url/QueryString.java
Sun Nov 7 15:01:05 2010
@@ -25,8 +25,8 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import java.util.Map.Entry;
+import java.util.TreeMap;
import com.ocpsoft.pretty.PrettyException;
import com.ocpsoft.pretty.faces.config.mapping.RequestParameter;
@@ -39,9 +39,8 @@
private final Map<String, List<String>> parameters = new
HashMap<String, List<String>>();
/**
- * Build a query string from the given map of name=value pairs. For
- * parameters with more than one value, each value will be appended
using the
- * same name.
+ * Build a query string from the given map of name=value pairs. For
parameters with more than one value, each value
+ * will be appended using the same name.
*/
public static QueryString build(final Map<String, String[]> params)
{
@@ -51,8 +50,7 @@
}
/**
- * Build a query string from the given list of {@link RequestParameter}
- * objects.
+ * Build a query string from the given list of {@link RequestParameter}
objects.
*/
public static <T extends RequestParameter> QueryString build(final
List<T> params)
{
@@ -62,9 +60,8 @@
}
/**
- * Build a query string from the given URL. If a '?' character is
encountered
- * in the URL, the any characters up to and including the first '?'
will be
- * ignored.
+ * Build a query string from the given URL. If a '?' character is
encountered in the URL, the any characters up to
+ * and including the first '?' will be ignored.
*/
public static QueryString build(final String url)
{
@@ -90,8 +87,8 @@
/**
* Get the first value of given parameter name.
*
- * @return The value of the parameter, null if the parameter does not
exist,
- * or "" if the parameter exists but has no values.
+ * @return The value of the parameter, null if the parameter does not
exist, or "" if the parameter exists but has no
+ * values.
*/
public String getParameter(final String name)
{
@@ -161,9 +158,8 @@
*/
/**
- * Add query parameters from the given list of {@link RequestParameter}
- * objects. If a parameter already exists, append new values to the
existing
- * list of values for that parameter.
+ * Add query parameters from the given list of {@link RequestParameter}
objects. If a parameter already exists,
+ * append new values to the existing list of values for that parameter.
*/
public <T extends RequestParameter> void addParameters(final List<T>
params)
{
@@ -189,10 +185,9 @@
}
/**
- * Add parameters from the given map of name=value pairs. For
parameters with
- * more than one value, each value will be appended using the same
name. If a
- * parameter already exists, append new values to the existing list of
values
- * for that parameter.
+ * Add parameters from the given map of name=value pairs. For
parameters with more than one value, each value will be
+ * appended using the same name. If a parameter already exists, append
new values to the existing list of values for
+ * that parameter.
*/
public void addParameters(final Map<String, String[]> params)
{
@@ -211,10 +206,9 @@
}
/**
- * Add parameters from the given URL. If a '?' character is encountered
in
- * the URL, the any characters up to and including the first '?' will be
- * ignored. If a parameter already exists, append new values to the
existing
- * list of values for that parameter.
+ * Add parameters from the given URL. If a '?' character is encountered
in the URL, the any characters up to and
+ * including the first '?' will be ignored. If a parameter already
exists, append new values to the existing list of
+ * values for that parameter.
*/
public void addParameters(String url)
{
@@ -250,7 +244,8 @@
}
catch (UnsupportedEncodingException e)
{
- throw new PrettyException("UTF-8 encoding not
supported. Something is seriously wrong with your environment.");
+ throw new PrettyException(
+ "UTF-8 encoding not supported. Something is
seriously wrong with your environment.");
}
}
List<String> list = parameters.get(name);
@@ -267,20 +262,19 @@
}
/**
- * Convert the current parameters to a valid query string, including the
- * leading '?' character.
+ * Convert the current parameters to a valid query string, including
the leading '?' character. This method
+ * automatically URLEncodes query-parameter values
* <p>
*
- * For example, a {@link QueryString} with the values [key=>value,
- * name=>value1,value2,value3] will become:
+ * For example, a {@link QueryString} with the values [key=>value,
name=>value1,value2,value3] will become:
*
* <pre>
*
* ?key=value&name=value1&name=value2&name=value3
* </pre>
*
- * @return If parameters exist, return a valid query string with
leading '?'
- * character. If no parameters exist, return an empty string.
+ * @return If parameters exist, return a valid query string with
leading '?' character. If no parameters exist,
+ * return an empty string.
*/
public String toQueryString()
{
=======================================
---
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/application/PrettyRedirector.java
Mon Oct 18 10:53:27 2010
+++
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/application/PrettyRedirector.java
Sun Nov 7 15:01:05 2010
@@ -51,13 +51,14 @@
PrettyContext prettyContext = PrettyContext.getCurrentInstance();
PrettyConfig config = prettyContext.getConfig();
ExternalContext externalContext = context.getExternalContext();
+
+ String contextPath = prettyContext.getContextPath();
if (PrettyContext.PRETTY_PREFIX.equals(action) &&
prettyContext.isPrettyRequest())
{
URL url = prettyContext.getRequestURL();
QueryString query = prettyContext.getRequestQueryString();
- String contextPath = prettyContext.getContextPath();
-
- String target = contextPath + url.toURL() +
query.toQueryString();
+
+ String target = contextPath + url.encode().toURL() +
query.toQueryString();
log.trace("Refreshing requested page [" + url + "]");
String redirectUrl = externalContext.encodeRedirectURL(target,
null);
externalContext.redirect(redirectUrl);
@@ -68,7 +69,8 @@
UrlMapping mapping = config.getMappingById(action);
if (mapping != null)
{
- String url = builder.build(mapping);
+ String url = contextPath +
builder.buildURL(mapping).encode()
+ + builder.buildQueryString(mapping).toString();
log.trace("Redirecting to mappingId [" + mapping.getId()
+ "], [" + url + "]");
String redirectUrl = externalContext.encodeRedirectURL(url,
null);
externalContext.redirect(redirectUrl);
=======================================
---
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/application/PrettyViewHandler.java
Fri Oct 15 08:43:10 2010
+++
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/application/PrettyViewHandler.java
Sun Nov 7 15:01:05 2010
@@ -38,6 +38,7 @@
import com.ocpsoft.pretty.faces.beans.ExtractedValuesURLBuilder;
import com.ocpsoft.pretty.faces.config.mapping.PathParameter;
import com.ocpsoft.pretty.faces.config.mapping.QueryParameter;
+import com.ocpsoft.pretty.faces.config.mapping.UrlMapping;
import com.ocpsoft.pretty.faces.util.FacesElUtils;
import com.ocpsoft.pretty.faces.util.URLDuplicatePathCanonicalizer;
@@ -51,9 +52,8 @@
private final ThreadLocal<Boolean> bookmarkable = new
ThreadLocal<Boolean>();
/**
- * <b>NOTE:</b> This method should only be used by the
getBookmarkableURL and
- * getActionURL methods, for the purposes of rewriting form URLs (which
do
- * not include viewParameters.)
+ * <b>NOTE:</b> This method should only be used by the
getBookmarkableURL and getActionURL methods, for the purposes
+ * of rewriting form URLs (which do not include viewParameters.)
*
* @return Bookmarkable state - defaults to false if not previously set;
*/
@@ -113,25 +113,27 @@
public String getActionURL(final FacesContext context, final String
viewId)
{
/*
- * When this method is called for forms, getBookmarkableURL is NOT
called;
- * therefore, we have a way to distinguish the two.
+ * When this method is called for forms, getBookmarkableURL is NOT
called; therefore, we have a way to distinguish
+ * the two.
*/
String result = parent.getActionURL(context, viewId);
PrettyContext prettyContext = PrettyContext.getCurrentInstance();
- if (!isBookmarkable() && prettyContext.isPrettyRequest()
&& !prettyContext.isInNavigation() && (viewId != null) &&
viewId.equals(context.getViewRoot().getViewId()))
+ if (!isBookmarkable() && prettyContext.isPrettyRequest()
&& !prettyContext.isInNavigation() && (viewId != null)
+ && viewId.equals(context.getViewRoot().getViewId()))
{
ExtractedValuesURLBuilder builder = new
ExtractedValuesURLBuilder();
- result = builder.build(prettyContext.getCurrentMapping());
+ UrlMapping mapping = prettyContext.getCurrentMapping();
+ result = prettyContext.getContextPath() +
builder.buildURL(mapping) + builder.buildQueryString(mapping);
}
return result;
}
@Override
- public String getBookmarkableURL(final FacesContext context, final
String viewId, final Map<String, List<String>> parameters, final boolean
includeViewParams)
+ public String getBookmarkableURL(final FacesContext context, final
String viewId,
+ final Map<String, List<String>> parameters, final boolean
includeViewParams)
{
/*
- * When this method is called for <h:link> tags, getActionURL is
called as
- * part of the parent call
+ * When this method is called for <h:link> tags, getActionURL is
called as part of the parent call
*/
setBookmarkable(true);
String result = parent.getBookmarkableURL(context, viewId,
parameters, includeViewParams);
@@ -140,7 +142,8 @@
}
@Override
- public String getRedirectURL(final FacesContext context, final String
viewId, final Map<String, List<String>> parameters, final boolean
includeViewParams)
+ public String getRedirectURL(final FacesContext context, final String
viewId,
+ final Map<String, List<String>> parameters, final boolean
includeViewParams)
{
return parent.getRedirectURL(context, viewId, parameters,
includeViewParams);
}
@@ -152,7 +155,8 @@
}
@Override
- public void renderView(final FacesContext facesContext, final
UIViewRoot viewRoot) throws IOException, FacesException
+ public void renderView(final FacesContext facesContext, final
UIViewRoot viewRoot) throws IOException,
+ FacesException
{
parent.renderView(facesContext, viewRoot);
}
@@ -164,8 +168,7 @@
}
/**
- * Canonicalize the given viewId, then pass that viewId to the next
- * ViewHandler in the chain.
+ * Canonicalize the given viewId, then pass that viewId to the next
ViewHandler in the chain.
*/
@Override
public String deriveViewId(final FacesContext context, final String
rawViewId)
@@ -197,8 +200,8 @@
*/
/**
- * Add PrettyFaces UIViewParameters to the component tree. This is how
we do
- * value injection, conversion, and validation.
+ * Add PrettyFaces UIViewParameters to the component tree. This is how
we do value injection, conversion, and
+ * validation.
*/
private void addPrettyViewParameters(final FacesContext context, final
UIViewRoot view)
{
@@ -217,7 +220,8 @@
List<PathParameter> pathParameters =
prettyContext.getCurrentMapping().getPatternParser().getPathParameters();
for (PathParameter p : pathParameters)
{
- UIViewParameter param = (UIViewParameter)
context.getApplication().createComponent(UIViewParameter.COMPONENT_TYPE);
+ UIViewParameter param = (UIViewParameter)
context.getApplication().createComponent(
+ UIViewParameter.COMPONENT_TYPE);
Map<String, Object> requestMap =
context.getExternalContext().getRequestMap();
requestMap.put(p.getName(), p.getValue());
=======================================
---
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/component/LocationBehavior.java
Thu Sep 30 22:56:28 2010
+++
/prettyfaces/trunk/impl-jsf2/src/main/java/com/ocpsoft/pretty/faces/component/LocationBehavior.java
Sun Nov 7 15:01:05 2010
@@ -12,8 +12,7 @@
import com.ocpsoft.pretty.faces.config.mapping.UrlMapping;
/**
- * Simple JSF2 client behavior that changes the current URL by setting
- * <code>window.location.href</code>.
+ * Simple JSF2 client behavior that changes the current URL by setting
<code>window.location.href</code>.
*
* @author Christian Kaltepoth
*/
@@ -27,17 +26,17 @@
private String url;
@Override
- public String getScript(ClientBehaviorContext behaviorContext)
+ public String getScript(final ClientBehaviorContext behaviorContext)
{
// use URL from url attribute if available
- if (url != null && url.trim().length() > 0)
+ if ((url != null) && (url.trim().length() > 0))
{
return buildScriptInternal(url.trim());
}
// Is there a mapping id?
- if (mappingId == null || mappingId.trim().length() == 0)
+ if ((mappingId == null) || (mappingId.trim().length() == 0))
{
log.error("Please set either 'mappingId' or 'url' attribute!");
return null;
@@ -63,7 +62,9 @@
{
// build path to redirect to
- String path = new ExtractedValuesURLBuilder().build(mapping);
+ ExtractedValuesURLBuilder builder = new
ExtractedValuesURLBuilder();
+ String contextPath = prettyContext.getContextPath();
+ String path = contextPath + builder.buildURL(mapping) +
builder.buildQueryString(mapping);
// return the script
return buildScriptInternal(path);
@@ -79,11 +80,10 @@
/**
* Creates the required script for the supplied URL
*
- * @param url
- * The URL
+ * @param url The URL
* @return The script
*/
- private String buildScriptInternal(String url)
+ private String buildScriptInternal(final String url)
{
StringBuilder builder = new StringBuilder();
builder.append("window.location.href = '");
@@ -97,7 +97,7 @@
return mappingId;
}
- public void setMappingId(String mappingId)
+ public void setMappingId(final String mappingId)
{
this.mappingId = mappingId;
}
@@ -107,7 +107,7 @@
return url;
}
- public void setUrl(String url)
+ public void setUrl(final String url)
{
this.url = url;
}
=======================================
---
/prettyfaces/trunk/tests-jsf2/src/test/java/com/ocpsoft/pretty/faces/test/encoding/URLEncodingTest.java
Tue Oct 19 09:11:21 2010
+++
/prettyfaces/trunk/tests-jsf2/src/test/java/com/ocpsoft/pretty/faces/test/encoding/URLEncodingTest.java
Sun Nov 7 15:01:05 2010
@@ -142,7 +142,8 @@
JSFSession jsfSession = new JSFSession("/hard encoding/Vračar");
JSFServerSession server = jsfSession.getJSFServerSession();
- assertEquals("/encoding.xhtml", server.getCurrentViewID());
+ String currentViewID = server.getCurrentViewID();
+ assertEquals("/encoding.xhtml", currentViewID);
}
@Test