You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by so...@apache.org on 2013/05/22 05:29:03 UTC
svn commit: r1485037 - in /myfaces/trinidad/trunk:
trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/
Author: sobryan
Date: Wed May 22 03:29:03 2013
New Revision: 1485037
URL: http://svn.apache.org/r1485037
Log:
TRINIDAD-2390: More specific URL encoding
Added:
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextURLEncoder.java
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/PortletURLEncoder.java (with props)
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoder.java
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderFactory.java
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderWrapper.java
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/URLEncoderExternalContext.java
Modified:
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLUtils.java
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java
Added: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextURLEncoder.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextURLEncoder.java?rev=1485037&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextURLEncoder.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextURLEncoder.java Wed May 22 03:29:03 2013
@@ -0,0 +1,94 @@
+/*
+ * 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.myfaces.trinidad.util;
+
+import java.util.Collections;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ * This class contains a URL encoder which delegates to an ExternalContext
+ */
+class ExternalContextURLEncoder extends URLEncoder
+{
+ public ExternalContextURLEncoder(ExternalContext ec)
+ {
+ assert(ec != null);
+ _context = ec;
+ }
+
+ @Override
+ public String encodePartialActionURL(String url)
+ {
+ return getExternalContext().encodePartialActionURL(url);
+ }
+
+ @Override
+ public String encodeRedirectURL(String url)
+ {
+ return (encodeRedirectURL(url, null));
+ }
+
+ @Override
+ public String encodeRedirectURL(String url, Map<String, List<String>> params)
+ {
+ return getExternalContext().encodeRedirectURL(url, params);
+ }
+
+ @Override
+ public String encodeInProtocolResourceURL(String url)
+ {
+ return getExternalContext().encodeResourceURL(url);
+ }
+
+ @Override
+ public String encodeSkinResourceURL(String url)
+ {
+ return url;
+ }
+
+ @Override
+ public String encodeActionURL(String url)
+ {
+ return getExternalContext().encodeActionURL(url);
+ }
+
+ @Override
+ public String encodeResourceURL(String url)
+ {
+ return getExternalContext().encodeResourceURL(url);
+ }
+
+ @Override
+ public String encodeBookmarkableURL(String url, Map<String, List<String>> params)
+ {
+ return getExternalContext().encodeBookmarkableURL(url, params);
+ }
+
+ protected ExternalContext getExternalContext()
+ {
+ return _context;
+ }
+
+ private ExternalContext _context;
+}
Added: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/PortletURLEncoder.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/PortletURLEncoder.java?rev=1485037&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/PortletURLEncoder.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/PortletURLEncoder.java Wed May 22 03:29:03 2013
@@ -0,0 +1,46 @@
+/*
+ * 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.myfaces.trinidad.util;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+
+/**
+ *
+ */
+class PortletURLEncoder extends ExternalContextURLEncoder
+{
+ public PortletURLEncoder(ExternalContext ec)
+ {
+ super(ec);
+ }
+
+ @Override
+ public String encodeInProtocolResourceURL(String url)
+ {
+ String enc = getExternalContext().getResponseCharacterEncoding();
+ return super.encodeInProtocolResourceURL(URLUtils.encodeURL(url, _IN_PROTOCOL_MAP, enc));
+ }
+
+ private static final Map <String, List<String>> _IN_PROTOCOL_MAP = Collections.singletonMap("javax.portlet.faces.InProtocolResourceLink", Collections.singletonList("true"));
+}
+
Propchange: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/PortletURLEncoder.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoder.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoder.java?rev=1485037&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoder.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoder.java Wed May 22 03:29:03 2013
@@ -0,0 +1,173 @@
+/*
+ * 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.myfaces.trinidad.util;
+
+import java.io.Serializable;
+
+import java.io.UnsupportedEncodingException;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ * Encodes URL's based on thier type. While the ExternalContext does this to
+ * some extent, the types of URL's it encodes are often ill-defined. This utility
+ * method allows the caller to ensure that URL's are encoded in the proper fashion
+ * depending on which container is active at the time.
+ * <p/>
+ * Out of the box, this class supports Servlet and Portlet encoding, but it may
+ * be extended on a per-request basis to support other types of URL encoding with
+ * the use of the "registerURLEncoder" method.
+ * <p/>
+ * It is also important to note that this does not impact the encoding done by the
+ * ExternalContext. As such, all current applications should work without
+ * modification if they do not choose to use this API for encoding.
+ */
+public abstract class URLEncoder
+{
+ /**
+ * This function should be the same as the {@link ExternalContext#encodeActionURL(String)}
+ * method. By default it call the code in the ExternalContext. The reason its
+ * provided here is that certain URLEncoderUtility instances may wish to override
+ * the default functionality and have the ExternalContext pull its default encoding
+ * from here.
+ */
+ public abstract String encodeActionURL(String url);
+
+ /**
+ * This encodes a URL so that it can be used to make a PPR request in all containers.
+ * JSF 2.0 has the ability to encode URL's in such a fashion, but this is missing
+ * from JSF 1.2 containers. This method provides the same functionality for JSF 1.2.
+ *
+ * @param url the unencoded url
+ * @return the encoded url
+ *
+ * @throws IllegalArgumentException if the URL cannot be encoded
+ */
+ public abstract String encodePartialActionURL(String url);
+
+ /**
+ * Encodes a url to be explicitly used for a redirect. In some containers, this is
+ * encoded as-is. In other containers this may not be encoded or must contain a
+ * fully qualified url. By default this method calls {@link #encodeRedirectURL(String,Map<String,List<String>>)}
+ * with an empty parameter map.
+ *
+ * @param url the unencoded url
+ * @return the encoded url
+ *
+ * @throws IllegalArgumentException if the URL cannot be encoded
+ */
+ public abstract String encodeRedirectURL(String url);
+
+ /**
+ * Encodes a url to be explicitly used for a redirect. In some containers, this is
+ * encoded as-is. In other containers this may not be encoded or must contain a
+ * fully qualified url. This version of the method allows for a map of parameters
+ * to be included in the URL. These parameters will generate a query string and add
+ * it to a URL that may or may-not already have its own existing query parameters.
+ * The parameter values should be encoded appropriately for the environment so that
+ * the resulting URL can be used at the target of the redirect.
+ *
+ * The default implementation throws and UnsupportedOperationException and is procided
+ * for the sole purpose of maintaining binary compatibility.
+ *
+ * @param url the unencoded url
+ * @return the encoded url
+ * @throws IllegalArgumentException if the URL cannot be encoded
+ * @throws UnsupportedOperationException if the implementation of the URLEncoder is not implemented.
+ *
+ * @since 2.1
+ * @see ExternalContext#encodeRedirectURL
+ */
+ public String encodeRedirectURL(String url, Map<String, List<String>> parameters)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Encodes a url as a resource. Generally speaking this will be equivalent to
+ * {@link ExternalContext#encodeResourceURL(String)}. The url returned from this
+ * method is NOT guarenteed to be in-protocol (meaning that it MAY not have access
+ * to session information). The advantage of encoding something in this fashion
+ * is that in certain types of containers, like portals, the URL generated may
+ * have faster access and will generally work better for the purposes of caching
+ * do to its RESTful state.
+ *
+ * @param url the unencoded url
+ * @return the encoded url
+ *
+ * @throws IllegalArgumentException if the URL cannot be encoded
+ */
+ public abstract String encodeResourceURL(String url);
+
+ /**
+ * Encodes a url to a resource such that it is inProtocol. This means that the
+ * URL returned will be encoded in such a way that the resource will have access
+ * to the parent application's session. While these URL's do have access to the
+ * session information, they may not be written in a format that is easily cachable.
+ *
+ * @param url the unencoded url
+ * @return the encoded url
+ *
+ * @throws IllegalArgumentException if the URL cannot be encoded
+ */
+ public abstract String encodeInProtocolResourceURL(String url);
+
+ /**
+ * Encodes a resource URL that is mapped to a skinning resources. Trinidad has
+ * an extensive skinning system that allows for extraction of certain properties
+ * like images so that they can be used with the componentry. Generally these
+ * image resources are on the same server and whatnot as the actual skin. In
+ * a servlet environment, this is always the same server, but in portal-like
+ * environments these resources may be on different servers. This encodes a
+ * URL that comes from a skin and sends it to the right location.
+ *
+ * @param url
+ * @return
+ */
+ public abstract String encodeSkinResourceURL(String url);
+
+ /**
+ * The purpose of this method is to generate a query string from the collection of Parameter
+ * objects provided by the parameters argument and append that query string to the baseUrl. This
+ * method must be able to encode the parameters to a baseUrl that may or may not have existing
+ * query parameters. The parameter values should be encoded appropriately for the environment
+ * so that the resulting URL can be used as the target of a link (e.g., in an href attribute) in
+ * a JSF response. It's possible for an ExternalContext implementation to override this method in
+ * any way that would make the URL bookmarkable in that environment.
+ * <p/>
+ * The default implementation simply throws an UnsupportedOperationException and is provided only
+ * for the purposes of ensuring binary compatibility.
+ *
+ * @param url the base url
+ * @param params a map of parameters
+ * @return
+ *
+ * @throws UnsupportedOperationException if the default implementation does not support encoding
+ * of bookmarkable urls.
+ */
+ public String encodeBookmarkableURL(String url, Map<String, List<String>> params)
+ {
+ throw new UnsupportedOperationException();
+ }
+}
Added: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderFactory.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderFactory.java?rev=1485037&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderFactory.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderFactory.java Wed May 22 03:29:03 2013
@@ -0,0 +1,114 @@
+/*
+ * 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.myfaces.trinidad.util;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ * This is a factory for the URLEncoder. The URL encoder is a convenience class that
+ * handles URL encoding in a container independant fashion. The Portlet bridge spec
+ * and later JSF specifications have tried to make URL encoding more specific, but
+ * these technologies do not always address the needs of Trinidad URL encoding in
+ * all circumstances. This method aims to do just that.
+ * <p>
+ * This factory can both create URLEncoders as well as keep track of an encoder on
+ * a per-request basis. Additionally, custom URLEncoders can be added manually via
+ * the {@link #setURLEncoder} method.
+ */
+public class URLEncoderFactory
+{
+ /**
+ * Returns the current URLEncoderFactory.
+ *
+ * @return a URLEncoder factory
+ */
+ public static URLEncoderFactory getFactory()
+ {
+ return _ENCODER;
+ }
+
+ /**
+ * Returns the current URLEncoder if it has been set. If it has not been set it
+ * creates a new URLEncoder, sets it to the current thread, and returns its value.
+ *
+ * @return the currently set URL encoder.
+ * @throws IllegalStateException if no controller has been set and FacesContext is
+ * currently unavailble.
+ */
+ public URLEncoder getURLEncoder()
+ {
+ FacesContext fc = FacesContext.getCurrentInstance();
+ if(null == fc)
+ {
+ return getURLEncoder(null);
+ }
+
+ return getURLEncoder(fc.getExternalContext());
+ }
+
+ /**
+ * Returns a URLEncoder if one has been set. If it has not been set, it
+ * creates a new URLEncoder using the provided ExternalContext.
+ *
+ * @return a URLEncoder for the given request
+ * @throws IllegalStateException if no controller has been set and the ExternalContext object
+ * is null
+ */
+ public URLEncoder getURLEncoder(ExternalContext ec)
+ {
+ //even though we should wait until we have a faces context and throw an error
+ //if we don't, go ahead and fudge it if the threadlocal is not null. This just
+ //means that a URLEncoder has already been set for this thread.
+ URLEncoder enc = _local.get();
+
+ if(null != enc)
+ {
+ return enc;
+ }
+
+ if(null == ec)
+ {
+ throw new IllegalStateException("An ExternalContext must be a available");
+ }
+
+ if(ExternalContextUtils.isPortlet(ec))
+ {
+ setURLEncoder(new PortletURLEncoder(ec));
+ }
+ else
+ {
+ setURLEncoder(new ExternalContextURLEncoder(ec));
+ }
+
+ return _local.get();
+ }
+
+ public void setURLEncoder(URLEncoder encoder)
+ {
+ _local.set(encoder);
+ }
+
+ private static final URLEncoderFactory _ENCODER = new URLEncoderFactory();
+
+ //This threadlocal should get cleaned up when the request is done. It's handled
+ //by the configurators.
+ private static final ThreadLocal<URLEncoder> _local = ThreadLocalUtils.newRequestThreadLocal();
+
+}
Added: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderWrapper.java?rev=1485037&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderWrapper.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLEncoderWrapper.java Wed May 22 03:29:03 2013
@@ -0,0 +1,145 @@
+/*
+ * 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.myfaces.trinidad.util;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Wrapper class for the URLEncoder that can be used to wrap and existing encoder and
+ * set it on the factory.
+ */
+public abstract class URLEncoderWrapper
+ extends URLEncoder
+{
+ public abstract URLEncoder getWrapped();
+
+ /**
+ * Encodes an action url. By default this method calls into the wrapped encoder and
+ * executes the {@link URLEncoder#encodeActionURL(String)} method.
+ *
+ * @param url a string containing the url to encode
+ * @return the encoded url
+ */
+ @Override
+ public String encodeActionURL(String url)
+ {
+ return getWrapped().encodeActionURL(url);
+ }
+
+ /**
+ * Encodes a resource url. By default this method calls into the wrapped encoder and
+ * executes the {@link URLEncoder#encodeResourceURL(String)} method.
+ *
+ * @param url a string containing the url to encode
+ * @return the encoded url
+ */
+ @Override
+ public String encodeResourceURL(String url)
+ {
+ return getWrapped().encodeResourceURL(url);
+ }
+
+ /**
+ * Encodes a resource url that is meant to be in-protocol. By default this method calls into the wrapped encoder and
+ * executes the {@link URLEncoder#encodeInProtocolResourceURL(String)} method.
+ *
+ * @param url a string containing the url to encode
+ * @return the encoded url
+ */
+ @Override
+ public String encodeInProtocolResourceURL(String url)
+ {
+ return getWrapped().encodeInProtocolResourceURL(url);
+ }
+
+ /**
+ * Encodes an action URL that is intended to represent a partial page submit. By default, this method calls into the wrapped
+ * encoder and executes the {@link URLEncoder#encodePartialActionURL(String)} method.
+ *
+ * @param url a string containing the url to encode
+ * @return the encoded url
+ */
+ @Override
+ public String encodePartialActionURL(String url)
+ {
+ return getWrapped().encodePartialActionURL(url);
+ }
+
+ /**
+ * Encodes a redirect url. By default this method calls into the wrapped encoder and
+ * executes the {@link URLEncoder#encodeRedirectURL(String)} method.
+ *
+ * @param url a string containing the url to encode
+ * @return the encoded url
+ */
+ @Override
+ public String encodeRedirectURL(String url)
+ {
+ return getWrapped().encodeRedirectURL(url);
+ }
+
+ /**
+ * Encodes a redirect url. By default this method calls into the wrapped encoder and
+ * executes the {@link URLEncoder#encodeRedirectURL(String, Map<String, List<String>>)} method.
+ *
+ * @param url a string containing the url to encode
+ * @param params a map containing additional params to add to the querystring
+ * @return the encoded url
+ * @throws UnsupportedOperationException if this method is not implemented or if this type of
+ * url cannot be encoded.
+ *
+ * @since 2.1
+ */
+ @Override
+ public String encodeRedirectURL(String url, Map<String, List<String>> params)
+ {
+ return getWrapped().encodeRedirectURL(url, params);
+ }
+
+ /**
+ * Encodes the URL of a Skin Resource. By default this method calls into the wrapped encoder and
+ * executes the {@link URLEncoder#encodeSkinResourceURL(String)} method.
+ *
+ * @param url a string containing additional params to add to the querystring.
+ * @return the encoded url
+ */
+ @Override
+ public String encodeSkinResourceURL(String url)
+ {
+ return getWrapped().encodeSkinResourceURL(url);
+ }
+
+ /**
+ * Encodes a bookmarkable url. By default this method calls into the wrapped encoder and
+ * executes the {@link URLEncoder#encodeBookmarkableURL(String,Map<String,List<String>>)} method.
+ *
+ * @param url a string containing additional params to add to the querystring.
+ * @return the encoded url
+ * @throws UnsupportedOperationException if this method is not implemented or if this type of
+ * url cannot be encoded.
+ *
+ * @since 2.1
+ */
+ @Override
+ public String encodeBookmarkableURL(String url, Map<String, List<String>> params)
+ {
+ return getWrapped().encodeBookmarkableURL(url, params);
+ }
+}
Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLUtils.java?rev=1485037&r1=1485036&r2=1485037&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLUtils.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/URLUtils.java Wed May 22 03:29:03 2013
@@ -21,10 +21,23 @@ package org.apache.myfaces.trinidad.util
import java.io.File;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
+import java.net.URLDecoder;
+
+import java.net.URLEncoder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
public final class URLUtils
{
private URLUtils()
@@ -88,4 +101,128 @@ public final class URLUtils
return modified;
}
+
+ /**
+ * Encodes a URL (with or without an existing query string) such that the value in the params map are added to them.
+ * A valid character encoding must be provided to ensure the parameters are encoded properly.
+ *
+ * @param url the base URL
+ * @param params the map of parameters to add, or <code>null</code>
+ * @param characterResponseEncoding the character response encoding
+ * @return the properly encoded url
+ *
+ * @throws UnsupportedOperationException if the encoding is not supported.
+ */
+ public static String encodeURL(String url, Map<String, List<String>> params, String characterResponseEncoding)
+ {
+ String fragment = null;
+ String queryString = null;
+ Map<String, List<String>> paramMap = null;
+
+ //extract any URL fragment
+ int index = url.indexOf(_URL_FRAGMENT_SEPERATOR);
+ if (index != -1)
+ {
+ fragment = url.substring(index+1);
+ url = url.substring(0,index);
+ }
+
+ //extract the current query string and add the params to the paramMap
+ index = url.indexOf(_URL_QUERY_SEPERATOR);
+ if (index != -1)
+ {
+ queryString = url.substring(index + 1);
+ url = url.substring(0, index);
+ String[] nameValuePairs = queryString.split(_URL_PARAM_SEPERATOR);
+ for (int i = 0; i < nameValuePairs.length; i++)
+ {
+ String[] currentPair = nameValuePairs[i].split(_URL_NAME_VALUE_PAIR_SEPERATOR);
+
+ ArrayList<String> value = new ArrayList<String>(1);
+ try
+ {
+ value.add(currentPair.length > 1
+ ? URLDecoder.decode(currentPair[1], characterResponseEncoding)
+ : "");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ //shouldn't ever get here
+ throw new UnsupportedOperationException("Encoding type=" + characterResponseEncoding
+ + " not supported", e);
+ }
+ if (paramMap == null)
+ {
+ paramMap = new HashMap<String, List<String>>();
+ }
+ paramMap.put(currentPair[0], value);
+ }
+ }
+
+ //add/update with new params on the paramMap
+ if (params != null && params.size() > 0)
+ {
+ for (Map.Entry<String, List<String>> pair : params.entrySet())
+ {
+ if (pair.getKey() != null && pair.getKey().trim().length() != 0)
+ {
+ if (paramMap == null)
+ {
+ paramMap = new HashMap<String, List<String>>();
+ }
+ paramMap.put(pair.getKey(), pair.getValue());
+ }
+ }
+ }
+
+ // start building the new URL
+ StringBuilder newUrl = new StringBuilder(url);
+
+ //now add the updated param list onto the url
+ if (paramMap != null && paramMap.size()>0)
+ {
+ boolean isFirstPair = true;
+ for (Map.Entry<String, List<String>> pair : paramMap.entrySet())
+ {
+ for (String value : pair.getValue())
+ {
+ if (!isFirstPair)
+ {
+ newUrl.append(_URL_PARAM_SEPERATOR);
+ }
+ else
+ {
+ newUrl.append(_URL_QUERY_SEPERATOR);
+ isFirstPair = false;
+ }
+
+ newUrl.append(pair.getKey());
+ newUrl.append(_URL_NAME_VALUE_PAIR_SEPERATOR);
+ try
+ {
+ newUrl.append(URLEncoder.encode(value,characterResponseEncoding));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ //shouldn't ever get here
+ throw new UnsupportedOperationException("Encoding type=" + characterResponseEncoding
+ + " not supported", e);
+ }
+ }
+ }
+ }
+
+ //add the fragment back on (if any)
+ if (fragment != null)
+ {
+ newUrl.append(_URL_FRAGMENT_SEPERATOR + fragment);
+ }
+
+ return newUrl.toString();
+ }
+
+ private static final String _URL_PARAM_SEPERATOR="&";
+ private static final String _URL_QUERY_SEPERATOR="?";
+ private static final String _URL_FRAGMENT_SEPERATOR="#";
+ private static final String _URL_NAME_VALUE_PAIR_SEPERATOR="=";
}
\ No newline at end of file
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java?rev=1485037&r1=1485036&r2=1485037&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java Wed May 22 03:29:03 2013
@@ -360,6 +360,9 @@ public final class GlobalConfiguratorImp
{
RequestStateMap state = RequestStateMap.getInstance(ec);
RequestType type = (RequestType) state.get(_REQUEST_TYPE);
+
+ //Install the URLEncoder plugin system
+ ec = new URLEncoderExternalContext(ec);
if (type == null)
{
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/URLEncoderExternalContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/URLEncoderExternalContext.java?rev=1485037&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/URLEncoderExternalContext.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/URLEncoderExternalContext.java Wed May 22 03:29:03 2013
@@ -0,0 +1,134 @@
+/*
+ * 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.myfaces.trinidadinternal.config;
+
+import java.io.UnsupportedEncodingException;
+
+import java.net.URLDecoder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.myfaces.trinidad.context.ExternalContextDecorator;
+import org.apache.myfaces.trinidad.util.URLEncoder;
+import org.apache.myfaces.trinidad.util.URLEncoderFactory;
+import org.apache.myfaces.trinidad.util.URLUtils;
+
+public class URLEncoderExternalContext
+ extends ExternalContextDecorator
+{
+ public URLEncoderExternalContext(ExternalContext ec)
+ {
+ _ec = ec;
+ }
+
+ protected ExternalContext getExternalContext()
+ {
+ return _ec;
+ }
+
+ @Override
+ public String encodeBookmarkableURL(String string, Map<String, List<String>> map)
+ {
+ URLEncoder encoder = getURLEncoder();
+
+ try
+ {
+ return encoder.encodeBookmarkableURL(string, map);
+ }
+ catch(UnsupportedOperationException e)
+ {
+ //This is a valid response if we have an old handler. In this case, we need to do our own encoding
+ Object response = _ec.getResponse();
+ if (!(response instanceof HttpServletResponse))
+ {
+ throw new UnsupportedOperationException("Only valid for HttpServlet requests");
+ }
+
+ String url = URLUtils.encodeURL(string, map, _ec.getResponseCharacterEncoding());
+
+ //For this guy, we simply return the URL I believe. Other encoding should be done before or after this.
+ return url;
+ }
+ }
+
+ @Override
+ public String encodeNamespace(String string)
+ {
+ // TODO Implement this method
+ return super.encodeNamespace(string);
+ }
+
+ @Override
+ public String encodePartialActionURL(String string)
+ {
+ // TODO Implement this method
+ return super.encodePartialActionURL(string);
+ }
+
+ @Override
+ public String encodeRedirectURL(String string, Map<String, List<String>> map)
+ {
+ URLEncoder encoder = getURLEncoder();
+
+ try
+ {
+ return encoder.encodeRedirectURL(string, map);
+ }
+ catch(UnsupportedOperationException e)
+ {
+ //This is a valid response if we have an old handler. In this case, we need to do our own encoding
+ Object response = _ec.getResponse();
+ if (!(response instanceof HttpServletResponse))
+ {
+ throw new UnsupportedOperationException("Only valid for HttpServlet requests");
+ }
+
+ String url = URLUtils.encodeURL(string, map, _ec.getResponseCharacterEncoding());
+
+ //this version of the encodeRedirect method MUST be supported.
+ return encoder.encodeRedirectURL(url);
+ }
+ }
+
+ @Override
+ public String encodeResourceURL(String url)
+ {
+ return getURLEncoder().encodeResourceURL(url);
+ }
+
+ @Override
+ public String encodeActionURL(String url)
+ {
+ return getURLEncoder().encodeActionURL(url);
+ }
+
+ protected URLEncoder getURLEncoder()
+ {
+ return URLEncoderFactory.getFactory().getURLEncoder(_ec);
+ }
+
+ private ExternalContext _ec;
+}