private String encodeURL()

in impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java [863:1018]


    private String encodeURL(String baseUrl, Map<String, List<String>> parameters)
    {
        Assert.notNull(baseUrl, "url");
        checkHttpServletRequest();

        String fragment = null;
        String queryString = null;
        Map<String, List<String>> paramMap = null;

        //extract any URL fragment
        int index = baseUrl.indexOf('#');
        if (index != -1)
        {
            fragment = baseUrl.substring(index + 1);
            baseUrl = baseUrl.substring(0, index);
        }

        //extract the current query string and add the params to the paramMap
        index = baseUrl.indexOf('?');
        if (index != -1)
        {
            queryString = baseUrl.substring(index + 1);
            baseUrl = baseUrl.substring(0, index);
            String[] nameValuePairs = queryString.split("&");
            for (int i = 0; i < nameValuePairs.length; i++)
            {
                String[] currentPair = nameValuePairs[i].split("=");
                String currentName = currentPair[0];

                if (paramMap == null)
                {
                    paramMap = new HashMap<>(5, 1f);
                }

                List<String> values = paramMap.get(currentName);
                if (values == null)
                {
                    values = new ArrayList<>(1);
                    paramMap.put(currentName, values);
                }

                try
                {
                    values.add(currentPair.length > 1
                                ? URLDecoder.decode(currentPair[1], getResponseCharacterEncoding())
                                : "");
                }
                catch (UnsupportedEncodingException e)
                {
                    //shouldn't ever get here
                    throw new UnsupportedOperationException("Encoding type=" + getResponseCharacterEncoding()
                                                            + " not supported", e);
                }
            }
        }

        //add/update with new params on the paramMap
        if (parameters != null && !parameters.isEmpty())
        {
            for (Map.Entry<String, List<String>> pair : parameters.entrySet())
            {
                String key = pair.getKey();
                if (StringUtils.isNotBlank(key))
                {
                    if (paramMap == null)
                    {
                        paramMap = new HashMap<>(5, 1f);
                    }
                    paramMap.put(key, pair.getValue());
                }
            }
        }
        
        FacesContext facesContext = getCurrentFacesContext();
        ClientWindow window = facesContext.getExternalContext().getClientWindow();
        if (window != null && window.isClientWindowRenderModeEnabled(facesContext))
        {
            if (paramMap == null)
            {
                paramMap = new HashMap<>(5, 1f);
            }

            if (!paramMap.containsKey(ResponseStateManager.CLIENT_WINDOW_URL_PARAM))
            {
                paramMap.put(ResponseStateManager.CLIENT_WINDOW_URL_PARAM, Arrays.asList(window.getId()));
            }

            Map<String, String> additionalQueryURLParameters = window.getQueryURLParameters(facesContext);
            if (additionalQueryURLParameters != null)
            {
                for (Map.Entry<String , String> entry : additionalQueryURLParameters.entrySet())
                {
                    paramMap.put(entry.getKey(), Arrays.asList(entry.getValue()));
                }
            }
        }

        boolean hasParams = paramMap != null && !paramMap.isEmpty();

        if (!hasParams && fragment == null) 
        {
            return baseUrl;
        }

        // start building the new URL
        StringBuilder newUrl = SharedStringBuilder.get(facesContext, SB_ENCODE_URL, baseUrl.length() + 10);
        newUrl.append(baseUrl);

        //now add the updated param list onto the url
        if (hasParams)
        {
            boolean isFirstPair = true;
            for (Map.Entry<String, List<String>> pair : paramMap.entrySet())
            {
                for (int i = 0; i < pair.getValue().size(); i++)
                {
                    String value = pair.getValue().get(i);
                    
                    if (!isFirstPair)
                    {
                        newUrl.append('&');
                    }
                    else
                    {
                        newUrl.append('?');
                        isFirstPair = false;
                    }

                    newUrl.append(pair.getKey());
                    newUrl.append('=');
                    if (value != null)
                    {
                        try
                        {
                            newUrl.append(URLEncoder.encode(value, getResponseCharacterEncoding()));
                        }
                        catch (UnsupportedEncodingException e)
                        {
                            //shouldn't ever get here
                            throw new UnsupportedOperationException("Encoding type=" + getResponseCharacterEncoding()
                                                                    + " not supported", e);
                        }
                    }
                }
            }
        }

        //add the fragment back on (if any)
        if (fragment != null)
        {
            newUrl.append('#');
            newUrl.append(fragment);
        }

        return newUrl.toString();
    }