You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mf...@apache.org on 2011/02/08 19:13:07 UTC
svn commit: r1068498 - in
/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util:
QueryString.java URLUtils.java
Author: mfreedman
Date: Tue Feb 8 18:13:07 2011
New Revision: 1068498
URL: http://svn.apache.org/viewvc?rev=1068498&view=rev
Log:
PORTLETBRIDGE-176: Handle Urls with # (fragments) in them
Modified:
myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java
myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/URLUtils.java
Modified: myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java?rev=1068498&r1=1068497&r2=1068498&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java (original)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java Tue Feb 8 18:13:07 2011
@@ -1,530 +1,557 @@
-/* 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.portlet.faces.util;
-
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A class encapsulating an HTTP query string.
- */
-public final class QueryString
-{
- private String mQueryString;
- private String mCharacterEncoding;
- private Map<String, List<Parameter>> mParameterMap;
- private List<Parameter> mParameterList;
- private List<String> mParameterNames;
-
- /**
- * Construct a <code>QueryString</code> from a pre-encoded string.
- */
- public QueryString(String queryString, String characterEncoding)
- {
- // We only work on regular QueryStrings not strictXhtml QueryStrings
- mQueryString = queryString.replace("&", "&");
- mCharacterEncoding = characterEncoding;
- }
-
- /**
- * Makes a copy of an existing <code>QueryString</code>.
- */
- public QueryString(QueryString source)
- {
- mQueryString = source.mQueryString;
- mCharacterEncoding = source.mCharacterEncoding;
- if (source.mParameterList != null)
- {
- mParameterList = new ArrayList<Parameter>(source.mParameterList);
- }
- }
-
- /**
- * Constructs an empty query string (parameters may be added later).
- */
- public QueryString(String characterEncoding)
- {
- mCharacterEncoding = characterEncoding;
- }
-
- /**
- * Constructs a query string from an old-fashioned array of PRE-ENCODED name-value pairs
- */
- public QueryString(String[][] args, String characterEncoding)
- {
- this(characterEncoding);
- for (String[] element : args)
- {
- addParameter(element[0], element[1], true);
- }
- }
-
- /**
- * Constructs a query string from a list of PRE-ENCODED name-value pairs
- */
- public QueryString(List<String[]> params, String characterEncoding)
- {
- this(characterEncoding);
-
- for (String[] pair : params)
- {
- // -= Simon Lessard =-
- // FIXME: Add if (pair == null) check
- addParameter(pair[0], pair[1], true);
- }
- }
-
- /**
- * Converts this object into an encoded query string.
- */
- @Override
- public String toString()
- {
- // Use appendTo to concatenate the parameters together
- if (mQueryString == null)
- {
- appendTo(new StringBuilder(200));
- }
- return mQueryString;
- }
-
- /**
- * Appends the contents of this object to the given buffer in encoded query string form.
- *
- * @param buff
- * the buffer to append to
- */
- public void appendTo(StringBuilder buff)
- {
- if (mQueryString == null)
- {
- // If we don't have a cached query string yet, generate it
- if (mParameterList == null || mParameterList.isEmpty())
- {
- // If we don't have any parameters at all, cache the empty string
- mQueryString = "";
- }
- else
- {
- // Remember the start position in the buffer, so that we can also
- // cache the concatenated string in mQueryString
- int startPos = buff.length();
-
- Iterator<Parameter> iter = mParameterList.iterator();
- Parameter param = iter.next();
- buff.append(param.getEncodedName()).append('=').append(param.getEncodedValue());
-
- while (iter.hasNext())
- {
- param = iter.next();
- buff.append('&').append(param.getEncodedName()).append('=')
- .append(param.getEncodedValue());
- }
-
- mQueryString = buff.substring(startPos);
- }
- }
- else
- {
- // If we have a cached query string, reuse it
- buff.append(mQueryString);
- }
- }
-
- public Enumeration<String> getParameterNames()
- {
- initParameterMap();
- return Collections.enumeration(mParameterNames);
- }
-
- public Map getParameterMap()
- {
- initParameterMap();
- return mParameterMap;
- }
-
- public int numParameters()
- {
- return (mParameterMap != null) ? mParameterMap.size() : 0;
- }
-
- public String getParameter(String name)
- {
- initParameterMap();
- List<Parameter> values = mParameterMap.get(name);
- return values == null ? null : values.get(0).getValue();
- }
-
- public Enumeration<String> getParameterValues(String name)
- {
- initParameterMap();
- List<Parameter> params = mParameterMap.get(name);
- if (params == null || params.isEmpty())
- {
- List<String> temp = Collections.emptyList();
- return Collections.enumeration(temp);
- }
-
- List<String> values = new ArrayList<String>(params.size());
- for (Parameter param : params)
- {
- values.add(param.getValue());
- }
-
- return Collections.enumeration(values);
- }
-
- public void addParameter(String name, String value)
- {
- addParameter(name, value, false);
- }
-
- public void addParameter(String name, String value, boolean isEncoded)
- {
- if (value == null)
- {
- return;
- }
- initParameterList();
-
- // Invalidate the query string
- mQueryString = null;
-
- // Update the parameter list
- Parameter param = new Parameter(name, value, isEncoded);
- mParameterList.add(param);
-
- // Update the parameter map if it is initialized
- if (mParameterMap != null)
- {
- String decodedName = param.getName();
- List<Parameter> values = mParameterMap.get(decodedName);
- if (values == null)
- {
- createParameterList(param);
- }
- else
- {
- values.add(param);
- }
- }
- }
-
- public void setParameter(String name, String value)
- {
- setParameter(name, value, false);
- }
-
- public void setParameter(String name, String value, boolean isEncoded)
- {
- if (value == null)
- {
- removeParameter(name, isEncoded);
- return;
- }
- initParameterMap();
-
- // Invalidate the query string
- mQueryString = null;
-
- // Update the map
- Parameter param = new Parameter(name, value, isEncoded);
- String decodedName = param.getName();
- List<Parameter> values = mParameterMap.get(decodedName);
- if (values == null)
- {
- createParameterList(param);
- mParameterList.add(param);
- }
- else
- {
- values.clear();
-
- // First, replace the existing occurence of the parameter
- int i = mParameterList.indexOf(param);
- mParameterList.set(i, param);
-
- // Now, remove any subsequent occurrences
- int j;
- while ((j = mParameterList.lastIndexOf(param)) > i)
- {
- mParameterList.remove(j);
- }
-
- values.add(param);
- }
- }
-
- public String removeParameter(String name)
- {
- return removeParameter(name, false);
- }
-
- public String removeParameter(String name, boolean isEncoded)
- {
- initParameterList();
-
- // Invalidate the query string
- mQueryString = null;
-
- // Create a template parameter for comparisons, so that we can avoid
- // decoding all parameter names in the list
- Parameter templateParam = new Parameter(name, "", isEncoded);
-
- // Update the parameter list
- Iterator<Parameter> i = mParameterList.iterator();
- Parameter firstParam = null;
- while (i.hasNext())
- {
- Parameter param = i.next();
- // Compare the parameter with our template (only the template name
- // will be encoded / decoded if necessary)
- if (templateParam.equals(param))
- {
- if (firstParam == null)
- {
- firstParam = param;
- }
-
- i.remove();
- }
- }
-
- if (firstParam == null)
- {
- return null;
- }
-
- // Update the map, if it is initialized and we found a parameter
- if (mParameterMap != null)
- {
- String decodedName = templateParam.getName();
- List<Parameter> values = mParameterMap.remove(decodedName);
- if (values != null)
- {
- mParameterNames.remove(decodedName);
- }
- }
-
- return isEncoded ? firstParam.getEncodedValue() : firstParam.getValue();
- }
-
- private void createParameterList(Parameter param)
- {
- String decodedName = param.getName();
-
- List<Parameter> values = new ArrayList<Parameter>(4);
- mParameterMap.put(decodedName, values);
-
- // Only add UNIQUE parameter names (preserving order)
- mParameterNames.add(decodedName);
-
- values.add(param);
- }
-
- private void initParameterMap()
- {
- if (mParameterMap == null)
- {
- initParameterList();
-
- // TODO: Constants
- mParameterMap = new HashMap<String, List<Parameter>>(30);
- mParameterNames = new ArrayList<String>(30);
- if (mParameterList.isEmpty())
- {
- return;
- }
-
- String decodedName;
-
- for (Parameter param : mParameterList)
- {
- decodedName = param.getName();
- List<Parameter> values = mParameterMap.get(decodedName);
- if (values == null)
- {
- createParameterList(param);
- }
- else
- {
- values.add(param);
- }
- }
- }
- }
-
- private void initParameterList()
- {
- if (mParameterList == null)
- {
- // TODO: Constant
- mParameterList = new ArrayList<Parameter>(30);
- int length;
- if (mQueryString == null || (length = mQueryString.length()) == 0)
- {
- return;
- }
- Parameter param;
- int lastPos = 0, nextPos, sepPos;
- do
- {
- nextPos = mQueryString.indexOf('&', lastPos);
- if (nextPos == -1)
- {
- nextPos = length;
- }
- sepPos = mQueryString.indexOf('=', lastPos);
- if (sepPos != -1 && sepPos < nextPos)
- {
- param = new Parameter(mQueryString.substring(lastPos, sepPos),
- mQueryString.substring(sepPos + 1, nextPos), true);
- }
- else
- {
- param = new Parameter(mQueryString.substring(lastPos, nextPos), "", true);
- }
- mParameterList.add(param);
- lastPos = nextPos + 1;
- } while (nextPos < length);
- }
- }
-
- private class Parameter
- {
- private String mName;
- private String mEncodedName;
-
- private String mValue;
- private String mEncodedValue;
-
- public Parameter(String name, String value, boolean encoded)
- {
- if (encoded)
- {
- mEncodedName = name;
- mEncodedValue = value;
- }
- else
- {
- mName = name;
- mValue = value;
- }
- }
-
- public String getName()
- {
- if (mName == null)
- {
- try
- {
- mName = HTTPUtils.decode(mEncodedName, mCharacterEncoding);
- }
- catch (UnsupportedEncodingException uee)
- {
- handleUnsupportedEncoding();
- }
- }
- return mName;
- }
-
- public String getEncodedName()
- {
- if (mEncodedName == null)
- {
- try
- {
- mEncodedName = HTTPUtils.encode(mName, mCharacterEncoding);
- }
- catch (UnsupportedEncodingException uee)
- {
- handleUnsupportedEncoding();
- }
- }
- return mEncodedName;
- }
-
- public String getValue()
- {
- if (mValue == null)
- {
- try
- {
- mValue = HTTPUtils.decode(mEncodedValue, mCharacterEncoding);
- }
- catch (UnsupportedEncodingException uee)
- {
- handleUnsupportedEncoding();
- }
- }
- return mValue;
- }
-
- public String getEncodedValue()
- {
- if (mEncodedValue == null)
- {
- try
- {
- mEncodedValue = HTTPUtils.encode(mValue, mCharacterEncoding);
- }
- catch (UnsupportedEncodingException uee)
- {
- handleUnsupportedEncoding();
- }
- }
- return mEncodedValue;
- }
-
- /**
- * Compares two parameters for name equality.
- *
- * Attempts not to invoke any lazy encoding or decoding in the passed in parameter - only in
- * this one.
- */
- @Override
- public boolean equals(Object o)
- {
- if (o == null || !(o instanceof Parameter))
- {
- return false;
- }
- Parameter p1 = (Parameter) o;
- return p1.mName != null && getName().equals(p1.mName) || p1.mEncodedName != null
- && getEncodedName().equals(p1.mEncodedName);
- }
- }
-
- private void handleUnsupportedEncoding()
- {
- throw new IllegalArgumentException(
- new StringBuilder(100)
- .append(
- "Unrecognized character encoding \"")
- .append(mCharacterEncoding)
- .append('"').toString());
- }
-}
+/* 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.portlet.faces.util;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A class encapsulating an HTTP query string.
+ */
+public final class QueryString
+{
+ private String mQueryString;
+ private String mCharacterEncoding;
+ private Map<String, List<Parameter>> mParameterMap;
+ private List<Parameter> mParameterList;
+ private List<String> mParameterNames;
+ private String mFragment;
+
+ /**
+ * Construct a <code>QueryString</code> from a pre-encoded string.
+ */
+ public QueryString(String queryString, String characterEncoding)
+ {
+ // We only work on regular QueryStrings not strictXhtml QueryStrings
+ mQueryString = queryString.replace("&", "&");
+ mCharacterEncoding = characterEncoding;
+ }
+
+ /**
+ * Makes a copy of an existing <code>QueryString</code>.
+ */
+ public QueryString(QueryString source)
+ {
+ mQueryString = source.mQueryString;
+ mCharacterEncoding = source.mCharacterEncoding;
+ if (source.mParameterList != null)
+ {
+ mParameterList = new ArrayList<Parameter>(source.mParameterList);
+ }
+ }
+
+ /**
+ * Constructs an empty query string (parameters may be added later).
+ */
+ public QueryString(String characterEncoding)
+ {
+ mCharacterEncoding = characterEncoding;
+ }
+
+ /**
+ * Constructs a query string from an old-fashioned array of PRE-ENCODED name-value pairs
+ */
+ public QueryString(String[][] args, String characterEncoding)
+ {
+ this(characterEncoding);
+ for (String[] element : args)
+ {
+ addParameter(element[0], element[1], true);
+ }
+ }
+
+ /**
+ * Constructs a query string from a list of PRE-ENCODED name-value pairs
+ */
+ public QueryString(List<String[]> params, String characterEncoding)
+ {
+ this(characterEncoding);
+
+ for (String[] pair : params)
+ {
+ // -= Simon Lessard =-
+ // FIXME: Add if (pair == null) check
+ addParameter(pair[0], pair[1], true);
+ }
+ }
+
+ /**
+ * Converts this object into an encoded query string.
+ */
+ @Override
+ public String toString()
+ {
+ // Use appendTo to concatenate the parameters together
+ if (mQueryString == null)
+ {
+ appendTo(new StringBuilder(200));
+ }
+ return mQueryString;
+ }
+
+ /**
+ * Appends the contents of this object to the given buffer in encoded query string form.
+ *
+ * @param buff
+ * the buffer to append to
+ */
+ public void appendTo(StringBuilder buff)
+ {
+ if (mQueryString == null)
+ {
+ // If we don't have a cached query string yet, generate it
+ if (mParameterList == null || mParameterList.isEmpty())
+ {
+ // If we don't have any parameters at all, cache the empty string
+ mQueryString = "";
+ }
+ else
+ {
+ // Remember the start position in the buffer, so that we can also
+ // cache the concatenated string in mQueryString
+ int startPos = buff.length();
+
+ Iterator<Parameter> iter = mParameterList.iterator();
+ Parameter param = iter.next();
+ buff.append(param.getEncodedName()).append('=').append(param.getEncodedValue());
+
+ while (iter.hasNext())
+ {
+ param = iter.next();
+ buff.append('&').append(param.getEncodedName()).append('=')
+ .append(param.getEncodedValue());
+ }
+
+ mQueryString = buff.substring(startPos);
+ }
+
+ if (mFragment != null)
+ {
+ mQueryString += mFragment;
+ }
+ }
+ else
+ {
+ // If we have a cached query string, reuse it
+ buff.append(mQueryString);
+ }
+ }
+
+ public Enumeration<String> getParameterNames()
+ {
+ initParameterMap();
+ return Collections.enumeration(mParameterNames);
+ }
+
+ public Map getParameterMap()
+ {
+ initParameterMap();
+ return mParameterMap;
+ }
+
+ public int numParameters()
+ {
+ return (mParameterMap != null) ? mParameterMap.size() : 0;
+ }
+
+ public String getParameter(String name)
+ {
+ initParameterMap();
+ List<Parameter> values = mParameterMap.get(name);
+ return values == null ? null : values.get(0).getValue();
+ }
+
+ public Enumeration<String> getParameterValues(String name)
+ {
+ initParameterMap();
+ List<Parameter> params = mParameterMap.get(name);
+ if (params == null || params.isEmpty())
+ {
+ List<String> temp = Collections.emptyList();
+ return Collections.enumeration(temp);
+ }
+
+ List<String> values = new ArrayList<String>(params.size());
+ for (Parameter param : params)
+ {
+ values.add(param.getValue());
+ }
+
+ return Collections.enumeration(values);
+ }
+
+ public void addParameter(String name, String value)
+ {
+ addParameter(name, value, false);
+ }
+
+ public void addParameter(String name, String value, boolean isEncoded)
+ {
+ if (value == null)
+ {
+ return;
+ }
+ initParameterList();
+
+ // Invalidate the query string
+ mQueryString = null;
+
+ // Update the parameter list
+ Parameter param = new Parameter(name, value, isEncoded);
+ mParameterList.add(param);
+
+ // Update the parameter map if it is initialized
+ if (mParameterMap != null)
+ {
+ String decodedName = param.getName();
+ List<Parameter> values = mParameterMap.get(decodedName);
+ if (values == null)
+ {
+ createParameterList(param);
+ }
+ else
+ {
+ values.add(param);
+ }
+ }
+ }
+
+ public void setParameter(String name, String value)
+ {
+ setParameter(name, value, false);
+ }
+
+ public void setParameter(String name, String value, boolean isEncoded)
+ {
+ if (value == null)
+ {
+ removeParameter(name, isEncoded);
+ return;
+ }
+ initParameterMap();
+
+ // Invalidate the query string
+ mQueryString = null;
+
+ // Update the map
+ Parameter param = new Parameter(name, value, isEncoded);
+ String decodedName = param.getName();
+ List<Parameter> values = mParameterMap.get(decodedName);
+ if (values == null)
+ {
+ createParameterList(param);
+ mParameterList.add(param);
+ }
+ else
+ {
+ values.clear();
+
+ // First, replace the existing occurence of the parameter
+ int i = mParameterList.indexOf(param);
+ mParameterList.set(i, param);
+
+ // Now, remove any subsequent occurrences
+ int j;
+ while ((j = mParameterList.lastIndexOf(param)) > i)
+ {
+ mParameterList.remove(j);
+ }
+
+ values.add(param);
+ }
+ }
+
+ public String removeParameter(String name)
+ {
+ return removeParameter(name, false);
+ }
+
+ public String removeParameter(String name, boolean isEncoded)
+ {
+ initParameterList();
+
+ // Invalidate the query string
+ mQueryString = null;
+
+ // Create a template parameter for comparisons, so that we can avoid
+ // decoding all parameter names in the list
+ Parameter templateParam = new Parameter(name, "", isEncoded);
+
+ // Update the parameter list
+ Iterator<Parameter> i = mParameterList.iterator();
+ Parameter firstParam = null;
+ while (i.hasNext())
+ {
+ Parameter param = i.next();
+ // Compare the parameter with our template (only the template name
+ // will be encoded / decoded if necessary)
+ if (templateParam.equals(param))
+ {
+ if (firstParam == null)
+ {
+ firstParam = param;
+ }
+
+ i.remove();
+ }
+ }
+
+ if (firstParam == null)
+ {
+ return null;
+ }
+
+ // Update the map, if it is initialized and we found a parameter
+ if (mParameterMap != null)
+ {
+ String decodedName = templateParam.getName();
+ List<Parameter> values = mParameterMap.remove(decodedName);
+ if (values != null)
+ {
+ mParameterNames.remove(decodedName);
+ }
+ }
+
+ return isEncoded ? firstParam.getEncodedValue() : firstParam.getValue();
+ }
+
+ private void createParameterList(Parameter param)
+ {
+ String decodedName = param.getName();
+
+ List<Parameter> values = new ArrayList<Parameter>(4);
+ mParameterMap.put(decodedName, values);
+
+ // Only add UNIQUE parameter names (preserving order)
+ mParameterNames.add(decodedName);
+
+ values.add(param);
+ }
+
+ private void initParameterMap()
+ {
+ if (mParameterMap == null)
+ {
+ initParameterList();
+
+ // TODO: Constants
+ mParameterMap = new HashMap<String, List<Parameter>>(30);
+ mParameterNames = new ArrayList<String>(30);
+ if (mParameterList.isEmpty())
+ {
+ return;
+ }
+
+ String decodedName;
+
+ for (Parameter param : mParameterList)
+ {
+ decodedName = param.getName();
+ List<Parameter> values = mParameterMap.get(decodedName);
+ if (values == null)
+ {
+ createParameterList(param);
+ }
+ else
+ {
+ values.add(param);
+ }
+ }
+ }
+ }
+
+ private void initParameterList()
+ {
+ if (mParameterList == null)
+ {
+ // remove/deal with a fragment hanging on the end
+ initFragment();
+
+ // TODO: Constant
+ mParameterList = new ArrayList<Parameter>(30);
+ int length;
+ if (mQueryString == null || (length = mQueryString.length()) == 0)
+ {
+ return;
+ }
+ Parameter param;
+ int lastPos = 0, nextPos, sepPos;
+ do
+ {
+ nextPos = mQueryString.indexOf('&', lastPos);
+ if (nextPos == -1)
+ {
+ nextPos = length;
+ }
+ sepPos = mQueryString.indexOf('=', lastPos);
+ if (sepPos != -1 && sepPos < nextPos)
+ {
+ param = new Parameter(mQueryString.substring(lastPos, sepPos),
+ mQueryString.substring(sepPos + 1, nextPos), true);
+ }
+ else
+ {
+ param = new Parameter(mQueryString.substring(lastPos, nextPos), "", true);
+ }
+ mParameterList.add(param);
+ lastPos = nextPos + 1;
+ } while (nextPos < length);
+ }
+ }
+
+ private void initFragment()
+ {
+ if (mQueryString != null)
+ {
+ int i = mQueryString.indexOf('#');
+ if (i == 0)
+ {
+ mFragment = mQueryString;
+ mQueryString = "";
+ }
+ else if (i > 0)
+ {
+ mFragment = mQueryString.substring(i);
+ mQueryString = mQueryString.substring(0, i);
+ }
+ }
+ }
+
+ private class Parameter
+ {
+ private String mName;
+ private String mEncodedName;
+
+ private String mValue;
+ private String mEncodedValue;
+
+ public Parameter(String name, String value, boolean encoded)
+ {
+ if (encoded)
+ {
+ mEncodedName = name;
+ mEncodedValue = value;
+ }
+ else
+ {
+ mName = name;
+ mValue = value;
+ }
+ }
+
+ public String getName()
+ {
+ if (mName == null)
+ {
+ try
+ {
+ mName = HTTPUtils.decode(mEncodedName, mCharacterEncoding);
+ }
+ catch (UnsupportedEncodingException uee)
+ {
+ handleUnsupportedEncoding();
+ }
+ }
+ return mName;
+ }
+
+ public String getEncodedName()
+ {
+ if (mEncodedName == null)
+ {
+ try
+ {
+ mEncodedName = HTTPUtils.encode(mName, mCharacterEncoding);
+ }
+ catch (UnsupportedEncodingException uee)
+ {
+ handleUnsupportedEncoding();
+ }
+ }
+ return mEncodedName;
+ }
+
+ public String getValue()
+ {
+ if (mValue == null)
+ {
+ try
+ {
+ mValue = HTTPUtils.decode(mEncodedValue, mCharacterEncoding);
+ }
+ catch (UnsupportedEncodingException uee)
+ {
+ handleUnsupportedEncoding();
+ }
+ }
+ return mValue;
+ }
+
+ public String getEncodedValue()
+ {
+ if (mEncodedValue == null)
+ {
+ try
+ {
+ mEncodedValue = HTTPUtils.encode(mValue, mCharacterEncoding);
+ }
+ catch (UnsupportedEncodingException uee)
+ {
+ handleUnsupportedEncoding();
+ }
+ }
+ return mEncodedValue;
+ }
+
+ /**
+ * Compares two parameters for name equality.
+ *
+ * Attempts not to invoke any lazy encoding or decoding in the passed in parameter - only in
+ * this one.
+ */
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o == null || !(o instanceof Parameter))
+ {
+ return false;
+ }
+ Parameter p1 = (Parameter) o;
+ return p1.mName != null && getName().equals(p1.mName) || p1.mEncodedName != null
+ && getEncodedName().equals(p1.mEncodedName);
+ }
+ }
+
+ private void handleUnsupportedEncoding()
+ {
+ throw new IllegalArgumentException(
+ new StringBuilder(100)
+ .append(
+ "Unrecognized character encoding \"")
+ .append(mCharacterEncoding)
+ .append('"').toString());
+ }
+}
Modified: myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/URLUtils.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/URLUtils.java?rev=1068498&r1=1068497&r2=1068498&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/URLUtils.java (original)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/URLUtils.java Tue Feb 8 18:13:07 2011
@@ -1,146 +1,215 @@
-/* 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.portlet.faces.util;
-
-public class URLUtils
-{
-
- /**
- * Borrowed from package oracle.adfinternal.view.faces.share.url.EncoderUtils
- */
- public static String appendURLArguments(StringBuilder buffer, String baseURL,
- String[] keysAndValues)
- {
-
- // Bug 1814825: the anchor has to stay on the end.
- int anchorIndex = baseURL.indexOf('#');
-
- if (anchorIndex >= 0)
- {
- buffer.append(baseURL.substring(0, anchorIndex));
- }
- else
- {
- buffer.append(baseURL);
- }
-
- boolean queryAppended = baseURL.indexOf('?') >= 0;
-
- for (int i = 0; i < keysAndValues.length; i += 2)
- {
- String value = keysAndValues[i + 1];
- if (value != null)
- {
- // only append '?' at start if the URL doesn't already contain
- // arguments
- if (!queryAppended)
- {
- queryAppended = true;
- buffer.append('?');
- }
- else
- {
- buffer.append('&');
- }
-
- buffer.append(keysAndValues[i]);
- buffer.append('=');
- buffer.append(value);
- }
- }
-
- String beforeEncode = buffer.toString();
- return beforeEncode;
- }
-
- /**
- * Borrowed from package oracle.adfinternal.view.faces.share.url.EncoderUtils
- */
- public static String appendURLArguments(String baseURL, String[] keysAndValues)
- {
- // buffer length = base + separators + keys + values
- int bufferLength = baseURL.length() + keysAndValues.length;
- for (int i = 0; i < keysAndValues.length; i += 2)
- {
- String value = keysAndValues[i + 1];
- if (value != null)
- {
- bufferLength += keysAndValues[i].length() + value.length();
- }
- }
-
- StringBuilder buffer = new StringBuilder(bufferLength);
-
- return appendURLArguments(buffer, baseURL, keysAndValues);
- }
-
- public static String convertFromRelative(String currentPath, String relativeLoc)
- throws IllegalArgumentException
- {
- // determine if and how many levels we must walk up the currentPath
- int levels = 0;
- int i = 0, length = relativeLoc.length();
- while (i + 1 < length)
- {
- if (relativeLoc.charAt(i) != '.')
- {
- break;
- }
- else if (relativeLoc.charAt(i) == '.' && relativeLoc.charAt(i + 1) == '/')
- {
- // no new level but prune the ./
- i += 2;
- }
- else if (i + 2 < length && relativeLoc.charAt(i) == '.' && relativeLoc.charAt(i + 1) == '.'
- && relativeLoc.charAt(i + 2) == '/')
- {
- levels += 1;
- i += 3;
- }
- }
-
- StringBuilder sb = new StringBuilder(currentPath);
- if (currentPath.endsWith("/"))
- {
- sb = sb.deleteCharAt(currentPath.length() - 1);
- }
- for (int j = 0; j < levels; j++)
- {
- int loc = sb.lastIndexOf("/");
- if (loc < 0)
- {
- throw new IllegalArgumentException("Location: " + relativeLoc
- + "Can't be made relative to: " + currentPath);
- }
- sb = sb.delete(loc, sb.length());
- }
-
- // now sb should contain root path without trailing / so add one
- sb = sb.append("/");
-
- // now add the portion of the relativeLoc that doesn't contain
- // the relative references
- sb = sb.append(relativeLoc.substring(i));
-
- return sb.toString();
-
- }
-
-}
+/* 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.portlet.faces.util;
+
+import java.util.List;
+import java.util.Map;
+
+public class URLUtils
+{
+
+ /**
+ * Borrowed from package oracle.adfinternal.view.faces.share.url.EncoderUtils
+ */
+ public static String appendURLArguments(StringBuilder buffer, String baseURL,
+ String[] keysAndValues)
+ {
+
+ // Bug 1814825: the anchor has to stay on the end.
+ int anchorIndex = baseURL.indexOf('#');
+
+ if (anchorIndex >= 0)
+ {
+ buffer.append(baseURL.substring(0, anchorIndex));
+ }
+ else
+ {
+ buffer.append(baseURL);
+ }
+
+ boolean queryAppended = baseURL.indexOf('?') >= 0;
+
+ for (int i = 0; i < keysAndValues.length; i += 2)
+ {
+ String value = keysAndValues[i + 1];
+ if (value != null)
+ {
+ // only append '?' at start if the URL doesn't already contain
+ // arguments
+ if (!queryAppended)
+ {
+ queryAppended = true;
+ buffer.append('?');
+ }
+ else
+ {
+ buffer.append('&');
+ }
+
+ buffer.append(keysAndValues[i]);
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+
+ String beforeEncode = buffer.toString();
+ return beforeEncode;
+ }
+
+ /**
+ * Borrowed from package oracle.adfinternal.view.faces.share.url.EncoderUtils
+ */
+ public static String appendURLArguments(String baseURL, String[] keysAndValues)
+ {
+ // buffer length = base + separators + keys + values
+ int bufferLength = baseURL.length() + keysAndValues.length;
+ for (int i = 0; i < keysAndValues.length; i += 2)
+ {
+ String value = keysAndValues[i + 1];
+ if (value != null)
+ {
+ bufferLength += keysAndValues[i].length() + value.length();
+ }
+ }
+
+ StringBuilder buffer = new StringBuilder(bufferLength);
+
+ return appendURLArguments(buffer, baseURL, keysAndValues);
+ }
+
+
+ public static String appendURLArguments(StringBuilder buffer, String baseURL,
+ Map<String, List<String>> keysAndValues)
+ {
+
+ // Bug 1814825: the anchor has to stay on the end.
+ int anchorIndex = baseURL.indexOf('#');
+
+ if (anchorIndex >= 0)
+ {
+ buffer.append(baseURL.substring(0, anchorIndex));
+ }
+ else
+ {
+ buffer.append(baseURL);
+ }
+
+ boolean queryAppended = baseURL.indexOf('?') >= 0;
+
+ for (Map.Entry<String, List<String>> entry : keysAndValues.entrySet())
+ {
+ String key = entry.getKey();
+ List<String> values = entry.getValue();
+
+ if (values == null) continue;
+
+ for (String value : values)
+ {
+ if (value != null)
+ {
+ // only append '?' at start if the URL doesn't already contain
+ // arguments
+ if (!queryAppended)
+ {
+ queryAppended = true;
+ buffer.append('?');
+ }
+ else
+ {
+ buffer.append('&');
+ }
+
+ buffer.append(key);
+ buffer.append('=');
+ buffer.append(value);
+ }
+ }
+ }
+
+
+ String beforeEncode = buffer.toString();
+ return beforeEncode;
+ }
+
+ public static String appendURLArguments(String baseURL, Map<String, List<String>> keysAndValues)
+ {
+ if (keysAndValues != null)
+ {
+ return appendURLArguments(new StringBuilder(baseURL.length()), baseURL, keysAndValues);
+ }
+ else
+ {
+ return baseURL;
+ }
+ }
+
+ public static String convertFromRelative(String currentPath, String relativeLoc)
+ throws IllegalArgumentException
+ {
+ // determine if and how many levels we must walk up the currentPath
+ int levels = 0;
+ int i = 0, length = relativeLoc.length();
+ while (i + 1 < length)
+ {
+ if (relativeLoc.charAt(i) != '.')
+ {
+ break;
+ }
+ else if (relativeLoc.charAt(i) == '.' && relativeLoc.charAt(i + 1) == '/')
+ {
+ // no new level but prune the ./
+ i += 2;
+ }
+ else if (i + 2 < length && relativeLoc.charAt(i) == '.' && relativeLoc.charAt(i + 1) == '.'
+ && relativeLoc.charAt(i + 2) == '/')
+ {
+ levels += 1;
+ i += 3;
+ }
+ }
+
+ StringBuilder sb = new StringBuilder(currentPath);
+ if (currentPath.endsWith("/"))
+ {
+ sb = sb.deleteCharAt(currentPath.length() - 1);
+ }
+ for (int j = 0; j < levels; j++)
+ {
+ int loc = sb.lastIndexOf("/");
+ if (loc < 0)
+ {
+ throw new IllegalArgumentException("Location: " + relativeLoc
+ + "Can't be made relative to: " + currentPath);
+ }
+ sb = sb.delete(loc, sb.length());
+ }
+
+ // now sb should contain root path without trailing / so add one
+ sb = sb.append("/");
+
+ // now add the portion of the relativeLoc that doesn't contain
+ // the relative references
+ sb = sb.append(relativeLoc.substring(i));
+
+ return sb.toString();
+
+ }
+
+}