Package com.sun.faces.lifecycle

Source Code of com.sun.faces.lifecycle.RestoreViewPhase

/*
* $Id: RestoreViewPhase.java,v 1.53.8.3 2008/04/12 16:32:30 edburns Exp $
*/

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

// RestoreViewPhase.java

package com.sun.faces.lifecycle;

import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.faces.FacesException;
import javax.faces.application.ViewExpiredException;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;

import com.sun.faces.config.WebConfiguration;
import com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.MessageUtils;
import com.sun.faces.util.Util;
import java.util.Collection;
import java.util.Map;
import javax.faces.component.UIViewParameter;
import javax.faces.component.visit.VisitCallback;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PostAddToViewEvent;
import javax.faces.event.PostRestoreStateEvent;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
import javax.faces.view.ViewDeclarationLanguage;
import javax.faces.view.ViewMetadata;

/**
* <B>Lifetime And Scope</B> <P> Same lifetime and scope as
* DefaultLifecycleImpl.
*
* @version $Id: RestoreViewPhase.java,v 1.53.8.3 2008/04/12 16:32:30 edburns Exp $
*/

public class RestoreViewPhase extends Phase {

    private static final String WEBAPP_ERROR_PAGE_MARKER =
            "javax.servlet.error.message";

    private static Logger LOGGER = FacesLogger.LIFECYCLE.getLogger();

    private WebConfiguration webConfig;


    // ---------------------------------------------------------- Public Methods


    public PhaseId getId() {

        return PhaseId.RESTORE_VIEW;

    }


    public void doPhase(FacesContext context,
                        Lifecycle lifecycle,
                        ListIterator<PhaseListener> listeners) {

        Util.getViewHandler(context).initView(context);
        super.doPhase(context, lifecycle, listeners);

    }

    /**
     * PRECONDITION: the necessary factories have been installed in the
     * ServletContext attr set. <P>
     * <p/>
     * POSTCONDITION: The facesContext has been initialized with a tree.
     */

    public void execute(FacesContext facesContext) throws FacesException {

        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.fine("Entering RestoreViewPhase");
        }
        if (null == facesContext) {
            throw new FacesException(MessageUtils.getExceptionMessageString(
                  MessageUtils.NULL_CONTEXT_ERROR_MESSAGE_ID));
        }

        // If an app had explicitely set the tree in the context, use that;
        //
        UIViewRoot viewRoot = facesContext.getViewRoot();
        if (viewRoot != null) {
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.fine("Found a pre created view in FacesContext");
            }
            facesContext.getViewRoot().setLocale(
                 facesContext.getExternalContext().getRequestLocale());

            // do per-component actions
            UIViewRoot root = facesContext.getViewRoot();
            final PostRestoreStateEvent event = new PostRestoreStateEvent(root);
            try {
                root.visitTree(VisitContext.createVisitContext(facesContext),
                        new VisitCallback() {

                    public VisitResult visit(VisitContext context, UIComponent target) {
                        event.setComponent(target);
                        target.processEvent(event);
                        return VisitResult.ACCEPT;
                    }

                });
            } catch (AbortProcessingException e) {
                facesContext.getApplication().publishEvent(facesContext,
                                                           ExceptionQueuedEvent.class,
                                                           new ExceptionQueuedEventContext(facesContext, e));
            }


            if (!facesContext.isPostback()) {
                facesContext.renderResponse();
            }
            return;
        }

        // Reconstitute or create the request tree
        Map requestMap = facesContext.getExternalContext().getRequestMap();
        String viewId = (String)
              requestMap.get("javax.servlet.include.path_info");
        if (viewId == null) {
            viewId = facesContext.getExternalContext().getRequestPathInfo();
        }

        // It could be that this request was mapped using
        // a prefix mapping in which case there would be no
        // path_info.  Query the servlet path.
        if (viewId == null) {
            viewId = (String)
                  requestMap.get("javax.servlet.include.servlet_path");
        }

        if (viewId == null) {
            viewId = facesContext.getExternalContext().getRequestServletPath();
        }

        if (viewId == null) {
            throw new FacesException(MessageUtils.getExceptionMessageString(
                  MessageUtils.NULL_REQUEST_VIEW_ERROR_MESSAGE_ID));
        }

        ViewHandler viewHandler = Util.getViewHandler(facesContext);

        boolean isPostBack = (facesContext.isPostback() && !isErrorPage(facesContext));
        if (isPostBack) {
            facesContext.setProcessingEvents(false);
            // try to restore the view
            viewRoot = viewHandler.restoreView(facesContext, viewId);
            if (viewRoot == null) {
                if (is11CompatEnabled(facesContext)) {
                    // 1.1 -> create a new view and flag that the response should
                    //        be immediately rendered
                    if (LOGGER.isLoggable(Level.FINE)) {
                        LOGGER.fine("Postback: recreating a view for " + viewId);
                    }
                    viewRoot = viewHandler.createView(facesContext, viewId);
                    facesContext.renderResponse();

                } else {
                    Object[] params = {viewId};
                    throw new ViewExpiredException(
                          MessageUtils.getExceptionMessageString(
                                MessageUtils.RESTORE_VIEW_ERROR_MESSAGE_ID,
                                params),
                          viewId);
                }
            }

            facesContext.setViewRoot(viewRoot);
            facesContext.setProcessingEvents(true);
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.fine("Postback: restored view for " + viewId);
            }
        } else {
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.fine("New request: creating a view for " + viewId);
            }

            ViewDeclarationLanguage vdl = facesContext.getApplication().getViewHandler().getViewDeclarationLanguage(facesContext, viewId);

            if (vdl != null) {
                // If we have one, get the ViewMetadata...
                ViewMetadata metadata = vdl.getViewMetadata(facesContext, viewId);

                if (metadata != null) { // perhaps it's not supported
                    // and use it to create the ViewRoot.  This will have, at most
                    // the UIViewRoot and its metadata facet.
                    viewRoot = metadata.createMetadataView(facesContext);

                    // Only skip to render response if there are no view parameters
                    Collection<UIViewParameter> params =
                          ViewMetadata.getViewParameters(viewRoot);
                    if (params.isEmpty()) {
                        facesContext.renderResponse();
                    }
                }
            } else {
                facesContext.renderResponse();
            }

            if (null == viewRoot) {
                viewRoot = (Util.getViewHandler(facesContext)).
                   createView(facesContext, viewId);
            }
            facesContext.setViewRoot(viewRoot);
            assert(null != viewRoot);
            facesContext.getApplication().publishEvent(facesContext,
                                                       PostAddToViewEvent.class,
                                                       viewRoot);
        }

        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.fine("Exiting RestoreViewPhase");
        }

    }

    // --------------------------------------------------------- Private Methods


    /**
     * The Servlet specification states that if an error occurs
     * in the application and there is a matching error-page declaration,
     * the that original request the cause the error is forwarded
     * to the error page.
     *
     * If the error occurred during a post-back and a matching
     * error-page definition was found, then an attempt to restore
     * the error view would be made as the javax.faces.ViewState
     * marker would still be in the request parameters.
     *
     * Use this method to determine if the current request is
     * an error page to avoid the above condition.
     *
     * @param context the FacesContext for the current request
     * @return <code>true</code> if <code>WEBAPP_ERROR_PAGE_MARKER</code>
     *  is found in the request, otherwise return <code>false</code>
     */
    private static boolean isErrorPage(FacesContext context) {

        return (context.getExternalContext().
                    getRequestMap().get(WEBAPP_ERROR_PAGE_MARKER) != null);

    }


    private WebConfiguration getWebConfig(FacesContext context) {

        if (webConfig == null) {
            webConfig = WebConfiguration.getInstance(context.getExternalContext());
        }
        return webConfig;

    }

    private boolean is11CompatEnabled(FacesContext context) {

        return (getWebConfig(context).isOptionEnabled(
              BooleanWebContextInitParameter.EnableRestoreView11Compatibility));
       
    }

    // The testcase for this class is TestRestoreViewPhase.java

} // end of class RestoreViewPhase
TOP

Related Classes of com.sun.faces.lifecycle.RestoreViewPhase

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.