001    /**
002     * Copyright (c) 2000-present 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                    parameterMap = new HashMap<String, String[]>(parameterMap);
053    
054                    String[] parameters = StringUtil.split(queryString, CharPool.AMPERSAND);
055    
056                    for (String parameter : parameters) {
057                            String[] parameterParts = StringUtil.split(
058                                    parameter, CharPool.EQUAL);
059    
060                            String name = parameterParts[0];
061                            String value = StringPool.BLANK;
062    
063                            if (parameterParts.length == 2) {
064                                    value = parameterParts[1];
065                            }
066    
067                            String[] values = parameterMap.get(name);
068    
069                            if (values == null) {
070                                    parameterMap.put(name, new String[] {value});
071                            }
072                            else {
073                                    String[] newValues = new String[values.length + 1];
074    
075                                    System.arraycopy(values, 0, newValues, 0, values.length);
076    
077                                    newValues[newValues.length - 1] = value;
078    
079                                    parameterMap.put(name, newValues);
080                            }
081                    }
082    
083                    request = new DynamicServletRequest(request, parameterMap, inherit);
084    
085                    request.setAttribute(DYNAMIC_QUERY_STRING, queryString);
086    
087                    return request;
088            }
089    
090            public static HttpServletRequest addQueryString(
091                    HttpServletRequest request, String queryString) {
092    
093                    return addQueryString(
094                            request, new HashMap<String, String[]>(), queryString, true);
095            }
096    
097            public static HttpServletRequest addQueryString(
098                    HttpServletRequest request, String queryString, boolean inherit) {
099    
100                    return addQueryString(
101                            request, new HashMap<String, String[]>(), queryString, inherit);
102            }
103    
104            public DynamicServletRequest(HttpServletRequest request) {
105                    this(request, null, true);
106            }
107    
108            public DynamicServletRequest(HttpServletRequest request, boolean inherit) {
109                    this(request, null, inherit);
110            }
111    
112            public DynamicServletRequest(
113                    HttpServletRequest request, Map<String, String[]> params) {
114    
115                    this(request, params, true);
116            }
117    
118            public DynamicServletRequest(
119                    HttpServletRequest request, Map<String, String[]> params,
120                    boolean inherit) {
121    
122                    super(request);
123    
124                    _params = new HashMap<String, String[]>();
125                    _inherit = inherit;
126    
127                    if (params != null) {
128                            _params.putAll(params);
129                    }
130    
131                    if (_inherit && (request instanceof DynamicServletRequest)) {
132                            DynamicServletRequest dynamicRequest =
133                                    (DynamicServletRequest)request;
134    
135                            dynamicRequest.injectInto(this);
136    
137                            params = dynamicRequest.getDynamicParameterMap();
138    
139                            for (Map.Entry<String, String[]> entry : params.entrySet()) {
140                                    String name = entry.getKey();
141                                    String[] oldValues = entry.getValue();
142    
143                                    String[] curValues = _params.get(name);
144    
145                                    if (curValues == null) {
146                                            _params.put(name, oldValues);
147                                    }
148                                    else {
149                                            String[] newValues = ArrayUtil.append(oldValues, curValues);
150    
151                                            _params.put(name, newValues);
152                                    }
153                            }
154                    }
155            }
156    
157            public void appendParameter(String name, String value) {
158                    String[] values = _params.get(name);
159    
160                    if (values == null) {
161                            values = new String[] {value};
162                    }
163                    else {
164                            String[] newValues = new String[values.length + 1];
165    
166                            System.arraycopy(values, 0, newValues, 0, values.length);
167    
168                            newValues[newValues.length - 1] = value;
169    
170                            values = newValues;
171                    }
172    
173                    _params.put(name, values);
174            }
175    
176            public Map<String, String[]> getDynamicParameterMap() {
177                    return _params;
178            }
179    
180            @Override
181            public String getParameter(String name) {
182                    String[] values = _params.get(name);
183    
184                    if (_inherit && (values == null)) {
185                            return super.getParameter(name);
186                    }
187    
188                    if (ArrayUtil.isNotEmpty(values)) {
189                            return values[0];
190                    }
191                    else {
192                            return null;
193                    }
194            }
195    
196            @Override
197            public Map<String, String[]> getParameterMap() {
198                    Map<String, String[]> map = new HashMap<String, String[]>();
199    
200                    if (_inherit) {
201                            map.putAll(super.getParameterMap());
202                    }
203    
204                    map.putAll(_params);
205    
206                    return map;
207            }
208    
209            @Override
210            public Enumeration<String> getParameterNames() {
211                    Set<String> names = new LinkedHashSet<String>();
212    
213                    if (_inherit) {
214                            Enumeration<String> enu = super.getParameterNames();
215    
216                            while (enu.hasMoreElements()) {
217                                    names.add(enu.nextElement());
218                            }
219                    }
220    
221                    names.addAll(_params.keySet());
222    
223                    return Collections.enumeration(names);
224            }
225    
226            @Override
227            public String[] getParameterValues(String name) {
228                    String[] values = _params.get(name);
229    
230                    if (_inherit && (values == null)) {
231                            return super.getParameterValues(name);
232                    }
233    
234                    return values;
235            }
236    
237            public void setParameter(String name, String value) {
238                    _params.put(name, new String[] {value});
239            }
240    
241            public void setParameterValues(String name, String[] values) {
242                    _params.put(name, values);
243            }
244    
245            protected void injectInto(DynamicServletRequest dynamicServletRequest) {
246                    dynamicServletRequest.setRequest(getRequest());
247            }
248    
249            private final boolean _inherit;
250            private final Map<String, String[]> _params;
251    
252    }