Search in sources :

Example 1 with FacesURLEncoder

use of com.liferay.faces.util.render.FacesURLEncoder in project liferay-faces-bridge-impl by liferay.

the class ExternalContextImpl method redirect.

@Override
public void redirect(String url) throws IOException {
    if (url != null) {
        logger.debug("redirect url=[{0}]", url);
        // lifecycle, then
        if ((portletPhase == Bridge.PortletPhase.ACTION_PHASE) || (portletPhase == Bridge.PortletPhase.EVENT_PHASE) || isHeaderPhase(portletPhase) || (portletPhase == Bridge.PortletPhase.RENDER_PHASE)) {
            // "javax.portlet.faces.DirectLink" parameter value of "true", then
            try {
                FacesContext facesContext = FacesContext.getCurrentInstance();
                ExternalContext externalContext = facesContext.getExternalContext();
                FacesURLEncoder facesURLEncoder = FacesURLEncoderFactory.getFacesURLEncoderInstance(externalContext);
                ResponseWriter responseWriter = facesContext.getResponseWriter();
                String urlCharacterEncoding = URLUtil.getURLCharacterEncoding(portletPhase, externalContext, responseWriter, "UTF-8");
                BridgeURI bridgeURI = new BridgeURI(url, portletResponse.getNamespace(), facesURLEncoder, urlCharacterEncoding);
                String directLink = bridgeURI.getParameter(Bridge.DIRECT_LINK);
                String contextPath = externalContext.getRequestContextPath();
                if ((portletPhase == Bridge.PortletPhase.ACTION_PHASE) && (url.startsWith("#") || bridgeURI.isExternal(contextPath) || "true".equals(directLink))) {
                    if (bridgeRequestScope != null) {
                        bridgeRequestScope.setRedirectOccurred(true);
                    }
                    // TCK: requestNoScopeOnRedirectTest
                    ActionResponse actionResponse = (ActionResponse) portletResponse;
                    actionResponse.sendRedirect(bridgeURI.toString());
                } else // Otherwise,
                {
                    // If running in the ACTION_PHASE of the portlet lifecycle and the portlet container has the
                    // ability to create a render URL during the ACTION_PHASE, then assume that the specified URL is
                    // an encoded RenderURL and issue a redirect.
                    PortletRequest portletRequest = (PortletRequest) externalContext.getRequest();
                    PortalContext portalContext = portletRequest.getPortalContext();
                    String createRenderUrlDuringActionPhaseSupport = portalContext.getProperty(BridgePortalContext.CREATE_RENDER_URL_DURING_ACTION_PHASE_SUPPORT);
                    if ((portletPhase == Bridge.PortletPhase.ACTION_PHASE) && (createRenderUrlDuringActionPhaseSupport != null)) {
                        // Redirect to the targeted view.
                        // TCK: redirectActionTest (Liferay Portal)
                        BridgeURL bridgeRedirectURL = bridgeURLFactory.getBridgeRedirectURL(facesContext, bridgeURI.toString(), null);
                        ActionResponse actionResponse = (ActionResponse) portletResponse;
                        actionResponse.sendRedirect(bridgeRedirectURL.toString());
                    } else // redirect).
                    if ((portletPhase == Bridge.PortletPhase.ACTION_PHASE) || (portletPhase == Bridge.PortletPhase.EVENT_PHASE)) {
                        // TCK: redirectActionTest (Pluto)
                        // TCK: redirectEventTest
                        String newViewId = bridgeURI.getContextRelativePath(contextPath);
                        // If redirecting to a different view, then create the target view and place it into the
                        // FacesContext.
                        UIViewRoot viewRoot = facesContext.getViewRoot();
                        String currentFacesViewId = viewRoot.getViewId();
                        if (!currentFacesViewId.equals(newViewId)) {
                            ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
                            UIViewRoot newViewRoot = viewHandler.createView(facesContext, newViewId);
                            facesContext.setViewRoot(newViewRoot);
                        }
                        // Set the "_facesViewIdRender" parameter on the URL to the new viewId so that the call
                        // to BridgeNavigationUtil.navigate(...) below will cause a render parameter to be set
                        // which will inform containers that implement POST-REDIRECT-GET (like Pluto) that the
                        // 302 redirect URL needs to specify the new viewId in order for redirection to work in
                        // the subsequent RENDER_PHASE.
                        bridgeURI.setParameter(bridgeConfig.getViewIdRenderParameterName(), newViewId);
                        // Update the PartialViewContext.
                        partialViewContextRenderAll(facesContext);
                        // Set the response as "complete" in the FacesContext.
                        facesContext.responseComplete();
                        // occurred which means that the request attributes should not be preserved.
                        if (bridgeRequestScope != null) {
                            bridgeRequestScope.setRedirectOccurred(true);
                        }
                        // Apply the PortletMode, WindowState, etc. that may be present in the URL to the response.
                        try {
                            StateAwareResponse stateAwareResponse = (StateAwareResponse) portletResponse;
                            BridgeNavigationUtil.navigate(portletRequest, stateAwareResponse, bridgeURI.getParameterMap());
                        } catch (PortletException e) {
                            logger.error(e.getMessage());
                        }
                    } else // lifecycle, then
                    if (isHeaderPhase(portletPhase) || (portletPhase == Bridge.PortletPhase.RENDER_PHASE)) {
                        // If the specified URL is for a JSF viewId, then prepare for a render-redirect.
                        BridgeURL bridgeRedirectURL = bridgeURLFactory.getBridgeRedirectURL(facesContext, url, null);
                        String redirectURLViewId = bridgeRedirectURL.getViewId();
                        if (redirectURLViewId != null) {
                            // TCK: renderRedirectTest
                            // TCK: redirectRenderTest
                            // TCK: redirectRenderPRP2Test
                            portletRequest.setAttribute(BridgeExt.RENDER_REDIRECT, Boolean.TRUE);
                            portletRequest.setAttribute(BridgeExt.RENDER_REDIRECT_VIEW_ID, redirectURLViewId);
                        } else // Otherwise,
                        {
                            // If there is a URL parameter specifying a JSF viewId, then prepare for a
                            // render-redirect.
                            String viewIdRenderParameterName = bridgeConfig.getViewIdRenderParameterName();
                            String viewIdRenderParameterValue = bridgeRedirectURL.getParameter(viewIdRenderParameterName);
                            // FACES-2978: Support render-redirect.
                            if (viewIdRenderParameterValue == null) {
                                Map<String, Object> requestMap = externalContext.getRequestMap();
                                String requestMapKey = Bridge.VIEW_ID + url;
                                viewIdRenderParameterValue = (String) requestMap.remove(requestMapKey);
                            }
                            if (viewIdRenderParameterValue != null) {
                                // TCK: redirectRenderPRP1Test
                                portletRequest.setAttribute(BridgeExt.RENDER_REDIRECT, Boolean.TRUE);
                                portletRequest.setAttribute(BridgeExt.RENDER_REDIRECT_VIEW_ID, viewIdRenderParameterValue);
                            } else // Otherwise, throw an IllegalStateException according to Section 6.1.3.1 of the Spec.
                            {
                                throw new IllegalStateException("6.1.3.1: Unable to redirect to a non-Faces view during the RENDER_PHASE.");
                            }
                        }
                    }
                }
            } catch (URISyntaxException e) {
                logger.error(e);
            }
        } else // Otherwise, since executing the RESOURCE_PHASE of the portlet lifecycle:
        {
            // NOTE: The Bridge Spec indicates that the redirect is to be ignored, but JSF 2 has the ability to
            // redirect during Ajax.
            FacesContext facesContext = FacesContext.getCurrentInstance();
            if (isJSF2PartialRequest(facesContext)) {
                try {
                    redirectJSF2PartialResponse(facesContext, (ResourceResponse) portletResponse, url);
                } catch (Exception e) {
                    logger.error(e);
                    throw new IOException(e.getMessage());
                }
            } else {
                throw new UnsupportedEncodingException("Can only redirect during RESOURCE_PHASE if a JSF partial/Ajax request has been triggered");
            }
        }
    } else {
        logger.error("redirect url=null");
    }
}
Also used : FacesContext(javax.faces.context.FacesContext) PortletException(javax.portlet.PortletException) ViewHandler(javax.faces.application.ViewHandler) UnsupportedEncodingException(java.io.UnsupportedEncodingException) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) ActionResponse(javax.portlet.ActionResponse) BridgeDefaultViewNotSpecifiedException(javax.portlet.faces.BridgeDefaultViewNotSpecifiedException) URISyntaxException(java.net.URISyntaxException) BridgeException(javax.portlet.faces.BridgeException) FacesException(javax.faces.FacesException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) BridgeInvalidViewPathException(javax.portlet.faces.BridgeInvalidViewPathException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) PortletException(javax.portlet.PortletException) StateAwareResponse(javax.portlet.StateAwareResponse) PortletRequest(javax.portlet.PortletRequest) ResponseWriter(javax.faces.context.ResponseWriter) ExternalContext(javax.faces.context.ExternalContext) PortalContext(javax.portlet.PortalContext) BridgePortalContext(com.liferay.faces.bridge.context.BridgePortalContext) FacesURLEncoder(com.liferay.faces.util.render.FacesURLEncoder) BridgeURI(com.liferay.faces.bridge.internal.BridgeURI) UIViewRoot(javax.faces.component.UIViewRoot) BridgeURL(javax.portlet.faces.BridgeURL)

Aggregations

BridgePortalContext (com.liferay.faces.bridge.context.BridgePortalContext)1 BridgeURI (com.liferay.faces.bridge.internal.BridgeURI)1 FacesURLEncoder (com.liferay.faces.util.render.FacesURLEncoder)1 IOException (java.io.IOException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 MalformedURLException (java.net.MalformedURLException)1 URISyntaxException (java.net.URISyntaxException)1 FacesException (javax.faces.FacesException)1 ViewHandler (javax.faces.application.ViewHandler)1 UIViewRoot (javax.faces.component.UIViewRoot)1 ExternalContext (javax.faces.context.ExternalContext)1 FacesContext (javax.faces.context.FacesContext)1 ResponseWriter (javax.faces.context.ResponseWriter)1 ActionResponse (javax.portlet.ActionResponse)1 PortalContext (javax.portlet.PortalContext)1 PortletException (javax.portlet.PortletException)1 PortletRequest (javax.portlet.PortletRequest)1 StateAwareResponse (javax.portlet.StateAwareResponse)1 BridgeDefaultViewNotSpecifiedException (javax.portlet.faces.BridgeDefaultViewNotSpecifiedException)1 BridgeException (javax.portlet.faces.BridgeException)1