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.resiliency.spi.agent;
016    
017    import com.liferay.portal.kernel.resiliency.spi.agent.annotation.Direction;
018    import com.liferay.portal.kernel.servlet.HttpHeaders;
019    import com.liferay.portal.kernel.servlet.PersistentHttpServletRequestWrapper;
020    import com.liferay.portal.kernel.upload.FileItem;
021    import com.liferay.portal.kernel.upload.UploadServletRequest;
022    import com.liferay.portal.kernel.util.ArrayUtil;
023    import com.liferay.portal.kernel.util.ContentTypes;
024    import com.liferay.portal.kernel.util.CookieUtil;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.theme.ThemeDisplay;
028    import com.liferay.portal.upload.UploadServletRequestImpl;
029    import com.liferay.portal.util.PortalUtil;
030    import com.liferay.portal.util.WebKeys;
031    
032    import java.io.Serializable;
033    
034    import java.util.Arrays;
035    import java.util.Collections;
036    import java.util.Enumeration;
037    import java.util.HashMap;
038    import java.util.List;
039    import java.util.Map;
040    
041    import javax.servlet.http.Cookie;
042    import javax.servlet.http.HttpServletRequest;
043    import javax.servlet.http.HttpSession;
044    
045    /**
046     * @author Shuyang Zhou
047     */
048    public class SPIAgentRequest extends SPIAgentSerializable {
049    
050            public SPIAgentRequest(HttpServletRequest request) {
051                    cookies = request.getCookies();
052                    distributedRequestAttributes = extractDistributedRequestAttributes(
053                            request, Direction.REQUEST);
054                    headerMap = extractRequestHeaders(request);
055                    parameterMap = request.getParameterMap();
056                    serverName = request.getServerName();
057                    serverPort = request.getServerPort();
058    
059                    String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
060    
061                    if ((contentType != null) &&
062                            contentType.startsWith(ContentTypes.MULTIPART_FORM_DATA)) {
063    
064                            UploadServletRequest uploadServletRequest =
065                                    PortalUtil.getUploadServletRequest(request);
066    
067                            Map<String, FileItem[]> multipartParameterMap =
068                                    uploadServletRequest.getMultipartParameterMap();
069                            Map<String, List<String>> regularParameterMap =
070                                    uploadServletRequest.getRegularParameterMap();
071    
072                            if (!multipartParameterMap.isEmpty()) {
073                                    this.multipartParameterMap = multipartParameterMap;
074                            }
075    
076                            if (!regularParameterMap.isEmpty()) {
077                                    this.regularParameterMap = regularParameterMap;
078                            }
079                    }
080    
081                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
082                            WebKeys.THEME_DISPLAY);
083    
084                    if ((themeDisplay != null) && themeDisplay.isAjax()) {
085                            parameterMap = new HashMap<String, String[]>(parameterMap);
086    
087                            parameterMap.put(
088                                    "portalResiliencyPortletShowFooter",
089                                    new String[] {StringPool.FALSE});
090                    }
091    
092                    HttpSession session = request.getSession();
093    
094                    originalSessionAttributes = extractSessionAttributes(session);
095    
096                    captureThreadLocals();
097            }
098    
099            public Map<String, Serializable> getOriginalSessionAttributes() {
100                    return originalSessionAttributes;
101            }
102    
103            public HttpServletRequest populateRequest(HttpServletRequest request) {
104                    request = new AgentHttpServletRequestWrapper(request);
105    
106                    for (Map.Entry<String, Serializable> entry :
107                                    distributedRequestAttributes.entrySet()) {
108    
109                            request.setAttribute(entry.getKey(), entry.getValue());
110                    }
111    
112                    if ((multipartParameterMap != null) || (regularParameterMap != null)) {
113                            request = new UploadServletRequestImpl(
114                                    request, multipartParameterMap, regularParameterMap);
115                    }
116    
117                    restoreThreadLocals();
118    
119                    return request;
120            }
121    
122            public void populateSessionAttributes(HttpSession httpSession) {
123                    for (Map.Entry<String, Serializable> entry :
124                                    originalSessionAttributes.entrySet()) {
125    
126                            httpSession.setAttribute(entry.getKey(), entry.getValue());
127                    }
128            }
129    
130            @Override
131            public String toString() {
132                    int length = 16 + parameterMap.size() * 4;
133    
134                    if (cookies != null) {
135                            length += cookies.length * 2 - 1;
136                    }
137    
138                    StringBundler sb = new StringBundler(length);
139    
140                    sb.append("{cookies=[");
141    
142                    if (cookies != null) {
143                            for (Cookie cookie : cookies) {
144                                    sb.append(CookieUtil.toString(cookie));
145                                    sb.append(", ");
146                            }
147    
148                            sb.setIndex(sb.index() - 1);
149                    }
150    
151                    sb.append("], distributedRequestAttributes=");
152                    sb.append(distributedRequestAttributes);
153                    sb.append(", _headerMap=");
154                    sb.append(headerMap);
155                    sb.append(", _multipartParameterMap=");
156                    sb.append(multipartParameterMap);
157                    sb.append(", originalSessionAttributes=");
158                    sb.append(originalSessionAttributes);
159                    sb.append(", parameterMap={");
160    
161                    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
162                            sb.append(entry.getKey());
163                            sb.append("=");
164                            sb.append(Arrays.toString(entry.getValue()));
165                            sb.append(", ");
166                    }
167    
168                    sb.setIndex(sb.index() - 1);
169    
170                    sb.append("}, _regularParameterMap=");
171                    sb.append(regularParameterMap);
172                    sb.append(", _serverName=");
173                    sb.append(serverName);
174                    sb.append(", _serverPort=");
175                    sb.append(serverPort);
176                    sb.append("}");
177    
178                    return sb.toString();
179            }
180    
181            protected Cookie[] cookies;
182            protected Map<String, Serializable> distributedRequestAttributes;
183            protected Map<String, List<String>> headerMap;
184            protected Map<String, FileItem[]> multipartParameterMap;
185            protected Map<String, Serializable> originalSessionAttributes;
186            protected Map<String, String[]> parameterMap;
187            protected Map<String, List<String>> regularParameterMap;
188            protected String serverName;
189            protected int serverPort;
190    
191            protected class AgentHttpServletRequestWrapper
192                    extends PersistentHttpServletRequestWrapper {
193    
194                    public AgentHttpServletRequestWrapper(HttpServletRequest request) {
195                            super(request);
196                    }
197    
198                    @Override
199                    public Cookie[] getCookies() {
200                            return cookies;
201                    }
202    
203                    @Override
204                    public String getHeader(String name) {
205                            List<String> values = headerMap.get(name.toLowerCase());
206    
207                            if ((values == null) || values.isEmpty()) {
208                                    return null;
209                            }
210    
211                            return values.get(0);
212                    }
213    
214                    @Override
215                    public Enumeration<String> getHeaderNames() {
216                            return Collections.enumeration(headerMap.keySet());
217                    }
218    
219                    @Override
220                    public Enumeration<String> getHeaders(String name) {
221                            List<String> values = headerMap.get(name.toLowerCase());
222    
223                            if (values == null) {
224                                    values = Collections.emptyList();
225                            }
226    
227                            return Collections.enumeration(values);
228                    }
229    
230                    @Override
231                    public String getParameter(String name) {
232                            String[] values = parameterMap.get(name);
233    
234                            if (ArrayUtil.isNotEmpty(values)) {
235                                    return values[0];
236                            }
237                            else {
238                                    return null;
239                            }
240                    }
241    
242                    @Override
243                    public Map<String, String[]> getParameterMap() {
244                            return parameterMap;
245                    }
246    
247                    @Override
248                    public Enumeration<String> getParameterNames() {
249                            return Collections.enumeration(parameterMap.keySet());
250                    }
251    
252                    @Override
253                    public String[] getParameterValues(String name) {
254                            return parameterMap.get(name);
255                    }
256    
257                    @Override
258                    public String getServerName() {
259                            return serverName;
260                    }
261    
262                    @Override
263                    public int getServerPort() {
264                            return serverPort;
265                    }
266    
267            }
268    
269    }