Example usage for javax.servlet.http HttpServletRequest removeAttribute

List of usage examples for javax.servlet.http HttpServletRequest removeAttribute

Introduction

In this page you can find the example usage for javax.servlet.http HttpServletRequest removeAttribute.

Prototype

public void removeAttribute(String name);

Source Link

Document

Removes an attribute from this request.

Usage

From source file:org.jasig.portal.url.UrlSyntaxProviderImpl.java

@Override
public IPortalRequestInfo getPortalRequestInfo(HttpServletRequest request) {
    request = this.portalRequestUtils.getOriginalPortalRequest(request);
    final IPortalRequestInfo cachedPortalRequestInfo = (IPortalRequestInfo) request
            .getAttribute(PORTAL_REQUEST_INFO_ATTR);
    if (cachedPortalRequestInfo != null) {
        if (logger.isDebugEnabled()) {
            logger.debug("short-circuit: found portalRequestInfo within request attributes");
        }/*from  www . j a  va 2s .  co  m*/
        return cachedPortalRequestInfo;
    }

    synchronized (PortalWebUtils.getRequestAttributeMutex(request)) {
        // set a flag to say this request is currently being parsed
        final Boolean inProgressAttr = (Boolean) request.getAttribute(PORTAL_REQUEST_PARSING_IN_PROGRESS_ATTR);
        if (inProgressAttr != null && inProgressAttr) {
            if (logger.isDebugEnabled()) {
                logger.warn("Portal request info parsing already in progress, returning null");
            }
            return null;
        }
        request.setAttribute(PORTAL_REQUEST_PARSING_IN_PROGRESS_ATTR, Boolean.TRUE);
    }

    try {
        //Clone the parameter map so data can be removed from it as it is parsed to help determine what to do with non-namespaced parameters
        final Map<String, String[]> parameterMap = new ParameterMap(request.getParameterMap());

        final String requestPath = this.urlPathHelper.getPathWithinApplication(request);

        if (LEGACY_URL_PATHS.contains(requestPath)) {
            return parseLegacyPortalUrl(request, parameterMap);
        }

        final IUrlNodeSyntaxHelper urlNodeSyntaxHelper = this.urlNodeSyntaxHelperRegistry
                .getCurrentUrlNodeSyntaxHelper(request);

        final PortalRequestInfoImpl portalRequestInfo = new PortalRequestInfoImpl();
        IPortletWindowId targetedPortletWindowId = null;
        PortletRequestInfoImpl targetedPortletRequestInfo = null;

        final String[] requestPathParts = SLASH_PATTERN.split(requestPath);

        UrlState requestedUrlState = null;
        ParseStep parseStep = ParseStep.FOLDER;
        for (int pathPartIndex = 0; pathPartIndex < requestPathParts.length; pathPartIndex++) {
            String pathPart = requestPathParts[pathPartIndex];
            if (StringUtils.isEmpty(pathPart)) {
                continue;
            }

            switch (parseStep) {
            case FOLDER: {
                parseStep = ParseStep.PORTLET;

                if (FOLDER_PATH_PREFIX.equals(pathPart)) {
                    //Skip adding the prefix to the folders deque
                    pathPartIndex++;

                    final LinkedList<String> folders = new LinkedList<String>();
                    for (; pathPartIndex < requestPathParts.length; pathPartIndex++) {
                        pathPart = requestPathParts[pathPartIndex];

                        //Found the portlet part of the path, step back one and finish folder parsing
                        if (PORTLET_PATH_PREFIX.equals(pathPart)) {
                            pathPartIndex--;
                            break;
                        }
                        //Found the end of the path, step back one, check for state and finish folder parsing
                        else if (pathPart.endsWith(REQUEST_TYPE_SUFFIX)) {
                            pathPartIndex--;
                            pathPart = requestPathParts[pathPartIndex];

                            //If a state was added to the folder list remove it and step back one so other code can handle it
                            if (UrlState.valueOfIngoreCase(pathPart, null) != null) {
                                folders.removeLast();
                                pathPartIndex--;
                            }
                            break;
                        }

                        folders.add(pathPart);
                    }

                    if (folders.size() > 0) {
                        final String targetedLayoutNodeId = urlNodeSyntaxHelper
                                .getLayoutNodeForFolderNames(request, folders);
                        portalRequestInfo.setTargetedLayoutNodeId(targetedLayoutNodeId);
                    }
                    break;
                }
            }
            case PORTLET: {
                parseStep = ParseStep.STATE;

                final String targetedLayoutNodeId = portalRequestInfo.getTargetedLayoutNodeId();

                if (PORTLET_PATH_PREFIX.equals(pathPart)) {
                    if (++pathPartIndex < requestPathParts.length) {
                        pathPart = requestPathParts[pathPartIndex];

                        targetedPortletWindowId = urlNodeSyntaxHelper.getPortletForFolderName(request,
                                targetedLayoutNodeId, pathPart);
                    }

                    break;
                }

                //See if a portlet was targeted by parameter  
                final String[] targetedPortletIds = parameterMap.remove(PARAM_TARGET_PORTLET);
                if (targetedPortletIds != null && targetedPortletIds.length > 0) {
                    final String targetedPortletString = targetedPortletIds[0];
                    targetedPortletWindowId = urlNodeSyntaxHelper.getPortletForFolderName(request,
                            targetedLayoutNodeId, targetedPortletString);
                }

            }
            case STATE: {
                parseStep = ParseStep.TYPE;

                //States other than the default only make sense if a portlet is being targeted
                if (targetedPortletWindowId == null) {
                    break;
                }

                requestedUrlState = UrlState.valueOfIngoreCase(pathPart, null);

                //Set the URL state
                if (requestedUrlState != null) {
                    portalRequestInfo.setUrlState(requestedUrlState);

                    //If the request is stateless
                    if (statelessUrlStates.contains(requestedUrlState)) {
                        final IPortletWindow statelessPortletWindow = this.portletWindowRegistry
                                .getOrCreateStatelessPortletWindow(request, targetedPortletWindowId);
                        targetedPortletWindowId = statelessPortletWindow.getPortletWindowId();
                    }

                    //Create the portlet request info
                    targetedPortletRequestInfo = portalRequestInfo
                            .getPortletRequestInfo(targetedPortletWindowId);
                    portalRequestInfo.setTargetedPortletWindowId(targetedPortletWindowId);

                    //Set window state based on URL State first then look for the window state parameter
                    switch (requestedUrlState) {
                    case MAX: {
                        targetedPortletRequestInfo.setWindowState(WindowState.MAXIMIZED);
                    }
                        break;

                    case DETACHED: {
                        targetedPortletRequestInfo.setWindowState(IPortletRenderer.DETACHED);
                    }
                        break;

                    case EXCLUSIVE: {
                        targetedPortletRequestInfo.setWindowState(IPortletRenderer.EXCLUSIVE);
                    }
                        break;
                    }

                    break;
                }
            }
            case TYPE: {
                parseStep = ParseStep.COMPLETE;

                if (pathPartIndex == requestPathParts.length - 1 && pathPart.endsWith(REQUEST_TYPE_SUFFIX)
                        && pathPart.length() > REQUEST_TYPE_SUFFIX.length()) {
                    final String urlTypePart = pathPart.substring(0,
                            pathPart.length() - REQUEST_TYPE_SUFFIX.length());
                    final UrlType urlType;

                    //Handle inline resourceIds, look for a . in the request type string and use the suffix as the urlType
                    final int lastPeriod = urlTypePart.lastIndexOf('.');
                    if (lastPeriod >= 0 && lastPeriod < urlTypePart.length()) {
                        final String urlTypePartSuffix = urlTypePart.substring(lastPeriod + 1);
                        urlType = UrlType.valueOfIngoreCase(urlTypePartSuffix, null);
                        if (urlType == UrlType.RESOURCE && targetedPortletRequestInfo != null) {
                            final String resourceId = urlTypePart.substring(0, lastPeriod);
                            targetedPortletRequestInfo.setResourceId(resourceId);
                        }
                    } else {
                        urlType = UrlType.valueOfIngoreCase(urlTypePart, null);
                    }

                    if (urlType != null) {
                        portalRequestInfo.setUrlType(urlType);
                        break;
                    }
                }
            }
            }
        }

        //If a targeted portlet window ID is found but no targeted portlet request info has been retrieved yet, set it up
        if (targetedPortletWindowId != null && targetedPortletRequestInfo == null) {
            targetedPortletRequestInfo = portalRequestInfo.getPortletRequestInfo(targetedPortletWindowId);
            portalRequestInfo.setTargetedPortletWindowId(targetedPortletWindowId);
        }

        //Get the set of portlet window ids that also have parameters on the url
        final String[] additionalPortletIdArray = parameterMap.remove(PARAM_ADDITIONAL_PORTLET);
        final Set<String> additionalPortletIds = Sets
                .newHashSet(additionalPortletIdArray != null ? additionalPortletIdArray : new String[0]);

        //Used if there is delegation to capture form-submit and other non-prefixed parameters
        //Map of parent id to delegate id
        final Map<IPortletWindowId, IPortletWindowId> delegateIdMappings = new LinkedHashMap<IPortletWindowId, IPortletWindowId>(
                0);

        //Parse all remaining parameters from the request
        final Set<Entry<String, String[]>> parameterEntrySet = parameterMap.entrySet();
        for (final Iterator<Entry<String, String[]>> parameterEntryItr = parameterEntrySet
                .iterator(); parameterEntryItr.hasNext();) {
            final Entry<String, String[]> parameterEntry = parameterEntryItr.next();

            final String name = parameterEntry.getKey();
            final List<String> values = Arrays.asList(parameterEntry.getValue());

            /* NOTE: continues are being used to allow fall-through behavior like a switch statement would provide */

            //Portal Parameters, just need to remove the prefix
            if (name.startsWith(PORTAL_PARAM_PREFIX)) {
                final Map<String, List<String>> portalParameters = portalRequestInfo.getPortalParameters();
                portalParameters.put(this.safeSubstringAfter(PORTAL_PARAM_PREFIX, name), values);
                parameterEntryItr.remove();
                continue;
            }

            //Generic portlet parameters, have to remove the prefix and see if there was a portlet windowId between the prefix and parameter name
            if (name.startsWith(PORTLET_PARAM_PREFIX)) {
                final Tuple<String, IPortletWindowId> portletParameterParts = this
                        .parsePortletParameterName(request, name, additionalPortletIds);
                final IPortletWindowId portletWindowId = portletParameterParts.second;
                final String paramName = portletParameterParts.first;

                //Get the portlet parameter map to add the parameter to
                final Map<String, List<String>> portletParameters;
                if (portletWindowId == null) {
                    if (targetedPortletRequestInfo == null) {
                        this.logger.warn("Parameter " + name
                                + " is for the targeted portlet but no portlet is targeted by the request. The parameter will be ignored. Value: "
                                + values);
                        parameterEntryItr.remove();
                        break;
                    }

                    portletParameters = targetedPortletRequestInfo.getPortletParameters();
                } else {
                    final PortletRequestInfoImpl portletRequestInfoImpl = portalRequestInfo
                            .getPortletRequestInfo(portletWindowId);
                    portletParameters = portletRequestInfoImpl.getPortletParameters();
                }

                portletParameters.put(paramName, values);
                parameterEntryItr.remove();
                continue;
            }

            //Portlet control parameters are either used directly or as a prefix to a windowId. Use the SuffixedPortletParameter to simplify their parsing
            for (final SuffixedPortletParameter suffixedPortletParameter : SuffixedPortletParameter.values()) {
                final String parameterPrefix = suffixedPortletParameter.getParameterPrefix();
                //Skip to the next parameter prefix if the current doesn't match
                if (!name.startsWith(parameterPrefix)) {
                    continue;
                }

                //All of these parameters require at least one value
                if (values.isEmpty()) {
                    this.logger
                            .warn("Ignoring parameter " + name + " as it must have a value. Value: " + values);
                    break;
                }

                //Verify the parameter is being used on the correct type of URL
                final Set<UrlType> validUrlTypes = suffixedPortletParameter.getValidUrlTypes();
                if (!validUrlTypes.contains(portalRequestInfo.getUrlType())) {
                    this.logger.warn("Ignoring parameter " + name + " as it is only valid for " + validUrlTypes
                            + " requests and this is a " + portalRequestInfo.getUrlType() + " request. Value: "
                            + values);
                    break;
                }

                //Determine the portlet window and request info the parameter targets
                final IPortletWindowId portletWindowId = this.parsePortletWindowIdSuffix(request,
                        parameterPrefix, additionalPortletIds, name);
                final PortletRequestInfoImpl portletRequestInfo = getTargetedPortletRequestInfo(
                        portalRequestInfo, targetedPortletRequestInfo, portletWindowId);
                if (portletRequestInfo == null) {
                    this.logger.warn("Parameter " + name
                            + " is for the targeted portlet but no portlet is targeted by the request. The parameter will be ignored. Value: "
                            + values);
                    break;
                }

                parameterEntryItr.remove();

                //Use the enum helper to store the parameter values on the request info
                suffixedPortletParameter.updateRequestInfo(request, portletWindowRegistry, portletRequestInfo,
                        values, delegateIdMappings);
                break;
            }
        }

        //Any non-namespaced parameters still need processing?
        if (!parameterMap.isEmpty()) {
            //If the parameter was not ignored by a previous parser add it to whatever was targeted (portlet or portal)
            final Map<String, List<String>> parameters;
            if (!delegateIdMappings.isEmpty()) {
                //Resolve the last portlet window in the chain of delegation
                PortletRequestInfoImpl delegatePortletRequestInfo = null;
                for (final IPortletWindowId delegatePortletWindowId : delegateIdMappings.values()) {
                    if (!delegateIdMappings.containsKey(delegatePortletWindowId)) {
                        delegatePortletRequestInfo = portalRequestInfo
                                .getPortletRequestInfo(delegatePortletWindowId);
                        break;
                    }
                }

                if (delegatePortletRequestInfo != null) {
                    parameters = delegatePortletRequestInfo.getPortletParameters();
                } else {
                    this.logger.warn(
                            "No root delegate portlet could be resolved, non-namespaced parameters will be sent to the targeted portlet. THIS SHOULD NEVER HAPPEN. Delegate parent/child mapping: "
                                    + delegateIdMappings);

                    if (targetedPortletRequestInfo != null) {
                        parameters = targetedPortletRequestInfo.getPortletParameters();
                    } else {
                        parameters = portalRequestInfo.getPortalParameters();
                    }
                }
            } else if (targetedPortletRequestInfo != null) {
                parameters = targetedPortletRequestInfo.getPortletParameters();
            } else {
                parameters = portalRequestInfo.getPortalParameters();
            }

            ParameterMap.putAllList(parameters, parameterMap);
        }

        //If a portlet is targeted but no layout node is targeted must be maximized
        if (targetedPortletRequestInfo != null && portalRequestInfo.getTargetedLayoutNodeId() == null
                && (requestedUrlState == null || requestedUrlState == UrlState.NORMAL)) {
            portalRequestInfo.setUrlState(UrlState.MAX);
            targetedPortletRequestInfo.setWindowState(WindowState.MAXIMIZED);
        }

        //Make the request info object read-only, once parsed the request info should be static
        portalRequestInfo.makeReadOnly();

        request.setAttribute(PORTAL_REQUEST_INFO_ATTR, portalRequestInfo);

        if (logger.isDebugEnabled()) {
            logger.debug("finished building requestInfo: " + portalRequestInfo);
        }

        return portalRequestInfo;
    } finally {
        request.removeAttribute(PORTAL_REQUEST_PARSING_IN_PROGRESS_ATTR);
    }
}

From source file:org.apereo.portal.url.UrlSyntaxProviderImpl.java

@Override
public IPortalRequestInfo getPortalRequestInfo(HttpServletRequest request) {
    request = this.portalRequestUtils.getOriginalPortalRequest(request);
    final IPortalRequestInfo cachedPortalRequestInfo = (IPortalRequestInfo) request
            .getAttribute(PORTAL_REQUEST_INFO_ATTR);
    if (cachedPortalRequestInfo != null) {
        if (logger.isDebugEnabled()) {
            logger.debug("short-circuit: found portalRequestInfo within request attributes");
        }/*  w w  w  .  ja v a 2s . c  o  m*/
        return cachedPortalRequestInfo;
    }

    synchronized (PortalWebUtils.getRequestAttributeMutex(request)) {
        // set a flag to say this request is currently being parsed
        final Boolean inProgressAttr = (Boolean) request.getAttribute(PORTAL_REQUEST_PARSING_IN_PROGRESS_ATTR);
        if (inProgressAttr != null && inProgressAttr) {
            if (logger.isDebugEnabled()) {
                logger.warn("Portal request info parsing already in progress, returning null");
            }
            return null;
        }
        request.setAttribute(PORTAL_REQUEST_PARSING_IN_PROGRESS_ATTR, Boolean.TRUE);
    }

    try {
        // Clone the parameter map so data can be removed from it as it is parsed to help determine
        // what to do with non-namespaced parameters
        final Map<String, String[]> parameterMap = new ParameterMap(request.getParameterMap());

        final String requestPath = this.urlPathHelper.getPathWithinApplication(request);

        if (LEGACY_URL_PATHS.contains(requestPath)) {
            return parseLegacyPortalUrl(request, parameterMap);
        }

        final IUrlNodeSyntaxHelper urlNodeSyntaxHelper = this.urlNodeSyntaxHelperRegistry
                .getCurrentUrlNodeSyntaxHelper(request);

        final PortalRequestInfoImpl portalRequestInfo = new PortalRequestInfoImpl();
        IPortletWindowId targetedPortletWindowId = null;
        PortletRequestInfoImpl targetedPortletRequestInfo = null;

        final String[] requestPathParts = SLASH_PATTERN.split(requestPath);

        UrlState requestedUrlState = null;
        ParseStep parseStep = ParseStep.FOLDER;
        for (int pathPartIndex = 0; pathPartIndex < requestPathParts.length; pathPartIndex++) {
            String pathPart = requestPathParts[pathPartIndex];

            logger.trace("In parseStep {} considering pathPart [{}].", parseStep, pathPart);

            if (StringUtils.isEmpty(pathPart)) {
                continue;
            }

            switch (parseStep) {
            case FOLDER: {
                parseStep = ParseStep.PORTLET;

                if (FOLDER_PATH_PREFIX.equals(pathPart)) {

                    logger.trace("Skipping adding {} to the folders deque "
                            + "because it is simply the folder path prefix.", pathPart);

                    pathPartIndex++;

                    final LinkedList<String> folders = new LinkedList<String>();
                    for (; pathPartIndex < requestPathParts.length; pathPartIndex++) {
                        pathPart = requestPathParts[pathPartIndex];

                        if (PORTLET_PATH_PREFIX.equals(pathPart)) {
                            logger.trace(
                                    "Found the portlet part of the path "
                                            + "demarked by portlet path prefix [{}]; "
                                            + "stepping back one path part to finish folder processing",
                                    pathPart);
                            pathPartIndex--;
                            break;
                        } else {

                            if (pathPart.endsWith(REQUEST_TYPE_SUFFIX)) {
                                logger.trace("Found the end of the folder path with pathPart [{}];"
                                        + " stepping back one, checking for state, "
                                        + "and finishing folder parsing", pathPart);
                                pathPartIndex--;
                                pathPart = requestPathParts[pathPartIndex];

                                // If a state was added to the folder list remove it and step back one so
                                // other code can handle it
                                if (UrlState.valueOfIngoreCase(pathPart, null) != null) {
                                    logger.trace(
                                            "A state was added to the end of folder list {};" + " removing it.",
                                            folders);
                                    folders.removeLast();
                                    pathPartIndex--;
                                }
                                break;
                            }
                        }

                        logger.trace("Adding pathPart [{}] to folders.", pathPart);
                        folders.add(pathPart);
                    }

                    logger.trace("Folders is [{}]", folders);
                    if (folders.size() > 0) {
                        final String targetedLayoutNodeId = urlNodeSyntaxHelper
                                .getLayoutNodeForFolderNames(request, folders);
                        portalRequestInfo.setTargetedLayoutNodeId(targetedLayoutNodeId);
                    }
                    break;
                }
            }
            case PORTLET: {
                parseStep = ParseStep.STATE;

                final String targetedLayoutNodeId = portalRequestInfo.getTargetedLayoutNodeId();

                if (PORTLET_PATH_PREFIX.equals(pathPart)) {
                    if (++pathPartIndex < requestPathParts.length) {
                        pathPart = requestPathParts[pathPartIndex];

                        targetedPortletWindowId = urlNodeSyntaxHelper.getPortletForFolderName(request,
                                targetedLayoutNodeId, pathPart);
                    }

                    break;
                }

                //See if a portlet was targeted by parameter  
                final String[] targetedPortletIds = parameterMap.remove(PARAM_TARGET_PORTLET);
                if (targetedPortletIds != null && targetedPortletIds.length > 0) {
                    final String targetedPortletString = targetedPortletIds[0];
                    targetedPortletWindowId = urlNodeSyntaxHelper.getPortletForFolderName(request,
                            targetedLayoutNodeId, targetedPortletString);
                }

            }
            case STATE: {
                parseStep = ParseStep.TYPE;

                //States other than the default only make sense if a portlet is being targeted
                if (targetedPortletWindowId == null) {
                    break;
                }

                requestedUrlState = UrlState.valueOfIngoreCase(pathPart, null);

                //Set the URL state
                if (requestedUrlState != null) {
                    portalRequestInfo.setUrlState(requestedUrlState);

                    //If the request is stateless
                    if (statelessUrlStates.contains(requestedUrlState)) {
                        final IPortletWindow statelessPortletWindow = this.portletWindowRegistry
                                .getOrCreateStatelessPortletWindow(request, targetedPortletWindowId);
                        targetedPortletWindowId = statelessPortletWindow.getPortletWindowId();
                    }

                    //Create the portlet request info
                    targetedPortletRequestInfo = portalRequestInfo
                            .getPortletRequestInfo(targetedPortletWindowId);
                    portalRequestInfo.setTargetedPortletWindowId(targetedPortletWindowId);

                    //Set window state based on URL State first then look for the window state parameter
                    switch (requestedUrlState) {
                    case MAX: {
                        targetedPortletRequestInfo.setWindowState(WindowState.MAXIMIZED);
                    }
                        break;

                    case DETACHED: {
                        targetedPortletRequestInfo.setWindowState(IPortletRenderer.DETACHED);
                    }
                        break;

                    case EXCLUSIVE: {
                        targetedPortletRequestInfo.setWindowState(IPortletRenderer.EXCLUSIVE);
                    }
                        break;
                    }

                    break;
                }
            }
            case TYPE: {
                parseStep = ParseStep.COMPLETE;

                if (pathPartIndex == requestPathParts.length - 1 && pathPart.endsWith(REQUEST_TYPE_SUFFIX)
                        && pathPart.length() > REQUEST_TYPE_SUFFIX.length()) {
                    final String urlTypePart = pathPart.substring(0,
                            pathPart.length() - REQUEST_TYPE_SUFFIX.length());
                    final UrlType urlType;

                    //Handle inline resourceIds, look for a . in the request type string and use the suffix as the urlType
                    final int lastPeriod = urlTypePart.lastIndexOf('.');
                    if (lastPeriod >= 0 && lastPeriod < urlTypePart.length()) {
                        final String urlTypePartSuffix = urlTypePart.substring(lastPeriod + 1);
                        urlType = UrlType.valueOfIngoreCase(urlTypePartSuffix, null);
                        if (urlType == UrlType.RESOURCE && targetedPortletRequestInfo != null) {
                            final String resourceId = urlTypePart.substring(0, lastPeriod);
                            targetedPortletRequestInfo.setResourceId(resourceId);
                        }
                    } else {
                        urlType = UrlType.valueOfIngoreCase(urlTypePart, null);
                    }

                    if (urlType != null) {
                        portalRequestInfo.setUrlType(urlType);
                        break;
                    }
                }
            }
            }
        }

        //If a targeted portlet window ID is found but no targeted portlet request info has been retrieved yet, set it up
        if (targetedPortletWindowId != null && targetedPortletRequestInfo == null) {
            targetedPortletRequestInfo = portalRequestInfo.getPortletRequestInfo(targetedPortletWindowId);
            portalRequestInfo.setTargetedPortletWindowId(targetedPortletWindowId);
        }

        //Get the set of portlet window ids that also have parameters on the url
        final String[] additionalPortletIdArray = parameterMap.remove(PARAM_ADDITIONAL_PORTLET);
        final Set<String> additionalPortletIds = Sets
                .newHashSet(additionalPortletIdArray != null ? additionalPortletIdArray : new String[0]);

        //Used if there is delegation to capture form-submit and other non-prefixed parameters
        //Map of parent id to delegate id
        final Map<IPortletWindowId, IPortletWindowId> delegateIdMappings = new LinkedHashMap<IPortletWindowId, IPortletWindowId>(
                0);

        //Parse all remaining parameters from the request
        final Set<Entry<String, String[]>> parameterEntrySet = parameterMap.entrySet();
        for (final Iterator<Entry<String, String[]>> parameterEntryItr = parameterEntrySet
                .iterator(); parameterEntryItr.hasNext();) {
            final Entry<String, String[]> parameterEntry = parameterEntryItr.next();

            final String name = parameterEntry.getKey();
            final List<String> values = Arrays.asList(parameterEntry.getValue());

            /* NOTE: continues are being used to allow fall-through behavior like a switch statement would provide */

            //Portal Parameters, just need to remove the prefix
            if (name.startsWith(PORTAL_PARAM_PREFIX)) {
                final Map<String, List<String>> portalParameters = portalRequestInfo.getPortalParameters();
                portalParameters.put(this.safeSubstringAfter(PORTAL_PARAM_PREFIX, name), values);
                parameterEntryItr.remove();
                continue;
            }

            //Generic portlet parameters, have to remove the prefix and see if there was a portlet windowId between the prefix and parameter name
            if (name.startsWith(PORTLET_PARAM_PREFIX)) {
                final Tuple<String, IPortletWindowId> portletParameterParts = this
                        .parsePortletParameterName(request, name, additionalPortletIds);
                final IPortletWindowId portletWindowId = portletParameterParts.second;
                final String paramName = portletParameterParts.first;

                //Get the portlet parameter map to add the parameter to
                final Map<String, List<String>> portletParameters;
                if (portletWindowId == null) {
                    if (targetedPortletRequestInfo == null) {
                        this.logger.warn("Parameter " + name
                                + " is for the targeted portlet but no portlet is targeted by the request. The parameter will be ignored. Value: "
                                + values);
                        parameterEntryItr.remove();
                        break;
                    }

                    portletParameters = targetedPortletRequestInfo.getPortletParameters();
                } else {
                    final PortletRequestInfoImpl portletRequestInfoImpl = portalRequestInfo
                            .getPortletRequestInfo(portletWindowId);
                    portletParameters = portletRequestInfoImpl.getPortletParameters();
                }

                portletParameters.put(paramName, values);
                parameterEntryItr.remove();
                continue;
            }

            // Portlet control parameters are either used directly or as a prefix to a windowId. Use the
            // SuffixedPortletParameter to simplify their parsing
            for (final SuffixedPortletParameter suffixedPortletParameter : SuffixedPortletParameter.values()) {
                final String parameterPrefix = suffixedPortletParameter.getParameterPrefix();
                //Skip to the next parameter prefix if the current doesn't match
                if (!name.startsWith(parameterPrefix)) {
                    continue;
                }

                //All of these parameters require at least one value
                if (values.isEmpty()) {
                    this.logger.warn("Ignoring parameter {} as it must have a value. Value: {}", name, values);
                    break;
                }

                //Verify the parameter is being used on the correct type of URL
                final Set<UrlType> validUrlTypes = suffixedPortletParameter.getValidUrlTypes();
                if (!validUrlTypes.contains(portalRequestInfo.getUrlType())) {
                    this.logger.warn(
                            "Ignoring parameter {} as it is only valid for {} requests and this is a "
                                    + "{} request. Value: {}",
                            name, validUrlTypes, portalRequestInfo.getUrlType(), values);
                    break;
                }

                //Determine the portlet window and request info the parameter targets
                final IPortletWindowId portletWindowId = this.parsePortletWindowIdSuffix(request,
                        parameterPrefix, additionalPortletIds, name);
                final PortletRequestInfoImpl portletRequestInfo = getTargetedPortletRequestInfo(
                        portalRequestInfo, targetedPortletRequestInfo, portletWindowId);
                if (portletRequestInfo == null) {
                    this.logger.warn(
                            "Parameter {} is for the targeted portlet but no portlet is targeted"
                                    + " by the request. The parameter will be ignored. Value: {}",
                            name, values);
                    break;
                }

                parameterEntryItr.remove();

                //Use the enum helper to store the parameter values on the request info
                suffixedPortletParameter.updateRequestInfo(request, portletWindowRegistry, portletRequestInfo,
                        values, delegateIdMappings);
                break;
            }
        }

        //Any non-namespaced parameters still need processing?
        if (!parameterMap.isEmpty()) {
            //If the parameter was not ignored by a previous parser add it to whatever was targeted (portlet or portal)
            final Map<String, List<String>> parameters;
            if (!delegateIdMappings.isEmpty()) {
                //Resolve the last portlet window in the chain of delegation
                PortletRequestInfoImpl delegatePortletRequestInfo = null;
                for (final IPortletWindowId delegatePortletWindowId : delegateIdMappings.values()) {
                    if (!delegateIdMappings.containsKey(delegatePortletWindowId)) {
                        delegatePortletRequestInfo = portalRequestInfo
                                .getPortletRequestInfo(delegatePortletWindowId);
                        break;
                    }
                }

                if (delegatePortletRequestInfo != null) {
                    parameters = delegatePortletRequestInfo.getPortletParameters();
                } else {
                    this.logger.warn("No root delegate portlet could be resolved, non-namespaced parameters"
                            + " will be sent to the targeted portlet. THIS SHOULD NEVER HAPPEN. Delegate"
                            + " parent/child mapping: {}", delegateIdMappings);

                    if (targetedPortletRequestInfo != null) {
                        parameters = targetedPortletRequestInfo.getPortletParameters();
                    } else {
                        parameters = portalRequestInfo.getPortalParameters();
                    }
                }
            } else if (targetedPortletRequestInfo != null) {
                parameters = targetedPortletRequestInfo.getPortletParameters();
            } else {
                parameters = portalRequestInfo.getPortalParameters();
            }

            ParameterMap.putAllList(parameters, parameterMap);
        }

        //If a portlet is targeted but no layout node is targeted must be maximized
        if (targetedPortletRequestInfo != null && portalRequestInfo.getTargetedLayoutNodeId() == null
                && (requestedUrlState == null || requestedUrlState == UrlState.NORMAL)) {
            portalRequestInfo.setUrlState(UrlState.MAX);
            targetedPortletRequestInfo.setWindowState(WindowState.MAXIMIZED);
        }

        //Make the request info object read-only, once parsed the request info should be static
        portalRequestInfo.makeReadOnly();

        request.setAttribute(PORTAL_REQUEST_INFO_ATTR, portalRequestInfo);

        logger.debug("Finished building requestInfo: {}", portalRequestInfo);

        return portalRequestInfo;
    } finally {
        request.removeAttribute(PORTAL_REQUEST_PARSING_IN_PROGRESS_ATTR);
    }
}