001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.util.common.string;
018
019import java.io.UnsupportedEncodingException;
020import java.net.URLEncoder;
021import java.util.Map;
022import java.util.Set;
023import javax.servlet.http.HttpServletRequest;
024import javax.servlet.http.HttpServletResponse;
025
026public class UrlUtils {
027    
028    private UrlUtils() {
029        super();
030    }
031    
032    private static class UrlUtilsHolder {
033        static UrlUtils instance = new UrlUtils();
034    }
035    
036    public static UrlUtils getInstance() {
037        return UrlUtilsHolder.instance;
038    }
039    
040    public StringBuilder buildBaseUrl(HttpServletRequest request) {
041        String scheme = request.getScheme();
042        String serverName = request.getServerName();
043        int serverPort = request.getServerPort();
044        String contextPath = request.getContextPath();
045        String servletPath = request.getServletPath();
046        boolean includeServerPort = (scheme.equals("http") && serverPort != 80) || (scheme.equals("https") && serverPort != 443);
047        
048        return new StringBuilder(scheme).append("://").append(serverName).append(includeServerPort? ":" + serverPort: "").append(contextPath).append(servletPath);
049    }
050
051    public StringBuilder buildParams(StringBuilder url, Map<String, String> params) {
052        if(params != null && params.size() > 0) {
053            Set<Map.Entry<String, String>> entrySet = params.entrySet();
054            boolean isFirst = true;
055
056            for(Map.Entry<String, String> entry : entrySet) {
057                url.append(isFirst ? '?' : '&');
058                try {
059                    url.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(), "UTF-8"));
060                } catch(UnsupportedEncodingException uee) {
061                    // If UTF-8 isn't a supported encoding, then there are severe problems.
062                    throw new RuntimeException(uee);
063                }
064                isFirst = false;
065            }
066        }
067
068        return url;
069    }
070
071    public String buildUrl(HttpServletRequest request, HttpServletResponse response, String path, Map<String, String> params) {
072        return response.encodeURL(buildParams(buildBaseUrl(request).append(path), params).toString());
073    }
074    
075}