001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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 */
016package org.kuali.rice.edl.impl;
017
018import java.io.UnsupportedEncodingException;
019import java.util.ArrayList;
020import java.util.Enumeration;
021import java.util.HashMap;
022import java.util.Iterator;
023import java.util.List;
024import java.util.Map;
025
026import javax.servlet.http.HttpServletRequest;
027
028import org.apache.commons.fileupload.FileItem;
029import org.apache.commons.fileupload.FileUploadException;
030import org.apache.commons.fileupload.disk.DiskFileItemFactory;
031import org.apache.commons.fileupload.servlet.ServletFileUpload;
032import org.apache.commons.lang.ArrayUtils;
033import org.kuali.rice.kew.api.WorkflowRuntimeException;
034
035
036/**
037 * An abstraction that allows for switching between multipart form requests and normal requests when getting
038 * request params
039 * 
040 * @author Kuali Rice Team (rice.collab@kuali.org)
041 *
042 */
043public class RequestParser {
044
045        private static final String PARSED_MULTI_REQUEST_KEY = "__parsedRequestStruct";
046        private static final String UPLOADED_FILES_KEY = "__uploadedFiles";
047        
048        public static final String WORKFLOW_DOCUMENT_SESSION_KEY = "workflowDocument";
049        public static final String GLOBAL_ERRORS_KEY = "org.kuali.rice.edl.impl.GlobalErrors";
050        public static final String GLOBAL_MESSAGES_KEY = "org.kuali.rice.edl.impl.GlobalMessages";
051        public static final String GLOBAL_FIELD_ERRORS_KEY = "org.kuali.rice.edl.impl.GlobalFieldErrors";
052        
053        private HttpServletRequest request;
054        private Map<String, String[]> additionalParameters = new HashMap<String, String[]>();
055        
056        public RequestParser(HttpServletRequest request) {
057                this.request = request;
058                // setup empty List of errors and messages
059                request.setAttribute(GLOBAL_ERRORS_KEY, new ArrayList());
060                request.setAttribute(GLOBAL_MESSAGES_KEY, new ArrayList());
061                request.setAttribute(GLOBAL_FIELD_ERRORS_KEY, new HashMap<String, String>());
062        }
063
064        private static void parseRequest(HttpServletRequest request) {
065                if (request.getAttribute(PARSED_MULTI_REQUEST_KEY) != null) {
066                        return;
067                }
068                
069                Map requestParams = new HashMap();
070                request.setAttribute(PARSED_MULTI_REQUEST_KEY, requestParams);
071                
072                DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
073                diskFileItemFactory.setSizeThreshold(100);
074                ServletFileUpload upload = new ServletFileUpload(diskFileItemFactory);
075                
076                List items = null;
077                try {
078                        items = upload.parseRequest(request);   
079                } catch (FileUploadException fue) {
080                        throw new WorkflowRuntimeException(fue);
081                }
082                
083                Iterator iter = items.iterator();
084                while (iter.hasNext()) {
085                        
086                        try {
087                                FileItem item = (FileItem) iter.next();
088                                if (item.isFormField()) {
089                                        String fieldName = item.getFieldName();
090                                        String fieldValue = item.getString("utf-8");
091                                        String[] paramVals = null;
092                                        if (requestParams.containsKey(fieldName)) {
093                                                paramVals = (String[])requestParams.get(fieldName);
094                                                paramVals = (String[]) ArrayUtils.add(paramVals, fieldValue);
095                                        } else {
096                                                paramVals = new String[1];
097                                                paramVals[0] = fieldValue;
098                                        }
099                                        requestParams.put(fieldName, paramVals);
100                                } else {
101                                        List uploadedFiles = (List)request.getAttribute(UPLOADED_FILES_KEY);
102                                        if (uploadedFiles == null) {
103                                                uploadedFiles = new ArrayList();
104                                                request.setAttribute(UPLOADED_FILES_KEY, uploadedFiles);
105                                        }
106                                        uploadedFiles.add(item);
107                                }
108                        } catch (UnsupportedEncodingException e) {
109                                throw new WorkflowRuntimeException(e);
110                        }
111                }
112        }
113        
114        public String[] getParameterValues(String paramName) {
115                boolean isMultipart = ServletFileUpload.isMultipartContent(this.getRequest());
116            String[] params = null;
117            if (isMultipart) {
118                parseRequest(this.getRequest());
119                params = (String[]) ((Map)request.getAttribute(PARSED_MULTI_REQUEST_KEY)).get(paramName);
120            } else {
121                params = this.getRequest().getParameterValues(paramName);
122            }
123            if (params == null) {
124                params = additionalParameters.get(paramName);
125            }
126            return params;
127        }
128        
129        public void setAttribute(String name, Object value) {
130                this.getRequest().setAttribute(name, value);
131        }
132        
133        public Object getAttribute(String name) {
134                return this.getRequest().getAttribute(name); 
135        }
136        
137        public String getParameterValue(String paramName) {
138                String[] paramVals = getParameterValues(paramName);
139                if (paramVals != null) {
140                        return paramVals[0];
141                }
142                return null;
143        }
144        
145        public void setParameterValue(String paramName, String paramValue) {
146            additionalParameters.put(paramName, new String[] { paramValue });
147        }
148        
149        public void setParameterValue(String paramName, String[] paramValue) {
150            additionalParameters.put(paramName, paramValue);
151        }
152        
153        public List<String> getParameterNames() {
154            List<String> names = new ArrayList<String>();
155            boolean isMultipart = ServletFileUpload.isMultipartContent(this.getRequest());
156            if (isMultipart) {
157                parseRequest(this.getRequest());
158                Map paramMap = ((Map)request.getAttribute(PARSED_MULTI_REQUEST_KEY));
159                for (Iterator iterator = paramMap.keySet().iterator(); iterator.hasNext();) {
160                    String parameterName = (String)iterator.next();
161                    names.add(parameterName);
162                }
163            } else { 
164                Enumeration<String> nameEnum = getRequest().getParameterNames();
165                while (nameEnum.hasMoreElements()) {
166                    names.add(nameEnum.nextElement());
167                }
168            }
169            return names;
170        }
171
172        public void setRequest(HttpServletRequest request) {
173                this.request = request;
174        }
175        
176        public HttpServletRequest getRequest() {
177                return request;
178        }
179
180        public List getUploadList() {
181                return (List) request.getAttribute(UPLOADED_FILES_KEY);
182        }
183}