Search in sources :

Example 31 with StateAwareResponse

use of javax.portlet.StateAwareResponse in project liferay-faces-bridge-impl by liferay.

the class BridgePhaseBaseImpl method maintainBridgeRequestScope.

protected void maintainBridgeRequestScope(PortletRequest portletRequest, PortletResponse portletResponse, BridgeRequestScope.Transport bridgeRequestScopeTransport) {
    String bridgeRequestScopeId = bridgeRequestScope.getId();
    bridgeRequestScope = bridgeRequestScopeCache.putValueIfAbsent(bridgeRequestScopeId, bridgeRequestScope);
    String bridgeRequestScopeKey = portletName + PARAM_BRIDGE_REQUEST_SCOPE_ID;
    if (bridgeRequestScopeTransport == BridgeRequestScope.Transport.PORTLET_SESSION_ATTRIBUTE) {
        // TCK: nonFacesResourceTest
        // TCK: resourceAttrRetainedAfterRedisplayPPRTest
        PortletSession portletSession = portletRequest.getPortletSession(true);
        portletSession.setAttribute(bridgeRequestScopeKey, bridgeRequestScopeId);
    } else {
        if (portletResponse instanceof StateAwareResponse) {
            logger.debug("Setting render parameter name=[{0}] value=[{1}]", bridgeRequestScopeKey, bridgeRequestScopeId);
            try {
                StateAwareResponse stateAwareResponse = (StateAwareResponse) portletResponse;
                stateAwareResponse.setRenderParameter(bridgeRequestScopeKey, bridgeRequestScopeId);
            } catch (IllegalStateException e) {
                // If a redirect occurred, then swallow/ignore the IllegalStateException
                if (bridgeRequestScope.isRedirectOccurred()) {
                // The Portlet API JavaDocs indicate that StateAwareResponse.setRenderParameter(String, String)
                // must throw an IllegalStateException if ActionResponse.sendRedirect(String) was previously
                // called. The JSR 329 TCK (requestNoScopeOnRedirectTest) and TestPage176 (redirectActionTest)
                // both perform pseudo-redirects (effectively treated like navigation-rules from one JSF viewId
                // to another). Since the tests don't actually call ActionResponse.sendRedirect(String), this
                // condition is never reached by the TCK. However, this condition is a real-world use-case and
                // so the IllegalStateException must be swallowed/ignored here so that portlet lifecycle
                // processing is able to continue. For more information, see:
                // http://issues.liferay.com/browse/FACES-1367
                } else // Otherwise queue the IllegalStateException.
                {
                    queueHandleableException(portletRequest, facesContext, e);
                }
            }
        }
    }
}
Also used : StateAwareResponse(javax.portlet.StateAwareResponse) PortletSession(javax.portlet.PortletSession)

Example 32 with StateAwareResponse

use of javax.portlet.StateAwareResponse 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)

Example 33 with StateAwareResponse

use of javax.portlet.StateAwareResponse in project liferay-faces-bridge-impl by liferay.

the class Tests method eventDestroyTest.

// Test is MultiRequest -- Render/Action
// Should never get to the render portion of this
@BridgeTest(test = "eventDestroyTest")
public String eventDestroyTest(TestBean testBean) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    // done by navigation rule.
    if (BridgeUtil.getPortletRequestPhase(facesContext) == Bridge.PortletPhase.ACTION_PHASE) {
        // Create and raise the event
        StateAwareResponse stateAwareResponse = (StateAwareResponse) externalContext.getResponse();
        stateAwareResponse.setEvent(new QName(Constants.EVENT_QNAME, Constants.EVENT_NAME), testBean.getTestName());
        // action Navigation result
        return "eventDestroyTest";
    } else {
        testBean.setTestComplete(true);
        testBean.setTestResult(false, "unexpectedly got to a render JSP in this test -- should have been handled by the test portlet.");
        return Constants.TEST_FAILED;
    }
}
Also used : FacesContext(javax.faces.context.FacesContext) StateAwareResponse(javax.portlet.StateAwareResponse) ExternalContext(javax.faces.context.ExternalContext) QName(javax.xml.namespace.QName) BridgeTest(com.liferay.faces.bridge.tck.annotation.BridgeTest)

Example 34 with StateAwareResponse

use of javax.portlet.StateAwareResponse in project liferay-faces-bridge-impl by liferay.

the class Tests method isAutoDispatchEventsTest.

public String isAutoDispatchEventsTest(TestBean testBean) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    // are explicitly excluded -- test for presence/absence in render
    if (BridgeUtil.getPortletRequestPhase(facesContext) == Bridge.PortletPhase.ACTION_PHASE) {
        // Create and raise the event -- this ensures isAutoDispatchEvents will get called
        StateAwareResponse stateAwareResponse = (StateAwareResponse) externalContext.getResponse();
        stateAwareResponse.setEvent(new QName("http://liferay.com/faces/event_ns", "faces.liferay.com.tck.testEvent"), testBean.getTestName());
        // action Navigation result
        return "isAutoDispatchEventsTest";
    } else {
        testBean.setTestComplete(true);
        String failedMsg = (String) externalContext.getRequestMap().get("test.fail.");
        String successMsg = (String) externalContext.getRequestMap().get("test.pass.");
        if (successMsg != null) {
            testBean.setTestResult(true, successMsg);
            return Constants.TEST_SUCCESS;
        } else if (failedMsg != null) {
            testBean.setTestResult(false, failedMsg);
            return Constants.TEST_FAILED;
        } else {
            testBean.setTestResult(false, "Unexpected failure: No result string set by the portlet");
            return Constants.TEST_FAILED;
        }
    }
}
Also used : FacesContext(javax.faces.context.FacesContext) StateAwareResponse(javax.portlet.StateAwareResponse) ExternalContext(javax.faces.context.ExternalContext) QName(javax.xml.namespace.QName)

Aggregations

StateAwareResponse (javax.portlet.StateAwareResponse)34 ExternalContext (javax.faces.context.ExternalContext)29 FacesContext (javax.faces.context.FacesContext)29 QName (javax.xml.namespace.QName)27 BridgeTest (com.liferay.faces.bridge.tck.annotation.BridgeTest)26 PortletRequest (javax.portlet.PortletRequest)9 ActionEvent (javax.faces.event.ActionEvent)3 PhaseEvent (javax.faces.event.PhaseEvent)3 Event (javax.portlet.Event)3 ELContext (javax.el.ELContext)2 ELResolver (javax.el.ELResolver)2 UIViewRoot (javax.faces.component.UIViewRoot)2 PortletMode (javax.portlet.PortletMode)2 PortletSession (javax.portlet.PortletSession)2 WindowState (javax.portlet.WindowState)2 Bridge (javax.portlet.faces.Bridge)2 BridgeURL (javax.portlet.faces.BridgeURL)2 BridgePortalContext (com.liferay.faces.bridge.context.BridgePortalContext)1 BridgeURI (com.liferay.faces.bridge.internal.BridgeURI)1 FacesURLEncoder (com.liferay.faces.util.render.FacesURLEncoder)1