Search in sources :

Example 1 with ViewPoolProcessor

use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.

the class NavigationHandlerImpl method handleNavigation.

@Override
public void handleNavigation(FacesContext facesContext, String fromAction, String outcome, String toFlowDocumentId) {
    NavigationContext navigationContext = new NavigationContext();
    NavigationCase navigationCase = null;
    try {
        navigationCase = getNavigationCommand(facesContext, navigationContext, fromAction, outcome, toFlowDocumentId);
    } finally {
        navigationContext.finish(facesContext);
    }
    if (navigationCase != null) {
        if (log.isLoggable(Level.FINEST)) {
            log.finest("handleNavigation fromAction=" + fromAction + " outcome=" + outcome + " toViewId =" + navigationCase.getToViewId(facesContext) + " redirect=" + navigationCase.isRedirect());
        }
        boolean isViewActionProcessingBroadcastAndRequiresRedirect = false;
        if (UIViewAction.isProcessingBroadcast(facesContext)) {
            // f:viewAction tag always triggers a redirect to enforce execution of
            // the lifecycle again. Note this requires enables flash scope
            // keepMessages automatically, because a view action can add messages
            // and these ones requires to be renderer afterwards.
            facesContext.getExternalContext().getFlash().setKeepMessages(true);
            String fromViewId = (facesContext.getViewRoot() == null) ? null : facesContext.getViewRoot().getViewId();
            String toViewId = navigationCase.getToViewId(facesContext);
            // lifecycle is not necessary.
            if (fromViewId == null && toViewId != null) {
                isViewActionProcessingBroadcastAndRequiresRedirect = true;
            } else if (fromViewId != null && !fromViewId.equals(toViewId)) {
                isViewActionProcessingBroadcastAndRequiresRedirect = true;
            }
        }
        if (navigationCase.isRedirect() || isViewActionProcessingBroadcastAndRequiresRedirect) {
            // Need to add the FlowHandler parameters here.
            FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
            List<Flow> activeFlows = FlowHandlerImpl.getActiveFlows(facesContext, flowHandler);
            Flow currentFlow = flowHandler.getCurrentFlow(facesContext);
            Flow targetFlow = calculateTargetFlow(facesContext, outcome, flowHandler, activeFlows, toFlowDocumentId);
            Map<String, List<String>> navigationCaseParameters = navigationCase.getParameters();
            // sourceFlow and targetFlow could both be null so need to have multiple checks here
            if (currentFlow != targetFlow) {
                // Ensure that at least one has a value and check for equality
                if ((currentFlow != null && !currentFlow.equals(targetFlow)) || (targetFlow != null && !targetFlow.equals(currentFlow))) {
                    if (navigationCaseParameters == null) {
                        navigationCaseParameters = new HashMap<>(5, 1f);
                    }
                    // include the following entries:
                    if (currentFlow != null && targetFlow == null) {
                        // Set the TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME parameter
                        navigationCaseParameters.put(FlowHandler.TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME, Arrays.asList(FlowHandler.NULL_FLOW));
                        // Set the FLOW_ID_REQUEST_PARAM_NAME
                        navigationCaseParameters.put(FlowHandler.FLOW_ID_REQUEST_PARAM_NAME, Arrays.asList(""));
                    } else {
                        // If current flow (sourceFlow) is null and new flow (targetFlow) is not null,
                        // include the following entries:
                        // If we make it this far we know the above statement is true due to the other
                        // logical checks we have hit to this point.
                        // Set the TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME parameter
                        navigationCaseParameters.put(FlowHandler.TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME, Arrays.asList((toFlowDocumentId == null ? "" : toFlowDocumentId)));
                        // Set the FLOW_ID_REQUEST_PARAM_NAME
                        navigationCaseParameters.put(FlowHandler.FLOW_ID_REQUEST_PARAM_NAME, Arrays.asList(targetFlow.getId()));
                    }
                }
            }
            ExternalContext externalContext = facesContext.getExternalContext();
            ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
            String toViewId = navigationCase.getToViewId(facesContext);
            String redirectPath = viewHandler.getRedirectURL(facesContext, toViewId, NavigationUtils.getEvaluatedNavigationParameters(facesContext, navigationCaseParameters), navigationCase.isIncludeViewParams());
            // The spec doesn't say anything about how to handle redirect but it is
            // better to apply the transition here where we have already calculated the
            // route than add the parameters and delegate to
            // FlowHandler.clientWindowTransition(facesContext)
            applyFlowTransition(facesContext, navigationContext);
            // Clear ViewMap if we are redirecting to other resource
            UIViewRoot viewRoot = facesContext.getViewRoot();
            if (viewRoot != null && !toViewId.equals(viewRoot.getViewId())) {
                // call getViewMap(false) to prevent unnecessary map creation
                Map<String, Object> viewMap = viewRoot.getViewMap(false);
                if (viewMap != null) {
                    viewMap.clear();
                }
            }
            // JSF 2.0 the javadoc of handleNavigation() says something like this
            // "...If the view has changed after an application action, call
            // PartialViewContext.setRenderAll(true)...". The effect is that ajax requests
            // are included on navigation.
            PartialViewContext partialViewContext = facesContext.getPartialViewContext();
            String viewId = facesContext.getViewRoot() != null ? facesContext.getViewRoot().getViewId() : null;
            if (partialViewContext.isPartialRequest() && !partialViewContext.isRenderAll() && toViewId != null && !toViewId.equals(viewId)) {
                partialViewContext.setRenderAll(true);
            }
            // Dispose view if the view has been marked as disposable by default action listener
            ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
            if (processor != null && processor.isViewPoolEnabledForThisView(facesContext, facesContext.getViewRoot())) {
                processor.disposeView(facesContext, facesContext.getViewRoot());
            }
            // JSF 2.0 Spec call Flash.setRedirect(true) to notify Flash scope and take proper actions
            externalContext.getFlash().setRedirect(true);
            try {
                externalContext.redirect(redirectPath);
                facesContext.responseComplete();
            } catch (IOException e) {
                throw new FacesException(e.getMessage(), e);
            }
        } else {
            ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
            // create new view
            String newViewId = navigationCase.getToViewId(facesContext);
            // JSF 2.0 the javadoc of handleNavigation() says something like this
            // "...If the view has changed after an application action, call
            // PartialViewContext.setRenderAll(true)...". The effect is that ajax requests
            // are included on navigation.
            PartialViewContext partialViewContext = facesContext.getPartialViewContext();
            String viewId = facesContext.getViewRoot() != null ? facesContext.getViewRoot().getViewId() : null;
            if (partialViewContext.isPartialRequest() && !partialViewContext.isRenderAll() && newViewId != null && !newViewId.equals(viewId)) {
                partialViewContext.setRenderAll(true);
            }
            if (facesContext.getViewRoot() != null && facesContext.getViewRoot().getAttributes().containsKey(CALL_PRE_DISPOSE_VIEW)) {
                try {
                    facesContext.getAttributes().put(MyFacesVisitHints.SKIP_ITERATION_HINT, Boolean.TRUE);
                    VisitContext visitContext = VisitContext.createVisitContext(facesContext, null, MyFacesVisitHints.SET_SKIP_ITERATION);
                    facesContext.getViewRoot().visitTree(visitContext, PreDisposeViewCallback.INSTANCE);
                } finally {
                    facesContext.getAttributes().remove(MyFacesVisitHints.SKIP_ITERATION_HINT);
                }
            }
            applyFlowTransition(facesContext, navigationContext);
            // Dispose view if the view has been marked as disposable by default action listener
            ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
            if (processor != null && processor.isViewPoolEnabledForThisView(facesContext, facesContext.getViewRoot())) {
                processor.disposeView(facesContext, facesContext.getViewRoot());
            }
            // create UIViewRoot for new view
            UIViewRoot viewRoot = null;
            String derivedViewId = viewHandler.deriveViewId(facesContext, newViewId);
            if (derivedViewId != null) {
                ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(facesContext, derivedViewId);
                if (vdl != null) {
                    ViewMetadata metadata = vdl.getViewMetadata(facesContext, newViewId);
                    if (metadata != null) {
                        viewRoot = metadata.createMetadataView(facesContext);
                    }
                }
            }
            // - viewHandler.deriveViewId() returned null
            if (viewRoot == null) {
                viewRoot = viewHandler.createView(facesContext, newViewId);
            }
            facesContext.setViewRoot(viewRoot);
            facesContext.renderResponse();
        }
    } else {
        // no navigationcase found, stay on current ViewRoot
        if (log.isLoggable(Level.FINEST)) {
            log.finest("handleNavigation fromAction=" + fromAction + " outcome=" + outcome + " no matching navigation-case found, staying on current ViewRoot");
        }
    }
}
Also used : ViewHandler(jakarta.faces.application.ViewHandler) VisitContext(jakarta.faces.component.visit.VisitContext) IOException(java.io.IOException) ViewDeclarationLanguage(jakarta.faces.view.ViewDeclarationLanguage) ViewPoolProcessor(org.apache.myfaces.view.facelets.ViewPoolProcessor) FacesException(jakarta.faces.FacesException) Flow(jakarta.faces.flow.Flow) NavigationCase(jakarta.faces.application.NavigationCase) ExternalContext(jakarta.faces.context.ExternalContext) List(java.util.List) ArrayList(java.util.ArrayList) PartialViewContext(jakarta.faces.context.PartialViewContext) FlowHandler(jakarta.faces.flow.FlowHandler) UIViewRoot(jakarta.faces.component.UIViewRoot) ViewMetadata(jakarta.faces.view.ViewMetadata)

Example 2 with ViewPoolProcessor

use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.

the class ViewPoolFaceletsTestCase method testDynPageResourceCleanup1.

/**
 * Check remove component resource added using h:outputScript
 *
 * @throws Exception
 */
@Test
public void testDynPageResourceCleanup1() throws Exception {
    facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
    ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
    // Store structure for state checkA=false
    facesContext.getExternalContext().getRequestMap().put("checkA", Boolean.FALSE);
    UIViewRoot root = facesContext.getViewRoot();
    vdl.buildView(facesContext, root, "dynPageResourceCleanup1.xhtml");
    processor.storeViewStructureMetadata(facesContext, root);
    // Store structure for state checkA=true
    facesContext.getExternalContext().getRequestMap().put("checkA", Boolean.TRUE);
    root = new UIViewRoot();
    root.setViewId("/test");
    root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
    facesContext.setViewRoot(root);
    vdl.buildView(facesContext, root, "dynPageResourceCleanup1.xhtml");
    processor.storeViewStructureMetadata(facesContext, root);
    // Try change a view with state checkA=true to checkA=false
    // change set filled view
    facesContext.getAttributes().remove(root);
    facesContext.getExternalContext().getRequestMap().put("checkA", Boolean.FALSE);
    vdl.buildView(facesContext, root, "dynPageResourceCleanup1.xhtml");
    UIComponent headerFacet = root.getFacet("head");
    int oldCount = headerFacet.getChildCount();
    // the resource should still be there
    // Assert.assertEquals(1, oldCount);
    // The code in MYFACES-3659 reset the component after refresh
    Assert.assertEquals(0, oldCount);
    // Clear the view and synchronize resources
    ViewStructureMetadata metadata = processor.retrieveViewStructureMetadata(facesContext, root);
    Assert.assertNotNull(metadata);
    processor.clearTransientAndNonFaceletComponentsForDynamicView(facesContext, root, metadata);
    // the resource added by state checkA=true should not be there
    Assert.assertEquals(0, headerFacet.getChildCount());
}
Also used : UIComponent(jakarta.faces.component.UIComponent) ViewPoolProcessor(org.apache.myfaces.view.facelets.ViewPoolProcessor) UIViewRoot(jakarta.faces.component.UIViewRoot) Test(org.junit.Test)

Example 3 with ViewPoolProcessor

use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.

the class ViewPoolMyFacesRequestTestCase method testStaticPage1_6.

@Test
public void testStaticPage1_6() throws Exception {
    Locale locale = null;
    startViewRequest("/staticPage3.xhtml");
    processLifecycleExecute();
    locale = facesContext.getViewRoot().getLocale();
    facesContext.getViewRoot().getViewMap().put("keyBeforeView", "someBeforeValue");
    executeBeforeRender(facesContext);
    executeBuildViewCycle(facesContext);
    // Use view scope
    Assert.assertEquals("someBeforeValue", facesContext.getViewRoot().getViewMap().get("keyBeforeView"));
    facesContext.getViewRoot().getViewMap().put("someKey", "someValue");
    UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
    executeViewHandlerRender(facesContext);
    executeAfterRender(facesContext);
    client.submit(submitButton);
    processLifecycleExecute();
    executeBeforeRender(facesContext);
    executeBuildViewCycle(facesContext);
    // Check if the view scope value is preserved
    Assert.assertEquals("someValue", facesContext.getViewRoot().getViewMap().get("someKey"));
    facesContext.getViewRoot().getViewMap().put("someKey", "someValue2");
    submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
    executeViewHandlerRender(facesContext);
    executeAfterRender(facesContext);
    client.submit(submitButton);
    processLifecycleExecute();
    executeBeforeRender(facesContext);
    executeBuildViewCycle(facesContext);
    // Check if the view scope value is preserved
    Assert.assertEquals("someValue2", facesContext.getViewRoot().getViewMap().get("someKey"));
    Assert.assertTrue(facesContext.getViewRoot().getChildCount() > 0);
    executeViewHandlerRender(facesContext);
    executeAfterRender(facesContext);
    UIViewRoot root = new UIViewRoot();
    root.setLocale(locale);
    root.setRenderKitId("HTML_BASIC");
    root.setViewId("/staticPage3.xhtml");
    ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
    ViewPool viewPool = processor.getViewPool(facesContext, root);
    ViewEntry entry = viewPool.popStaticOrPartialStructureView(facesContext, root);
    Assert.assertNotNull(entry);
    Assert.assertEquals(RestoreViewFromPoolResult.COMPLETE, entry.getResult());
    endRequest();
}
Also used : Locale(java.util.Locale) UICommand(jakarta.faces.component.UICommand) ViewPoolProcessor(org.apache.myfaces.view.facelets.ViewPoolProcessor) UIViewRoot(jakarta.faces.component.UIViewRoot) Test(org.junit.Test)

Example 4 with ViewPoolProcessor

use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.

the class ViewPoolMyFacesRequestTestCase method testPartialPage1_1.

@Test
public void testPartialPage1_1() throws Exception {
    Locale locale = null;
    startViewRequest("/partialPage1.xhtml");
    processLifecycleExecute();
    locale = facesContext.getViewRoot().getLocale();
    executeBuildViewCycle(facesContext);
    // Now let's try to remove some component programatically
    // that invalidates the view to be reused without a refresh,
    // so in the pool it should be marked as REFRESH_REQUIRED
    UIPanel panel = (UIPanel) facesContext.getViewRoot().findComponent("mainForm:panel1");
    panel.getParent().getChildren().remove(panel);
    UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
    executeViewHandlerRender(facesContext);
    executeAfterRender(facesContext);
    client.submit(submitButton);
    processLifecycleExecute();
    FaceletState faceletState = (FaceletState) facesContext.getViewRoot().getAttributes().get(ComponentSupport.FACELET_STATE_INSTANCE);
    UIViewRoot root = new UIViewRoot();
    root.setLocale(locale);
    root.setRenderKitId("HTML_BASIC");
    root.setViewId("/partialPage1.xhtml");
    ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
    ViewPool viewPool = processor.getViewPool(facesContext, root);
    // Check the view was used
    ViewEntry entry2 = viewPool.popStaticOrPartialStructureView(facesContext, root);
    Assert.assertNull(entry2);
    ViewEntry entry3 = viewPool.popDynamicStructureView(facesContext, root, faceletState);
    Assert.assertNull(entry3);
}
Also used : Locale(java.util.Locale) UIPanel(jakarta.faces.component.UIPanel) UICommand(jakarta.faces.component.UICommand) FaceletState(org.apache.myfaces.view.facelets.tag.faces.FaceletState) ViewPoolProcessor(org.apache.myfaces.view.facelets.ViewPoolProcessor) UIViewRoot(jakarta.faces.component.UIViewRoot) Test(org.junit.Test)

Example 5 with ViewPoolProcessor

use of org.apache.myfaces.view.facelets.ViewPoolProcessor in project myfaces by apache.

the class ViewPoolMyFacesRequestTestCase method testPartialPage1_2.

@Test
public void testPartialPage1_2() throws Exception {
    Locale locale = null;
    startViewRequest("/partialPage1.xhtml");
    processLifecycleExecute();
    locale = facesContext.getViewRoot().getLocale();
    executeBuildViewCycle(facesContext);
    // Now let's try to remove some component programatically
    // that invalidates the view to be reused without a refresh,
    // so in the pool it should be marked as REFRESH_REQUIRED
    UIPanel panel = (UIPanel) facesContext.getViewRoot().findComponent("mainForm:panel1");
    panel.getParent().getChildren().remove(panel);
    facesContext.getViewRoot().getViewMap().put("someKey", "someValue");
    UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
    executeViewHandlerRender(facesContext);
    executeAfterRender(facesContext);
    client.submit(submitButton);
    processLifecycleExecute();
    Assert.assertEquals("someValue", facesContext.getViewRoot().getViewMap().get("someKey"));
    FaceletState faceletState = (FaceletState) facesContext.getViewRoot().getAttributes().get(ComponentSupport.FACELET_STATE_INSTANCE);
    UIViewRoot root = new UIViewRoot();
    root.setLocale(locale);
    root.setRenderKitId("HTML_BASIC");
    root.setViewId("/partialPage1.xhtml");
    ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
    ViewPool viewPool = processor.getViewPool(facesContext, root);
    // Check the view was used
    ViewEntry entry2 = viewPool.popStaticOrPartialStructureView(facesContext, root);
    Assert.assertNull(entry2);
    ViewEntry entry3 = viewPool.popDynamicStructureView(facesContext, root, faceletState);
    Assert.assertNull(entry3);
}
Also used : Locale(java.util.Locale) UIPanel(jakarta.faces.component.UIPanel) UICommand(jakarta.faces.component.UICommand) FaceletState(org.apache.myfaces.view.facelets.tag.faces.FaceletState) ViewPoolProcessor(org.apache.myfaces.view.facelets.ViewPoolProcessor) UIViewRoot(jakarta.faces.component.UIViewRoot) Test(org.junit.Test)

Aggregations

ViewPoolProcessor (org.apache.myfaces.view.facelets.ViewPoolProcessor)54 UIViewRoot (jakarta.faces.component.UIViewRoot)52 Test (org.junit.Test)50 Locale (java.util.Locale)48 UICommand (jakarta.faces.component.UICommand)17 FaceletState (org.apache.myfaces.view.facelets.tag.faces.FaceletState)13 UIPanel (jakarta.faces.component.UIPanel)11 UIOutput (jakarta.faces.component.UIOutput)10 UIComponent (jakarta.faces.component.UIComponent)8 UIForm (jakarta.faces.component.UIForm)5 NavigationCase (jakarta.faces.application.NavigationCase)2 ArrayList (java.util.ArrayList)2 MethodExpression (jakarta.el.MethodExpression)1 FacesException (jakarta.faces.FacesException)1 Application (jakarta.faces.application.Application)1 ConfigurableNavigationHandler (jakarta.faces.application.ConfigurableNavigationHandler)1 NavigationHandler (jakarta.faces.application.NavigationHandler)1 ViewHandler (jakarta.faces.application.ViewHandler)1 ActionSource2 (jakarta.faces.component.ActionSource2)1 VisitContext (jakarta.faces.component.visit.VisitContext)1