org.opensubsystems.core.util.servlet.WebParamUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.opensubsystems.core.util.servlet.WebParamUtils.java

Source

/*
 * Copyright (C) 2003 - 2014 OpenSubsystems.com/net/org and its owners. All rights reserved.
 * 
 * This file is part of OpenSubsystems.
 *
 * OpenSubsystems is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */

package org.opensubsystems.core.util.servlet;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.FileCleanerCleanup;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileCleaningTracker;
import org.opensubsystems.core.error.OSSInvalidDataException;
import org.opensubsystems.core.util.Config;
import org.opensubsystems.core.util.FileUtils;
import org.opensubsystems.core.util.GlobalConstants;
import org.opensubsystems.core.util.Log;
import org.opensubsystems.core.util.OSSObject;
import org.opensubsystems.core.util.PropertyUtils;
import org.opensubsystems.core.util.TwoElementStruct;

/**
 * Collection of useful methods to work with servlet parameters.
 *
 * @author bastafidli
 */
public final class WebParamUtils extends OSSObject {
    // Configuration settings ///////////////////////////////////////////////////

    /** 
     * Name of the property to specify maximal size of files that can be uploaded.
     * @see #REQUEST_UPLOAD_MAX_SIZE_DEFAULT
     */
    public static final String REQUEST_UPLOAD_MAX_SIZE = "oss.upload.max.size";

    /**
     * Name of the property to specify threshold for uploaded files so that if the
     * files are smaller than this value, they will be kept in memory.
     * @see #REQUEST_UPLOAD_MEMORY_THRESHOLD_DEFAULT
     */
    public static final String REQUEST_UPLOAD_MEMORY_THRESHOLD = "oss.upload.memory.threshold";

    // Constants ////////////////////////////////////////////////////////////////

    /**
     * Default value for the REQUEST_UPLOAD_MEMORY_THRESHOLD.
     * @see #REQUEST_UPLOAD_MAX_SIZE
     */
    public static final int REQUEST_UPLOAD_MAX_SIZE_DEFAULT = 1000000;

    /**
     * Default value for the REQUEST_UPLOAD_MEMORY_THRESHOLD.
     * @see #REQUEST_UPLOAD_MEMORY_THRESHOLD
     */
    public static final int REQUEST_UPLOAD_MEMORY_THRESHOLD_DEFAULT = 4096;

    /**
     * Name of attribute used to store parsed parameters passed in via multipart 
     * request keyed by the name of the parameter
     */
    public static final String REQUEST_PARAMS_MAP = "ossrequestparamsmap";

    // Cached values ////////////////////////////////////////////////////////////

    /**
     * Logger for this class
     */
    private static Logger s_logger = Log.getInstance(WebParamUtils.class);

    // Constructors /////////////////////////////////////////////////////////////

    /** 
     * Private constructor since this class cannot be instantiated
     */
    private WebParamUtils() {
        // Do nothing
    }

    // Logic ////////////////////////////////////////////////////////////////////

    /**
     * Get parameter as a String and if it is not present provide user friendly 
     * error message.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @param strDisplayName - display name used for this parameter
     * @param bRequired - is this value required or not
     * @return String - value of the parameter
     * @throws OSSInvalidDataException
     */
    public static String getParameterAsString(String strLogPrefix, HttpServletRequest request, String strParamName,
            String strDisplayName, boolean bRequired) throws OSSInvalidDataException {
        String strValue;

        strValue = getParameter(strLogPrefix, request, strParamName);
        if (strValue == null) {
            // Not a user error, use strParamName
            throw new OSSInvalidDataException(strLogPrefix, strParamName + " parameter is missing in the request");
        } else if ((bRequired) && (strValue.trim().length() == 0)) {
            throw new OSSInvalidDataException(strLogPrefix, strDisplayName + " wasn't specified");
        }

        return strValue;
    }

    /**
     * Get parameter as a Integer.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @return Integer - value of the parameter or null if it doesn't exist
     * @throws OSSInvalidDataException
     */
    public static Integer getParameterAsInteger(String strLogPrefix, HttpServletRequest request,
            String strParamName) throws OSSInvalidDataException {
        String strValue;
        Integer iValue = null;

        strValue = getParameter(strLogPrefix, request, strParamName);
        if ((strValue != null) && (strValue.trim().length() != 0)) {
            try {
                iValue = Integer.parseInt(strValue);
            } catch (NumberFormatException nfeExc) {
                throw new OSSInvalidDataException(strLogPrefix,
                        "Incorrecly formatted value of parameter " + strParamName);
            }
        }

        return iValue;
    }

    /**
     * Get parameter as a Integer and if it is not present provide user friendly 
     * error message.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @param strDisplayName - display name used for this parameter
     * @param bRequired - is this value required or not
     * @return Integer - value of the parameter
     * @throws OSSInvalidDataException
     */
    public static Integer getParameterAsInteger(String strLogPrefix, HttpServletRequest request,
            String strParamName, String strDisplayName, boolean bRequired) throws OSSInvalidDataException {
        String strValue;
        Integer iValue = null;

        strValue = getParameter(strLogPrefix, request, strParamName);
        if (strValue == null) {
            // Not a user error, use strParamName
            throw new OSSInvalidDataException(strLogPrefix, strParamName + " parameter is missing in the request");
        } else {
            try {
                iValue = Integer.parseInt(strValue);
            } catch (NumberFormatException nfeExc) {
                // Not a user error, use strParamName
                throw new OSSInvalidDataException(strLogPrefix,
                        strParamName + " parameter is not valid number: " + strValue);
            }
            // TODO: Verify if it is a valid number, e.g. from a list of valid
            // number and if it is not use the strDisplayName to provide user 
            // friendly message/
        }

        return iValue;
    }

    /**
     * Get parameter as a Long.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @return Long - value of the parameter or null if it doesn't exist
     * @throws OSSInvalidDataException
     */
    public static Long getParameterAsLong(String strLogPrefix, HttpServletRequest request, String strParamName)
            throws OSSInvalidDataException {
        String strValue;
        Long lValue = null;

        strValue = getParameter(strLogPrefix, request, strParamName);
        if ((strValue != null) && (strValue.trim().length() != 0)) {
            try {
                lValue = Long.parseLong(strValue);
            } catch (NumberFormatException nfeExc) {
                throw new OSSInvalidDataException(strLogPrefix,
                        "Incorrecly formatted value of parameter " + strParamName);
            }
        }

        return lValue;
    }

    /**
     * Get parameter as a Long and if it is not present provide user friendly 
     * error message.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @param strDisplayName - display name used for this parameter
     * @param bRequired - is this value required or not
     * @return Long - value of the parameter
     * @throws OSSInvalidDataException
     */
    public static Long getParameterAsLong(String strLogPrefix, HttpServletRequest request, String strParamName,
            String strDisplayName, boolean bRequired) throws OSSInvalidDataException {
        String strValue;
        Long lValue = null;

        strValue = getParameter(strLogPrefix, request, strParamName);
        if (strValue == null) {
            // Not a user error, use strParamName
            throw new OSSInvalidDataException(strLogPrefix, strParamName + " parameter is missing in the request");
        } else {
            try {
                lValue = Long.parseLong(strValue);
            } catch (NumberFormatException nfeExc) {
                // Not a user error, use strParamName
                throw new OSSInvalidDataException(strLogPrefix,
                        strParamName + " parameter is not valid number: " + strValue);
            }
            // TODO: Verify if it is a valid number, e.g. from a list of valid
            // number and if it is not use the strDisplayName to provide user 
            // friendly message/
        }

        return lValue;
    }

    /**
     * Get parameter as a Collection of Long, Values and if it is not present 
     * provide user friendly  error message.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @param strDisplayName - display name used for this parameter
     * @param bRequired - is this value required or not
     * @return Collection<Long> - value of the parameter
     * @throws OSSInvalidDataException
     */
    public static Collection<Long> getParameterAsLongCollection(String strLogPrefix, HttpServletRequest request,
            String strParamName, String strDisplayName, boolean bRequired) throws OSSInvalidDataException {
        String[] arValue;
        Collection<Long> colValues = null;

        arValue = getParameterValues(strLogPrefix, request, strParamName);
        if (arValue == null) {
            // Not a user error, use strParamName
            throw new OSSInvalidDataException(strLogPrefix, strParamName + " parameter is missing in the request");
        } else if (arValue.length == 0) {
            // Not a user error, use strParamName
            throw new OSSInvalidDataException(strLogPrefix, strParamName + " parameter contains no values.");
        } else {
            Long lValue = null;
            colValues = new ArrayList<>(arValue.length);

            for (String strValue : arValue) {
                try {
                    lValue = Long.parseLong(strValue);
                    colValues.add(lValue);
                } catch (NumberFormatException nfeExc) {
                    // Not a user error, use strParamName
                    throw new OSSInvalidDataException(strLogPrefix,
                            strParamName + " parameter is not valid number: " + strValue);
                }
                // TODO: Verify if it is a valid number, e.g. from a list of valid
                // number and if it is not use the strDisplayName to provide user 
                // friendly message/
            }
        }

        return colValues;
    }

    /**
     * Get parameter as a Boolean and if it is not present provide user friendly 
     * error message.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @param strDisplayName - display name used for this parameter
     * @param bRequired - is this value required or not
     * @return Boolean - value of the parameter
     * @throws OSSInvalidDataException
     */
    public static Boolean getParameterAsBoolean(String strLogPrefix, HttpServletRequest request,
            String strParamName, String strDisplayName, boolean bRequired) throws OSSInvalidDataException {
        String strValue;
        Boolean bValue = null;

        strValue = getParameter(strLogPrefix, request, strParamName);
        if (strValue == null) {
            // Not a user error, use strParamName
            throw new OSSInvalidDataException(strLogPrefix, strParamName + " parameter is missing in the request");
        } else {
            bValue = Boolean.parseBoolean(strValue);

            // TODO: Verify if it is a valid boolean, e.g. from a list of valid
            // booleans and if it is not use the strDisplayName to provide user 
            // friendly message/
        }

        return bValue;
    }

    /**
     * Get parameter as a List of Strings.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @param bFilterEmptyStrings - if true then empty strings will be removed
     * @return Long - value of the parameter or null if it doesn't exist
     * @throws OSSInvalidDataException
     */
    public static List<String> getParameterAsList(String strLogPrefix, HttpServletRequest request,
            String strParamName, boolean bFilterEmptyStrings) throws OSSInvalidDataException {
        String[] strValues;
        List<String> lstValues = null;

        strValues = getParameterValues(strLogPrefix, request, strParamName);
        if (strValues != null) {
            lstValues = Arrays.asList(strValues);
            if (bFilterEmptyStrings) {
                // The above list is read only so we need to reinitialize it
                lstValues = new ArrayList<>(lstValues);
                for (Iterator<String> values = lstValues.iterator(); values.hasNext();) {
                    if (values.next().trim().length() == 0) {
                        values.remove();
                    }
                }
            }
        }

        return lstValues;
    }

    /**
     * Get parameter as a file stored on a disk and if it is not present provide 
     * user friendly error message.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @param strDisplayName - display name used for this parameter
     * @param bRequired - is this value required or not
     * @return File - value of the parameter
     * @throws OSSInvalidDataException
     */
    public static File getParameterAsDiskFile(String strLogPrefix, HttpServletRequest request, String strParamName,
            String strDisplayName, boolean bRequired) throws OSSInvalidDataException {
        File fileValue;
        FileItem uploadedFile;
        Object temp;
        Map<String, FileItem> mpFiles;
        TwoElementStruct<Map<String, Object>, Map<String, FileItem>> params;

        params = getMultipartParameters(strLogPrefix, request);

        mpFiles = params.getSecond();
        uploadedFile = mpFiles.get(strParamName);

        if (uploadedFile == null) {
            if (bRequired) {
                throw new OSSInvalidDataException(strLogPrefix, strDisplayName + " wasn't specified");
            }
            fileValue = null;
        } else {
            // TODO: Improve: Consider calling 
            // FileUtils.createTemporarySubdirectory
            // as done in legacy Formature.DocumentTemplateServlet.getFormToProcess
            // to store the temporary files per session and request
            String strTempDir = FileUtils.getTemporaryDirectory();

            try {
                fileValue = File.createTempFile("oss-", ".upload", new File(strTempDir));
                try {
                    uploadedFile.write(fileValue);
                } catch (Exception exc) {
                    throw new OSSInvalidDataException(strLogPrefix, "Unable to save the uploaded file to disk.",
                            exc);
                }
            } catch (IOException exc) {
                throw new OSSInvalidDataException(strLogPrefix,
                        "Unable to generate temporary file to save the uploaded" + " file to disk.", exc);
            }
        }

        return fileValue;
    }

    /**
     * Get single parameter value correctly handling regular and multipart requests.
     * Returns the value of a request parameter as a String, or null if the parameter 
     * does not exist. Request parameters are extra information sent with the request. 
     * For HTTP servlets, parameters are contained in the query string or posted 
     * form data. You should only use this method when you are sure the parameter 
     * has only one value. If the parameter might have more than one value, use 
     * getParameterValues(java.lang.String). If you use this method with a 
     * multivalued parameter, the value returned is equal to the first value in 
     * the array returned by getParameterValues.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @return String - a single (first) value of the parameter or null if the 
     *                  parameter values were not specified
     * @throws OSSInvalidDataException - an error has occurred
     */
    public static String getParameter(String strLogPrefix, HttpServletRequest request, String strParamName)
            throws OSSInvalidDataException {
        String strValue;
        boolean bIsMultipart = ServletFileUpload.isMultipartContent(request);

        if (!bIsMultipart) {
            strValue = request.getParameter(strParamName);
        } else {
            Object temp;

            temp = getMultipartParameterValueAsObject(strLogPrefix, request, strParamName);
            if (temp != null) {
                if (temp instanceof String) {
                    strValue = (String) temp;
                } else {
                    List<String> lstValues;

                    lstValues = (List<String>) temp;
                    strValue = lstValues.get(0);
                }
            } else {
                strValue = null;
            }
        }

        return strValue;
    }

    /**
     * Get all parameter value correctly handling regular and multipart requests.
     * Returns an array of String objects containing all of the values the given 
     * request parameter has, or null if the parameter does not exist. If the 
     * parameter has a single value, the array has a length of 1.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @return String[] - an array of String objects containing the parameter's 
     *                    values or null if the parameter values were not specified
     * @throws OSSInvalidDataException - an error has occurred
     */
    public static String[] getParameterValues(String strLogPrefix, HttpServletRequest request, String strParamName)
            throws OSSInvalidDataException {
        String[] arValues;
        boolean bIsMultipart = ServletFileUpload.isMultipartContent(request);

        if (!bIsMultipart) {
            arValues = request.getParameterValues(strParamName);
        } else {
            Object temp;

            temp = getMultipartParameterValueAsObject(strLogPrefix, request, strParamName);
            if (temp != null) {
                if (temp instanceof String) {
                    arValues = new String[1];
                    arValues[0] = (String) temp;
                } else {
                    List<String> lstValues;

                    lstValues = (List<String>) temp;
                    arValues = lstValues.toArray(new String[lstValues.size()]);
                }
            } else {
                arValues = null;
            }
        }

        return arValues;
    }

    /**
     * Get map of all parameters correctly handling regular and multipart requests.
     * Returns a java.util.Map of the parameters of this request. Request 
     * parameters are extra information sent with the request. For HTTP servlets, 
     * parameters are contained in the query string or posted form data.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @return Map<String, String[]> - an immutable java.util.Map containing 
     *                                 parameter names as keys and parameter 
     *                                 values as map values. The keys in the 
     *                                 parameter map are of type String. The 
     *                                 values in the parameter map are of type 
     *                                 String array.
     * @throws OSSInvalidDataException - an error has occurred
     */
    public static Map<String, String[]> getParameterMap(String strLogPrefix, HttpServletRequest request)
            throws OSSInvalidDataException {
        Map<String, String[]> mpParamMap;
        boolean bIsMultipart;

        bIsMultipart = ServletFileUpload.isMultipartContent(request);
        if (!bIsMultipart) {
            mpParamMap = request.getParameterMap();
        } else {
            String[] arValues;
            Object temp;
            Map<String, Object> mpParams;
            TwoElementStruct<Map<String, Object>, Map<String, FileItem>> params;

            params = getMultipartParameters(strLogPrefix, request);
            mpParams = params.getFirst();
            mpParamMap = new HashMap(mpParams.size());

            for (Map.Entry<String, Object> entry : mpParams.entrySet()) {
                temp = entry.getValue();
                if (temp != null) {
                    if (temp instanceof String) {
                        arValues = new String[1];
                        arValues[0] = (String) temp;
                    } else {
                        List<String> lstValues;

                        lstValues = (List<String>) temp;
                        arValues = lstValues.toArray(new String[lstValues.size()]);
                    }
                } else {
                    arValues = null;
                }
                mpParamMap.put(entry.getKey(), arValues);
            }
        }

        return mpParamMap;
    }

    /**
     * Parse multipart request and separate regular parameters and files. The
     * files names are also stored as values of the parameters that are used to 
     * upload them.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @return TwoElementStruct<Map<String, String>, Map<String, FileItem>> - the
     *                  first element is map of parameter names and their values. 
     *                  For uploaded files the files names are also stored here as 
     *                  values of the parameters that are used to upload them.
     *                  If there is only one value of the parameter then the value
     *                  is stored directly as String. If there are multiple values
     *                  then the values are stored as List<String>.
     *                  The second element is map of parameter names and the files
     *                  that are uploaded as these parameters.
     * @throws FileUploadException - an error has occurred
     */
    public static TwoElementStruct<Map<String, Object>, Map<String, FileItem>> parseMultipartRequest(
            String strLogPrefix, HttpServletRequest request) throws FileUploadException {
        if (GlobalConstants.ERROR_CHECKING) {
            assert ServletFileUpload.isMultipartContent(request) : "Specified request is not multipart";
        }

        TwoElementStruct<Map<String, Object>, Map<String, FileItem>> returnValue;
        FileCleaningTracker fileCleaningTracker;
        String strTempDir;
        DiskFileItemFactory factory;
        Properties prpSettings;
        int iMaxInMemorySize;
        int iMaxSize;
        ServletFileUpload upload;
        List<FileItem> items;

        // TODO: Improve: Consider calling 
        // FileUtils.createTemporarySubdirectory
        // as done in legacy Formature.DocumentTemplateServlet.getFormToProcess
        // to store the temporary files per session and request
        strTempDir = FileUtils.getTemporaryDirectory();

        prpSettings = Config.getInstance().getProperties();
        iMaxInMemorySize = PropertyUtils.getIntPropertyInRange(prpSettings, REQUEST_UPLOAD_MEMORY_THRESHOLD,
                REQUEST_UPLOAD_MEMORY_THRESHOLD_DEFAULT, "Maximal size of uploaded file that is kept in memory", 1, // 0 is allowed 
                Integer.MAX_VALUE);
        iMaxSize = PropertyUtils.getIntPropertyInRange(prpSettings, REQUEST_UPLOAD_MAX_SIZE,
                REQUEST_UPLOAD_MAX_SIZE_DEFAULT, "Maximal size of uploaded file", 1, // 0 is allowed 
                Integer.MAX_VALUE);

        fileCleaningTracker = FileCleanerCleanup.getFileCleaningTracker(request.getServletContext());

        // Create a factory for disk-based file items
        factory = new DiskFileItemFactory();
        factory.setFileCleaningTracker(fileCleaningTracker);
        // Set factory constraints
        factory.setSizeThreshold(iMaxInMemorySize);
        factory.setRepository(new File(strTempDir));

        // Create a new file upload handler
        upload = new ServletFileUpload(factory);
        // Set overall request size constraint
        upload.setSizeMax(iMaxSize);

        // Parse the request
        items = upload.parseRequest(request);
        if ((items != null) && (!items.isEmpty())) {
            Map mpParams;
            Map mpFiles;
            String strParamName;
            String strValue;
            Object temp;
            List<String> lstValues;

            mpParams = new HashMap(items.size());
            mpFiles = new HashMap();

            returnValue = new TwoElementStruct(mpParams, mpFiles);
            for (FileItem item : items) {
                strParamName = item.getFieldName();
                if (item.isFormField()) {
                    strValue = item.getString();
                } else {
                    strValue = item.getName();
                    mpFiles.put(strParamName, item);
                }

                temp = mpParams.put(strParamName, strValue);
                if (temp != null) {
                    // There was already an value so convert it to list of values
                    if (temp instanceof String) {
                        // There are currently exactly two values
                        lstValues = new ArrayList<>();
                        lstValues.add((String) temp);
                        mpParams.put(strParamName, lstValues);
                    } else {
                        // There are currently more than two values
                        lstValues = (List<String>) temp;
                    }
                    lstValues.add(strValue);
                }
            }
        } else {
            returnValue = new TwoElementStruct(Collections.emptyMap(), Collections.emptyMap());
        }

        return returnValue;
    }

    // Helper methods ///////////////////////////////////////////////////////////

    /**
     * Get all parameter value correctly handling regular and multipart requests.
     * Returns Object that represents either a single String value of the parameter 
     * or an array of String objects containing all of the values the given 
     * request parameter has, or null if the parameter does not exist. If the 
     * parameter has a single value, the array has a length of 1.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @param strParamName  - parameter name to get
     * @return Object - an array of String objects or a String containing the 
     *                  parameter's values or null if the parameter values were 
     *                  not specified
     * @throws OSSInvalidDataException - an error has occurred
     */
    protected static Object getMultipartParameterValueAsObject(String strLogPrefix, HttpServletRequest request,
            String strParamName) throws OSSInvalidDataException {
        Object temp;
        Map<String, Object> mpParams;
        TwoElementStruct<Map<String, Object>, Map<String, FileItem>> params;

        params = getMultipartParameters(strLogPrefix, request);
        mpParams = params.getFirst();
        temp = mpParams.get(strParamName);

        return temp;
    }

    /**
     * Get map of parsed multipart parameters.
     * 
     * @param strLogPrefix - log prefix used for all log output to tie together
     *                       the same invocations
     * @param request - request to get parameter from
     * @return TwoElementStruct<Map<String, String>, Map<String, FileItem>> - the
     *                  first element is map of parameter names and their values. 
     *                  For uploaded files the files names are also stored here as 
     *                  values of the parameters that are used to upload them.
     *                  If there is only one value of the parameter then the value
     *                  is stored directly as String. If there are multiple values
     *                  then the values are stored as List<String>.
     *                  The second element is map of parameter names and the files
     *                  that are uploaded as these parameters.
     * @throws OSSInvalidDataException - an error has occurred
     */
    protected static TwoElementStruct<Map<String, Object>, Map<String, FileItem>> getMultipartParameters(
            String strLogPrefix, HttpServletRequest request) throws OSSInvalidDataException {
        Object temp;
        Map<String, Object> mpParams;
        TwoElementStruct<Map<String, Object>, Map<String, FileItem>> params;

        temp = request.getAttribute(REQUEST_PARAMS_MAP);
        if (temp == null) {
            try {
                params = parseMultipartRequest(strLogPrefix, request);
            } catch (FileUploadException exc) {
                throw new OSSInvalidDataException(strLogPrefix, "Cannot parse multipart request", exc);
            }
            request.setAttribute(REQUEST_PARAMS_MAP, params);
        } else {
            params = (TwoElementStruct<Map<String, Object>, Map<String, FileItem>>) temp;
        }

        return params;
    }
}