Package org.apache.pluto.container.impl

Source Code of org.apache.pluto.container.impl.PortletRequestDispatcherImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.pluto.container.impl;

import java.io.IOException;
import java.util.Map;

import javax.portlet.MimeResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.pluto.container.PortletInvokerService;
import org.apache.pluto.container.PortletRequestContext;

/**
* Implementation of the <code>PortletRequestDispatcher</code> interface.
* The portlet request dispatcher is used to dispatch <b>PortletRequest</b> and
* <b>PortletResponse</b> to a URI.
*
*/
public class PortletRequestDispatcherImpl implements PortletRequestDispatcher, RequestDispatcher
    /** Logger. */
    private static final Logger LOG = LoggerFactory.getLogger(PortletRequestDispatcherImpl.class);
   
    // Private Member Variables ------------------------------------------------
   
    /** The nested servlet request dispatcher instance. */
    private RequestDispatcher requestDispatcher;
    private boolean namedDispatch;
   
   
    // Constructors ------------------------------------------------------------
   
    /**
     * Creates an instance. This constructor should be called to construct a
     * portlet request dispatcher.
     * @param requestDispatcher  the servlet request dispatcher.
     * @param namedDispatch true if requestDispatcher is a named dispatcher
     * @see javax.portlet.PortletContext#getNamedDispatcher(String)
     * @see javax.portlet.PortletContext#getRequestDispatcher(String)
     */
    public PortletRequestDispatcherImpl(RequestDispatcher requestDispatcher, boolean namedDispatch)
    {
        this.requestDispatcher = requestDispatcher;
        this.namedDispatch = namedDispatch;
     
        if (LOG.isDebugEnabled())
        {
          LOG.debug("Request dispatcher created.");
        }
    }
   
    private static HttpServletPortletRequestWrapper getWrappedRequest(ServletRequest request)
    {
        HttpServletPortletRequestWrapper req = null;
       
        do
        {
            if (request instanceof HttpServletPortletRequestWrapper)
            {
                req = (HttpServletPortletRequestWrapper)request;
            }
            else if (request instanceof HttpServletRequestWrapper)
            {
                request = ((HttpServletRequestWrapper)request).getRequest();
            }
            else
            {
                request = null;
            }               
        }
        while (request != null && req == null);
        return req;
    }

    private static HttpServletPortletResponseWrapper getWrappedResponse(ServletResponse response)
    {
        HttpServletPortletResponseWrapper res = null;
       
        do
        {
            if (response instanceof HttpServletPortletResponseWrapper)
            {
                res = (HttpServletPortletResponseWrapper)response;
            }
            else if (response instanceof HttpServletResponseWrapper)
            {
                response = ((HttpServletResponseWrapper)response).getResponse();
            }
            else
            {
                response = null;
            }               
        }
        while (response != null && res == null);
        return res;
    }
   
    private void doDispatch(PortletRequest request, PortletResponse response, boolean included) throws PortletException, IOException
    {
        boolean needsFlushAfterForward = false;
        if (!included)
        {
            String lifecyclePhase = (String)request.getAttribute(PortletRequest.LIFECYCLE_PHASE);
            if (PortletRequest.RENDER_PHASE.equals(lifecyclePhase) || PortletRequest.RESOURCE_PHASE.equals(lifecyclePhase))
            {
                needsFlushAfterForward = true;
                ((MimeResponse)response).resetBuffer();
            }
        }
       
        PortletRequestContext requestContext = (PortletRequestContext)request.getAttribute(PortletInvokerService.REQUEST_CONTEXT);
        HttpSession session = null;
       
        // PLT.10.4.3. Proxied session is created and passed if javax.portlet.servletDefaultSessionScope == PORTLET_SCOPE
        if (isPortletScopeSessionConfigured(requestContext))
        {
            String portletWindowId = requestContext.getPortletWindow().getId().getStringId();
            session = ServletPortletSessionProxy.createProxy(requestContext.getServletRequest(), portletWindowId);
        }
       
        HttpServletPortletRequestWrapper req = new HttpServletPortletRequestWrapper(requestContext.getServletRequest(),
                                                                                    requestContext.getServletContext(),
                                                                                    session,
                                                                                    request,
                                                                                    included,
                                                                                    namedDispatch);
        HttpServletPortletResponseWrapper res = new HttpServletPortletResponseWrapper(requestContext.getServletResponse(),
                                                                                      request,
                                                                                      response,
                                                                                      included);
        try
        {
            request.setAttribute(PortletInvokerService.PORTLET_CONFIG, requestContext.getPortletConfig());
            request.setAttribute(PortletInvokerService.PORTLET_REQUEST, request);
            request.setAttribute(PortletInvokerService.PORTLET_RESPONSE, response);
           
            if (!included && req.isForwardingPossible())
            {
                requestDispatcher.forward(req, res);
            }
            else
            {
                // need to "fake" the forward using an include
                requestDispatcher.include(req, res);
            }
            if (needsFlushAfterForward)
            {
                ((MimeResponse)response).flushBuffer();
            }
        }
        catch (ServletException sex)
        {
            if (sex.getRootCause() != null)
            {
                throw new PortletException(sex.getRootCause());
            }
            throw new PortletException(sex);
        }
        finally
        {
            request.removeAttribute(PortletInvokerService.PORTLET_CONFIG);
            request.removeAttribute(PortletInvokerService.PORTLET_REQUEST);
            request.removeAttribute(PortletInvokerService.PORTLET_RESPONSE);
        }
    }
   
    private boolean isPortletScopeSessionConfigured(PortletRequestContext requestContext)
    {
        boolean portletScopeSessionConfigured = false;
       
        PortletConfig portletConfig = requestContext.getPortletConfig();
        Map<String, String []> containerRuntimeOptions = portletConfig.getContainerRuntimeOptions();
        String [] values = containerRuntimeOptions.get("javax.portlet.servletDefaultSessionScope");
       
        if (values != null && values.length > 0)
        {
            portletScopeSessionConfigured = "PORTLET_SCOPE".equals(values[0]);
        }
       
        return portletScopeSessionConfigured;
    }

    // PortletRequestDispatcher Impl -------------------------------------------
  
    public void forward(PortletRequest request, PortletResponse response) throws PortletException, IOException
    {
        doDispatch(request, response, false);
    }
   
  public void include(PortletRequest request, PortletResponse response) throws PortletException, IOException
  {
      doDispatch(request, response, true);
  }
 
  public void include(RenderRequest request, RenderResponse response) throws PortletException, IOException
  {
      doDispatch(request, response, true);
    }
 
    // Nested RequestDispatcher Impl -------------------------------------------
 
    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException
    {
        HttpServletPortletRequestWrapper req = getWrappedRequest(request);
        HttpServletPortletResponseWrapper res = getWrappedResponse(response);
        res.resetBuffer();
       
        // cache the current dispatch state
        boolean forwarded = req.isForwarded();
        boolean namedDispatch = req.isNamedDispatch();
        Map<String,Object> pathAttributeValues = req.getPathAttributeValues();
        HttpServletPortletRequestWrapper.PathMethodValues pathMethodValues = req.getInitPathMethodValues();
       
        // (re)initialize the request wrapper to a nested forward
        req.setNestedForward();
        try
        {
            if (req.isForwardingPossible())
            {
                requestDispatcher.forward(request, response);
            }
            else
            {
                // need to "fake" the forward using an include
                requestDispatcher.include(request, response);
            }
        }
        finally
        {
            // restore the previously cached dispatch state
            req.restoreFromNestedForward(forwarded, namedDispatch, pathMethodValues, pathAttributeValues);
        }
    }

    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException
    {
        // no need for special handling on a nested dispatcher include: just calling the wrapped servlet dispatcher
        requestDispatcher.include(request, response);
    }
}
TOP

Related Classes of org.apache.pluto.container.impl.PortletRequestDispatcherImpl

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.