001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.servlet;
016    
017    import com.liferay.portal.kernel.util.ArrayUtil;
018    import com.liferay.portal.kernel.util.CharPool;
019    import com.liferay.portal.kernel.util.StringPool;
020    import com.liferay.portal.kernel.util.StringUtil;
021    
022    import java.util.Collections;
023    import java.util.Enumeration;
024    import java.util.HashMap;
025    import java.util.LinkedHashSet;
026    import java.util.Map;
027    import java.util.Set;
028    
029    import javax.servlet.http.HttpServletRequest;
030    import javax.servlet.http.HttpServletRequestWrapper;
031    
032    /**
033     * @author Brian Wing Shun Chan
034     * @author Shuyang Zhou
035     * @author Sampsa Sohlman
036     */
037    public class DynamicServletRequest extends HttpServletRequestWrapper {
038    
039            public static final String DYNAMIC_QUERY_STRING = "DYNAMIC_QUERY_STRING";
040    
041            public static HttpServletRequest addQueryString(
042                    HttpServletRequest request, Map<String, String[]> parameterMap,
043                    String queryString) {
044    
045                    return addQueryString(request, parameterMap, queryString, true);
046            }
047    
048            public static HttpServletRequest addQueryString(
049                    HttpServletRequest request, Map<String, String[]> parameterMap,
050                    String queryString, boolean inherit) {
051    
052                    String[] parameters = StringUtil.split(queryString, CharPool.AMPERSAND);
053    
054                    if (parameters.length == 0) {
055                            return request;
056                    }
057    
058                    parameterMap = new HashMap<String, String[]>(parameterMap);
059    
060                    for (String parameter : parameters) {
061                            String[] parameterParts = StringUtil.split(
062                                    parameter, CharPool.EQUAL);
063    
064                            String name = parameterParts[0];
065                            String value = StringPool.BLANK;
066    
067                            if (parameterParts.length == 2) {
068                                    value = parameterParts[1];
069                            }
070    
071                            String[] values = parameterMap.get(name);
072    
073                            if (values == null) {
074                                    parameterMap.put(name, new String[] {value});
075                            }
076                            else {
077                                    String[] newValues = new String[values.length + 1];
078    
079                                    System.arraycopy(values, 0, newValues, 0, values.length);
080    
081                                    newValues[newValues.length - 1] = value;
082    
083                                    parameterMap.put(name, newValues);
084                            }
085                    }
086    
087                    request = new DynamicServletRequest(request, parameterMap, inherit);
088    
089                    request.setAttribute(DYNAMIC_QUERY_STRING, queryString);
090    
091                    return request;
092            }
093    
094            public static HttpServletRequest addQueryString(
095                    HttpServletRequest request, String queryString) {
096    
097                    return addQueryString(
098                            request, new HashMap<String, String[]>(), queryString, true);
099            }
100    
101            public static HttpServletRequest addQueryString(
102                    HttpServletRequest request, String queryString, boolean inherit) {
103    
104                    return addQueryString(
105                            request, new HashMap<String, String[]>(), queryString, inherit);
106            }
107    
108            public DynamicServletRequest(HttpServletRequest request) {
109                    this(request, null, true);
110            }
111    
112            public DynamicServletRequest(HttpServletRequest request, boolean inherit) {
113                    this(request, null, inherit);
114            }
115    
116            public DynamicServletRequest(
117                    HttpServletRequest request, Map<String, String[]> params) {
118    
119                    this(request, params, true);
120            }
121    
122            public DynamicServletRequest(
123                    HttpServletRequest request, Map<String, String[]> params,
124                    boolean inherit) {
125    
126                    super(request);
127    
128                    _params = new HashMap<String, String[]>();
129                    _inherit = inherit;
130    
131                    if (params != null) {
132                            _params.putAll(params);
133                    }
134    
135                    if (_inherit && (request instanceof DynamicServletRequest)) {
136                            DynamicServletRequest dynamicRequest =
137                                    (DynamicServletRequest)request;
138    
139                            setRequest(dynamicRequest.getRequest());
140    
141                            params = dynamicRequest.getDynamicParameterMap();
142    
143                            for (Map.Entry<String, String[]> entry : params.entrySet()) {
144                                    String name = entry.getKey();
145                                    String[] oldValues = entry.getValue();
146    
147                                    String[] curValues = _params.get(name);
148    
149                                    if (curValues == null) {
150                                            _params.put(name, oldValues);
151                                    }
152                                    else {
153                                            String[] newValues = ArrayUtil.append(oldValues, curValues);
154    
155                                            _params.put(name, newValues);
156                                    }
157                            }
158                    }
159            }
160    
161            public void appendParameter(String name, String value) {
162                    String[] values = _params.get(name);
163    
164                    if (values == null) {
165                            values = new String[] {value};
166                    }
167                    else {
168                            String[] newValues = new String[values.length + 1];
169    
170                            System.arraycopy(values, 0, newValues, 0, values.length);
171    
172                            newValues[newValues.length - 1] = value;
173    
174                            values = newValues;
175                    }
176    
177                    _params.put(name, values);
178            }
179    
180            public Map<String, String[]> getDynamicParameterMap() {
181                    return _params;
182            }
183    
184            @Override
185            public String getParameter(String name) {
186                    String[] values = _params.get(name);
187    
188                    if (_inherit && (values == null)) {
189                            return super.getParameter(name);
190                    }
191    
192                    if (ArrayUtil.isNotEmpty(values)) {
193                            return values[0];
194                    }
195                    else {
196                            return null;
197                    }
198            }
199    
200            @Override
201            public Map<String, String[]> getParameterMap() {
202                    Map<String, String[]> map = new HashMap<String, String[]>();
203    
204                    if (_inherit) {
205                            map.putAll(super.getParameterMap());
206                    }
207    
208                    map.putAll(_params);
209    
210                    return map;
211            }
212    
213            @Override
214            public Enumeration<String> getParameterNames() {
215                    Set<String> names = new LinkedHashSet<String>();
216    
217                    if (_inherit) {
218                            Enumeration<String> enu = super.getParameterNames();
219    
220                            while (enu.hasMoreElements()) {
221                                    names.add(enu.nextElement());
222                            }
223                    }
224    
225                    names.addAll(_params.keySet());
226    
227                    return Collections.enumeration(names);
228            }
229    
230            @Override
231            public String[] getParameterValues(String name) {
232                    String[] values = _params.get(name);
233    
234                    if (_inherit && (values == null)) {
235                            return super.getParameterValues(name);
236                    }
237    
238                    return values;
239            }
240    
241            public void setParameter(String name, String value) {
242                    _params.put(name, new String[] {value});
243            }
244    
245            public void setParameterValues(String name, String[] values) {
246                    _params.put(name, values);
247            }
248    
249            private boolean _inherit;
250            private Map<String, String[]> _params;
251    
252    }