public void buildView()

in impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java [309:532]


    public void buildView(FacesContext context, UIViewRoot view) throws IOException
    {
        if (isFilledView(context, view))
        {
            if (view != null && 
                FaceletViewDeclarationLanguageBase.isDynamicComponentRefreshTransientBuildActive(context, view))
            {
                // don't return
            }
            else
            {
                return;
            }
        }

        String viewId = view.getViewId();

        if (log.isLoggable(Level.FINEST))
        {
            log.finest("Building View: " + viewId);
        }

        boolean usePartialStateSavingOnThisView = _usePartialStateSavingOnThisView(viewId);
        boolean refreshTransientBuild = view.getChildCount() > 0;
        boolean refreshTransientBuildOnPSS = usePartialStateSavingOnThisView && config.isRefreshTransientBuildOnPSS();
        boolean refreshPartialView = false;

        if (viewPoolProcessor != null && !refreshTransientBuild)
        {
            RestoreViewFromPoolResult result = tryRestoreViewFromCache(context, view);
            if (result != null)
            {
                // Since all transient stuff has been removed, add listeners that keep
                // track of tree updates.
                if (RestoreViewFromPoolResult.COMPLETE.equals(result))
                {
                    if (!PhaseId.RESTORE_VIEW.equals(context.getCurrentPhaseId()))
                    {
                        ((PartialStateManagementStrategy) 
                                getStateManagementStrategy(context, view.getViewId())).
                                subscribeListeners(view);
                    }
                    // If the result is complete, the view restored here is static. 
                    // static views can be marked as filled.
                    if (!refreshTransientBuildOnPSS)
                    {
                        // This option will be true on this cases:
                        // -pss is true and refresh is not active
                        setFilledView(context, view);
                    }
                    //At this point refreshTransientBuild = false && refreshTransientBuildOnPSS is true
                    else if (config.isRefreshTransientBuildOnPSSAuto() &&
                             !context.getAttributes().containsKey(CLEAN_TRANSIENT_BUILD_ON_RESTORE))
                    {
                        setFilledView(context, view);
                    }
                    return;
                }
                else
                {
                    // We need to refresh a partial view.
                    refreshTransientBuild = true;
                    refreshPartialView = true;
                }
            }
        }
        
        if (usePartialStateSavingOnThisView)
        {
            // Before apply we need to make sure the current view has
            // a clientId that will be used as a key to save and restore
            // the current view. Note that getClientId is never called (or used)
            // from UIViewRoot.
            if (view.getId() == null)
            {
                view.setId(view.createUniqueId(context, null));
            }

            context.getAttributes().put(USING_PSS_ON_THIS_VIEW, Boolean.TRUE);
            //Add a key to indicate ComponentTagHandlerDelegate to 
            //call UIComponent.markInitialState after it is populated
            if (!refreshTransientBuild || refreshPartialView)
            {
                context.getAttributes().put(StateManager.IS_BUILDING_INITIAL_STATE, Boolean.TRUE);
                context.getAttributes().put(IS_BUILDING_INITIAL_STATE_KEY_ALIAS, Boolean.TRUE);
            }
            if (!refreshTransientBuild && config.isMarkInitialStateWhenApplyBuildView())
            {
                context.getAttributes().put(MARK_INITIAL_STATE_KEY, Boolean.TRUE);
            }
            if (refreshTransientBuildOnPSS)
            {
                //This value is only set when _refreshTransientBuildOnPSSMode is "auto" or "true" 
                context.getAttributes().put(REFRESH_TRANSIENT_BUILD_ON_PSS,
                                            config.isRefreshTransientBuildOnPSSAuto() ? "auto" : "true");
            }
        }

        try
        {
            if (refreshTransientBuild)
            {
                context.getAttributes().put(REFRESHING_TRANSIENT_BUILD, Boolean.TRUE);

                // In theory, this should be disabled on ComponentTagHandlerDelegate,
                // otherwise we could lost PostAddToViewEvent / PreRemoveFromViewEvent
                // caused by c:if effect or facelets cleanup algorithm
                //context.setProcessingEvents(false);
            }
            // populate UIViewRoot
            _getFacelet(context, viewId).apply(context, view);
        }
        finally
        {
            if (refreshTransientBuildOnPSS)
            {
                context.getAttributes().remove(REFRESH_TRANSIENT_BUILD_ON_PSS);
            }
            if (refreshTransientBuild)
            {
                //context.setProcessingEvents(true);
                if (FaceletViewDeclarationLanguageBase.isDynamicComponentRefreshTransientBuildActive(context))
                {
                    VisitContext visitContext = getVisitContextFactory().
                        getVisitContext(context, null, MyFacesVisitHints.SET_SKIP_ITERATION);
                    view.visitTree(visitContext, PublishDynamicComponentRefreshTransientBuildCallback.INSTANCE);
                }
                if (!usePartialStateSavingOnThisView || refreshTransientBuildOnPSS)
                {
                    // When the facelet is applied, all components are removed and added from view,
                    // but the difference resides in the ordering. Since the view is
                    // being refreshed, if we don't do this manually, some tags like
                    // cc:insertChildren or cc:insertFacet will not work correctly, because
                    // we expect PostAddToViewEvent will be propagated from parent to child, and
                    // facelets refreshing algorithm do the opposite.
                    //FaceletViewDeclarationLanguage._publishPreRemoveFromViewEvent(context, view);
                    //FaceletViewDeclarationLanguage._publishPostAddToViewEvent(context, view);
                }

                context.getAttributes().remove(REFRESHING_TRANSIENT_BUILD);
            }
            else
            {
                // Publish PostAddToView over UIViewRoot, because this is not done automatically.
                context.getApplication().publishEvent(context, PostAddToViewEvent.class, UIViewRoot.class, view);
            }
        }

        // set this view as filled
        if (refreshTransientBuild)
        {
            //This option will be true on this cases:
            //- pss is false, but we are refreshing
            //- pss is true, and we are refreshing a view already filled
            setFilledView(context, view);
        }
        else if (!refreshTransientBuildOnPSS)
        {
            // This option will be true on this cases:
            // -pss is true and refresh is not active
            setFilledView(context, view);
        }
        //At this point refreshTransientBuild = false && refreshTransientBuildOnPSS is true
        else if (config.isRefreshTransientBuildOnPSSAuto()
                && !context.getAttributes().containsKey(CLEAN_TRANSIENT_BUILD_ON_RESTORE))
        {
            setFilledView(context, view);
        }

        // Subscribe listeners if we are using partialStateSaving
        if (usePartialStateSavingOnThisView)
        {
            // UIViewRoot.markInitialState() is not called because it does
            // not have a facelet tag handler class that create it, instead
            // new instances are created programmatically.
            if (!refreshTransientBuild || refreshPartialView)
            {
                // Save the state
                if (viewPoolProcessor != null &&
                    viewPoolProcessor.isViewPoolEnabledForThisView(context, view))
                {
                    viewPoolProcessor.storeViewStructureMetadata(context, view);
                }
                if (config.isMarkInitialStateWhenApplyBuildView())
                {
                    if (!refreshTransientBuildOnPSS ||
                        !view.getAttributes().containsKey(COMPONENT_ADDED_AFTER_BUILD_VIEW))
                    {
                        view.markInitialState();
                    }

                    //Remove the key that indicate we need to call UIComponent.markInitialState
                    //on the current tree
                    context.getAttributes().remove(MARK_INITIAL_STATE_KEY);
                }
                else
                {
                    context.getAttributes().put(MARK_INITIAL_STATE_KEY, Boolean.TRUE);
                    _markInitialStateOnView(view, refreshTransientBuildOnPSS);
                    context.getAttributes().remove(MARK_INITIAL_STATE_KEY);
                }
                context.getAttributes().remove(StateManager.IS_BUILDING_INITIAL_STATE);
                context.getAttributes().remove(IS_BUILDING_INITIAL_STATE_KEY_ALIAS);
            }

            // We need to subscribe the listeners of changes in the component tree
            // only the first time here. Later we subscribe this listeners on
            // DefaultFaceletsStateManagement.restoreView, to ensure 
            // relocated components are not retrieved later on getClientIdsRemoved().
            if (!(refreshTransientBuild && PhaseId.RESTORE_VIEW.equals(context.getCurrentPhaseId()))
                    && !view.isTransient())
            {
                ((PartialStateManagementStrategy) getStateManagementStrategy(context, view.getViewId())).
                        subscribeListeners(view);
            }

            context.getAttributes().remove(USING_PSS_ON_THIS_VIEW);
        }

        // Remove this var from faces context because this one prevent AjaxHandler
        // register the standard script library on Post-Redirect-Get pattern or
        // in the next view
        context.getAttributes().remove(AjaxHandler.FACES_JS_DYNAMICALLY_ADDED);
    }