/* * #! * Ontopia Webed * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * !# */ package net.ontopia.topicmaps.webed.impl.utils; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import net.ontopia.topicmaps.webed.core.FileValueIF; import net.ontopia.utils.URIUtils; import org.apache.commons.fileupload.DefaultFileItemFactory; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUpload; import org.apache.commons.fileupload.FileUploadException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * INTERNAL: Utility class for providing helper methods handling * servlet request parameters (mainly for string manipulation * purposes). */ public final class ReqParamUtils { // initialization of logging facility private static Logger log = LoggerFactory .getLogger(ReqParamUtils.class.getName()); /** * INTERNAL: Generate string which can be used to append to an * URL. Use all request parameter (that are key, value) pairs from * the provided <code>extraReqParams</code> Map object. * * @param charenc the character encoding to use in the URL */ public static final String params2URLQuery(Map extraReqParams, Parameters reqparams, String charenc) throws IOException { StringBuilder urlQuery = new StringBuilder(48); boolean seenFirstPair = false; Iterator it = extraReqParams.keySet().iterator(); while (it.hasNext()) { // first try to lookup if fixed value otherwise get it from request String key = (String) it.next(); String val = (String) extraReqParams.get(key); if (val == null && reqparams != null) val = reqparams.get(key); // URL encode the request parameter value if (val != null) { if (seenFirstPair) urlQuery.append("&"); else seenFirstPair = true; urlQuery.append(key).append("=").append(URIUtils.urlEncode(val, charenc)); } } return urlQuery.toString(); } /** * INTERNAL: Parses the query part of a URL to extract the parameter * names and values. */ public static Map parseURLQuery(String url) { Map params = new HashMap(); // start at beginning of query part, before first param name int ix = 0; while (ix < url.length()) { int start = ix; // scan for end of param name (or url) for (; ix < url.length() && url.charAt(ix) != '='; ix++) ; // does url end at end of param name? int equalsAt = ix; if (url.charAt(ix) != '=') break; // FIXME: ought to report an error here... // scan through param value for (; ix < url.length() && url.charAt(ix) != '&'; ix++) ; params.put(url.substring(start, equalsAt), url.substring(equalsAt + 1, ix)); ix++; } return params; } /** * INTERNAL: Builds the Parameters object from an HttpServletRequest * object. * @since 2.0 */ public static Parameters decodeParameters(HttpServletRequest request, String charenc) throws ServletException, IOException { String ctype = request.getHeader("content-type"); log.debug("Content-type: " + ctype); Parameters params = new Parameters(); if (ctype != null && ctype.startsWith("multipart/form-data")) { // special file upload request, so use FileUpload to decode log.debug("Decoding with FileUpload; charenc="+ charenc); try { FileUpload upload = new FileUpload(new DefaultFileItemFactory()); Iterator iterator = upload.parseRequest(request).iterator(); while (iterator.hasNext()) { FileItem item = (FileItem) iterator.next(); log.debug("Reading: " + item); if (item.isFormField()) { if (charenc != null) params.addParameter(item.getFieldName(), item.getString(charenc)); else params.addParameter(item.getFieldName(), item.getString()); } else params.addParameter(item.getFieldName(), new FileParameter(item)); } } catch (FileUploadException e) { throw new ServletException(e); } } else { // ordinary web request, so retrieve info and stuff into Parameters object log.debug("Normal parameter decode, charenc=" + charenc); if (charenc != null) request.setCharacterEncoding(charenc); Enumeration enumeration = request.getParameterNames(); while (enumeration.hasMoreElements()) { String param = (String) enumeration.nextElement(); params.addParameter(param, request.getParameterValues(param)); } } return params; } // --- Internal helper class for wrapping FileItems /** * INTERNAL: We use this to avoid having other parts of the API * depend on the FileUpload API. */ static class FileParameter implements FileValueIF { private FileItem file; public FileParameter(FileItem file) { this.file = file; } public String getFileName() { return file.getName(); } public InputStream getContents() throws IOException { return file.getInputStream(); } public long getLength() { return file.getSize(); } public String getContentType() { return file.getContentType(); } } }