/******************************************************************************* * Signavio Core Components * Copyright (C) 2012 Signavio GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ /** * */ package com.signavio.platform.filters; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.catalina.util.RequestUtil; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.signavio.platform.exceptions.InputException; import com.signavio.platform.exceptions.RequestException; import com.signavio.platform.servlets.DispatcherServlet; /** * @author Bjoern Wagner * */ public class ParseParametersFilter implements Filter { /* (non-Javadoc) * @see javax.servlet.Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { if (!(req instanceof HttpServletRequest)) { chain.doFilter(req, res); } HttpServletRequest httpReq = (HttpServletRequest) req; Map<String, List<String>> params = new HashMap<String, List<String>>(); parseUriParameters(httpReq, params); parseStreamParameters(httpReq, params); parseRequestParameters(httpReq, params); filterParameters(params); JSONObject jsonParams = parametersToJSONObject(params); httpReq.setAttribute("params", jsonParams); httpReq.setAttribute("javaParams", params); chain.doFilter(httpReq, res); } /* (non-Javadoc) * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) */ public void init(FilterConfig config) throws ServletException { // TODO Auto-generated method stub } /** * Helper method that adds a new parameter to the map * @param params * @param key * @param value */ private void addParameter(Map<String, List<String>> params, String key, String value) { List<String> values = params.get(key); if (values == null) { values = new ArrayList<String>(); params.put(key, values); } values.add(value); } private void parseUriParameters(HttpServletRequest req, Map<String, List<String>> params) { // get parameters form uri after the extension String[] path = DispatcherServlet.parseURL( req.getRequestURI() ); if( path[3] != null && !path[3].equals("") ){ try { addParameter(params, "suffix", URLDecoder.decode( path[3], "utf-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); // ignore exception } } } /** * Read all parameters directly from the input stream. Necessary because parameters are not mapped to the * HttpRequest.getParameter api on PUT requests * @param req * @param params */ private void parseStreamParameters(HttpServletRequest req, Map<String, List<String>> params) { try { String content = this.convertStreamToString(req.getInputStream()); if( content != null && content.length() >= 1 ){ Map<String, String[]> ps = new HashMap<String, String[]>(); RequestUtil.parseParameters(ps, content, "UTF-8"); for (String key : ps.keySet()) { List<String> param = new ArrayList<String>(); for(String value : ps.get(key)) { param.add(value); } params.put(key, param); } } } catch (IOException e) { throw new InputException(e); } } /** * Parse parameters using the HttpRequest API * @param req * @param params */ @SuppressWarnings("unchecked") private void parseRequestParameters(HttpServletRequest req, Map<String, List<String>> params) { // get all parameter and add those to the map Enumeration<String> paramNames = req.getParameterNames(); while( paramNames.hasMoreElements() ){ String key = paramNames.nextElement(); String[] values = req.getParameterValues(key); for (String value : values) { addParameter(params, key, value); } } } /** * Remove code from all parameters except those ending with '_xml' * @param params */ private void filterParameters(Map<String, List<String>> params) { for (String key : params.keySet()) { if (!key.endsWith("_xml")&&!key.endsWith("_json")) { List<String> filteredValues = new ArrayList<String>(); for (String value : params.get(key)) { filteredValues.add(RequestUtil.filter(value)); } params.put(key, filteredValues); } } } /** * Convert map to json object containing strings for single values and a json array * for multiple values * @param params * @return */ private JSONObject parametersToJSONObject(Map<String, List<String>> params) { JSONObject jsonParams = new JSONObject(); for (String key : params.keySet()) { try { if (params.get(key).size() == 1) { jsonParams.put(key, params.get(key).iterator().next()); } else { jsonParams.put(key, new JSONArray(params.get(key))); } } catch(JSONException e) { e.printStackTrace(); // ignore } } return jsonParams; } /** * Helper method. converts request input stream to java string * @param is * @return */ private String convertStreamToString(InputStream is) { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line = null; try { String separator = ""; while ((line = reader.readLine()) != null) { sb.append(separator + line); separator = "\n"; } is.close(); } catch (IOException e) { try { is.close(); } catch (IOException e2) {} throw new RequestException("platform.stream2StringFailed", e); } return sb.toString(); } }