Package org.jasig.portal.url.processing

Source Code of org.jasig.portal.url.processing.ChannelRequestParameterProcessor

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you 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 org.jasig.portal.url.processing;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.apache.commons.io.FileCleaner;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.Constants;
import org.jasig.portal.Errors;
import org.jasig.portal.ExceptionHelper;
import org.jasig.portal.IUserPreferencesManager;
import org.jasig.portal.MultipartDataSource;
import org.jasig.portal.PortalException;
import org.jasig.portal.UPFileSpec;
import org.jasig.portal.UploadStatus;
import org.jasig.portal.layout.IUserLayoutManager;
import org.jasig.portal.portlet.url.IPortletRequestParameterManager;
import org.jasig.portal.url.IWritableHttpServletRequest;
import org.jasig.portal.url.support.IChannelRequestParameterManager;
import org.jasig.portal.user.IUserInstance;
import org.jasig.portal.user.IUserInstanceManager;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsFileUploadSupport;

/**
* Does request parameter processing on any request that does not explicitly target a portlet.
* Takes care of pulling out channel parameters and handling file uploads so the data can be
* passed into the ChannelRuntimeData for the targeted channel.
*
* @author Eric Dalquist
* @version $Revision$
*/
public class ChannelRequestParameterProcessor extends CommonsFileUploadSupport implements IRequestParameterProcessor, DisposableBean {
    public static final String UPLOAD_STATUS = "up_upload_status";
   
    protected final Log logger = LogFactory.getLog(this.getClass());

    private IPortletRequestParameterManager portletRequestParameterManager;
    private IChannelRequestParameterManager channelRequestParameterManager;
    private IUserInstanceManager userInstanceManager;
   
    /**
     * @return the userInstanceManager
     */
    public IUserInstanceManager getUserInstanceManager() {
        return this.userInstanceManager;
    }
    /**
     * @param userInstanceManager the userInstanceManager to set
     */
    @Required
    public void setUserInstanceManager(IUserInstanceManager userInstanceManager) {
        Validate.notNull(userInstanceManager);
        this.userInstanceManager = userInstanceManager;
    }
   
    /**
     * @return the portletRequestParameterManager
     */
    public IPortletRequestParameterManager getPortletRequestParameterManager() {
        return portletRequestParameterManager;
    }
    /**
     * @param portletRequestParameterManager the portletRequestParameterManager to set
     */
    @Required
    public void setPortletRequestParameterManager(IPortletRequestParameterManager portletRequestParameterManager) {
        Validate.notNull(portletRequestParameterManager, "IPortletRequestParameterManager can not be null");
        this.portletRequestParameterManager = portletRequestParameterManager;
    }
    /**
     * @return the channelRequestParameterManager
     */
    public IChannelRequestParameterManager getChannelRequestParameterManager() {
        return channelRequestParameterManager;
    }
    /**
     * @param channelRequestParameterManager the channelRequestParameterManager to set
     */
    @Required
    public void setChannelRequestParameterManager(IChannelRequestParameterManager channelRequestParameterManager) {
        Validate.notNull(channelRequestParameterManager, "IChannelRequestParameterManager can not be null");
        this.channelRequestParameterManager = channelRequestParameterManager;
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.url.processing.IRequestParameterProcessor#processParameters(org.jasig.portal.url.IWritableHttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public boolean processParameters(IWritableHttpServletRequest request, HttpServletResponse response) {
        boolean isPortletRequest = false;
        try {
            //If this is a portlet request don't do any channel parameter processing
            if (this.portletRequestParameterManager.getTargetedPortletWindowId(request) != null) {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Request is targeting a portlet, channel parameter processing will not take place.");
                }
               
                isPortletRequest = true;
            }
        }
        catch (RequestParameterProcessingIncompleteException rppie) {
            //Need to wait for the portlet request processor to complete
            return false;
        }
       
        //Determine the targeted channel
        final String targetChannelId = this.getTargetChannelId(request);
       
        //If no channel is targeted mark the request as such in the manager and return
        if (targetChannelId == null) {
            this.channelRequestParameterManager.setNoChannelParameters(request);
            return true;
        }

        //Map to track channel parameters in
        final Map<String, Object[]> channelParameters = new HashMap<String, Object[]>();
       
        //If it is a portlet request just set the targeted channel id with an empty parameters map
        if (isPortletRequest) {
            this.channelRequestParameterManager.setChannelParameters(request, targetChannelId, channelParameters);
            return true;
        }

        //Do multipart file upload request processing
        if (ServletFileUpload.isMultipartContent(new ServletRequestContext(request))) {
            //Used to communicate to clients of multipart data if the request processing worked correctly
            UploadStatus uploadStatus;
           
            final String encoding = this.determineEncoding(request);
            final FileUpload fileUpload = this.prepareFileUpload(encoding);
            try {
                final List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
                final MultipartParsingResult parsingResult = parseFileItems(fileItems, encoding);
               
                final Map<String, MultipartDataSource[]> multipartDataSources = this.getMultipartDataSources(parsingResult);
                channelParameters.putAll(multipartDataSources);
               
                final Map<String, String[]> multipartParameters = parsingResult.getMultipartParameters();
                channelParameters.putAll(multipartParameters);
               
                uploadStatus = new UploadStatus(UploadStatus.SUCCESS, this.getFileUpload().getFileSizeMax());
            }
            catch (FileUploadException fue) {
                this.logger.warn("Failed to parse multipart upload, processing will continue but not all parameters may be available.", fue);
                uploadStatus = new UploadStatus(UploadStatus.FAILURE, this.getFileUpload().getFileSizeMax());
                ExceptionHelper.genericTopHandler(Errors.bug, fue);
            }
           
            channelParameters.put(UPLOAD_STATUS, new UploadStatus[] { uploadStatus });
        }

        // process parameters on the request object
        final Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames != null && parameterNames.hasMoreElements()) {
            final String parameterName = parameterNames.nextElement();
           
            if (!parameterName.equals("uP_channelTarget") && !parameterName.equals("uP_fname")
                && !parameterName.equals("uP_help_target")
                && !parameterName.equals("uP_about_target")
                && !parameterName.equals("uP_edit_target")
                && !parameterName.equals("uP_detach_target")) {
                final String[] parameterValues = request.getParameterValues(parameterName);
                channelParameters.put(parameterName, parameterValues);
            }
        }

        //Set the parameters on the request
        this.channelRequestParameterManager.setChannelParameters(request, targetChannelId, channelParameters);
       
        //Processing is complete
        return true;
    }
   
    /**
     * Ensures the temp files from uploads are cleaned up correctly.
     *
     * @see org.springframework.beans.factory.DisposableBean#destroy()
     */
    public void destroy() throws Exception {
        FileCleaner.exitWhenFinished();       
    }
   
   
    /**
     * Determine the targeted channel ID for the request.
     *
     * @param request Current request.
     * @return The targeted channel ID, null if no channel is targeted.
     */
    protected String getTargetChannelId(IWritableHttpServletRequest request) {
        String targetChannelId = null;
       
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
        final IUserPreferencesManager userPreferencesManager = userInstance.getPreferencesManager();
        final IUserLayoutManager userLayoutManger = userPreferencesManager.getUserLayoutManager();

        // see if this is targeted at an fname channel. if so then it takes
        // precedence. This is done so that a baseActionURL can be used for
        // the basis of an fname targeted channel with the fname query parm
        // appended to direct all query parms to the fname channel
        final String fname = request.getParameter(Constants.FNAME_PARAM);
        if (fname != null) {
            // get a subscribe id for the fname
            try {
                targetChannelId = userLayoutManger.getSubscribeId(fname);
            }
            catch (PortalException pe) {
                this.logger.error("Unable to get subscribe ID for fname=" + fname, pe);
            }
        }
       
        // check if the uP_channelTarget parameter has been passed
        if (targetChannelId == null) {
            targetChannelId = request.getParameter("uP_channelTarget");
        }
       
        // check if the uP_help_target parameter has been passed       
        if (targetChannelId == null) {
            targetChannelId = request.getParameter("uP_help_target");
        }
       
        // check if the uP_about_target parameter has been passed
        if (targetChannelId == null) {
            targetChannelId = request.getParameter("uP_about_target");
        }       
       
        // check if the uP_edit_target parameter has been passed
        if (targetChannelId == null) {
            targetChannelId = request.getParameter("uP_edit_target");
        }       
       
        // check if the uP_detach_target parameter has been passed
        if (targetChannelId == null) {
            targetChannelId = request.getParameter("uP_detach_target");
        }   
       
        final UPFileSpec upfs = new UPFileSpec(request);
       
        // determine target channel id
        if (targetChannelId == null) {
            targetChannelId = upfs.getTargetNodeId();
        }
       
        // look for detached channel id
        if (targetChannelId == null) {
            final String methodNodeId = upfs.getMethodNodeId();
            if (!UPFileSpec.USER_LAYOUT_ROOT_NODE.equals(methodNodeId)) {
                targetChannelId = methodNodeId;
            }
        }
       
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("targetChannelId='" + targetChannelId + "'.");
        }

        return targetChannelId;
    }
   
    /* (non-Javadoc)
     * @see org.springframework.web.multipart.commons.CommonsFileUploadSupport#newFileUpload(org.apache.commons.fileupload.FileItemFactory)
     */
    @Override
    protected FileUpload newFileUpload(FileItemFactory fileItemFactory) {
        return new ServletFileUpload(fileItemFactory);
    }
   
    /**
     * Determine the encoding for the given request.
     * Can be overridden in subclasses.
     * <p>The default implementation checks the request encoding,
     * falling back to the default encoding specified for this resolver.
     * @param request current HTTP request
     * @return the encoding for the request (never <code>null</code>)
     * @see javax.servlet.ServletRequest#getCharacterEncoding
     * @see #setDefaultEncoding
     */
    protected String determineEncoding(HttpServletRequest request) {
        String encoding = request.getCharacterEncoding();
        if (encoding == null) {
            encoding = getDefaultEncoding();
        }
        return encoding;
    }
   


    /**
     * Convert's Spring's MultipartFile objects to uPortal's MultipartDataSource objects.
     *
     * @param parsingResult The results of the multipart request parsing
     * @return A Map of String parameter names to MultipartDataSource objects
     */
    protected Map<String, MultipartDataSource[]> getMultipartDataSources(final MultipartParsingResult parsingResult) {
        final Map<String, MultipartFile> multipartFiles = parsingResult.getMultipartFiles();
       
        final Map<String, MultipartDataSource[]> multipartDataSources = new HashMap<String, MultipartDataSource[]>(multipartFiles.size());
        for (final Map.Entry<String, MultipartFile> multipartFileEntry : multipartFiles.entrySet()) {
            final MultipartFile multipartFile = multipartFileEntry.getValue();
           
            if (StringUtils.isNotEmpty(multipartFile.getOriginalFilename())) {
                final MultipartDataSource multipartDataSource = new MultipartDataSource(multipartFile);
                multipartDataSources.put(multipartFileEntry.getKey(), new MultipartDataSource[] { multipartDataSource });
            }
        }
       
        return multipartDataSources;
    }
}
TOP

Related Classes of org.jasig.portal.url.processing.ChannelRequestParameterProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.