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