alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Struts example source code file (RestoreViewInterceptor.java)

This example Struts source code file (RestoreViewInterceptor.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Struts tags/keywords

bindingaware, class, class, externalcontext, facescontext, facescontext, io, method, reflection, restoreviewinterceptor, string, string, uicomponent, uicomponent, uiinput, util, valuebinding

The Struts RestoreViewInterceptor.java source code

/*
 * $Id: RestoreViewInterceptor.java 651946 2008-04-27 13:41:38Z apetrelli $
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.struts2.jsf;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Iterator;

import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.event.PhaseId;

/**
 * Restores the view or component tree
 */
public class RestoreViewInterceptor extends FacesInterceptor {

    private static final long serialVersionUID = -1500785113037140668L;

    /**
     * Restore View (JSF.2.2.1)
     *
     * @param viewId
     *            The view id
     * @param facesContext
     *            The faces context
     * @return true, if immediate rendering should occur
     */
    protected boolean executePhase(String viewId, FacesContext facesContext) {
        boolean skipFurtherProcessing = false;
        if (log.isTraceEnabled())
            log.trace("entering restoreView");

        informPhaseListenersBefore(facesContext, PhaseId.RESTORE_VIEW);

        try {
            if (isResponseComplete(facesContext, "restoreView", true)) {
                // have to skips this phase
                return true;
            }
            if (shouldRenderResponse(facesContext, "restoreView", true)) {
                skipFurtherProcessing = true;
            }

            ExternalContext externalContext = facesContext.getExternalContext();
            String defaultSuffix = externalContext
                    .getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
            String suffix = defaultSuffix != null ? defaultSuffix
                    : ViewHandler.DEFAULT_SUFFIX;
            if (viewId != null) {
                viewId += suffix;
            }

            if (viewId == null) {
                if (!externalContext.getRequestServletPath().endsWith("/")) {
                    try {
                        externalContext.redirect(externalContext
                                .getRequestServletPath()
                                + "/");
                        facesContext.responseComplete();
                        return true;
                    } catch (IOException e) {
                        throw new FacesException("redirect failed", e);
                    }
                }
            }

            Application application = facesContext.getApplication();
            ViewHandler viewHandler = application.getViewHandler();

            // boolean viewCreated = false;
            UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewId);
            if (viewRoot == null) {
                viewRoot = viewHandler.createView(facesContext, viewId);
                viewRoot.setViewId(viewId);
                facesContext.renderResponse();
                // viewCreated = true;
            }

            facesContext.setViewRoot(viewRoot);

            /*
             * This section has been disabled because it causes some bug. Be
             * careful if you need to re-enable it. Furthermore, for an unknown
             * reason, it seems that by default it is executed (i.e.
             * log.isTraceEnabled() is true). Bug example : This traceView
             * causes DebugUtil.printComponent to print all the attributes of
             * the view components. And if you have a data table within an
             * aliasBean, this causes the data table to initialize it's value
             * attribute while the alias isn't set. So, the value initializes
             * with an UIData.EMPTY_DATA_MODEL, and not with the aliased one.
             * But as it's initialized, it will not try to get the value from
             * the ValueBinding next time it needs to. I expect this to cause
             * more similar bugs. TODO : Completely remove or be SURE by default
             * it's not executed, and it has no more side-effects.
             *
             * if (log.isTraceEnabled()) { //Note: DebugUtils Logger must also
             * be in trace level DebugUtils.traceView(viewCreated ? "Newly
             * created view" : "Restored view"); }
             */

            if (facesContext.getExternalContext().getRequestParameterMap()
                    .isEmpty()) {
                // no POST or query parameters --> set render response flag
                facesContext.renderResponse();
            }

            recursivelyHandleComponentReferencesAndSetValid(facesContext,
                    viewRoot);
        } finally {
            informPhaseListenersAfter(facesContext, PhaseId.RESTORE_VIEW);
        }

        if (isResponseComplete(facesContext, "restoreView", false)
                || shouldRenderResponse(facesContext, "restoreView", false)) {
            // since this phase is completed we don't need to return right away
            // even if the response is completed
            skipFurtherProcessing = true;
        }

        if (!skipFurtherProcessing && log.isTraceEnabled())
            log.trace("exiting restoreView ");
        return skipFurtherProcessing;
    }

    /**
     * Walk the component tree, executing any component-bindings to reattach
     * components to their backing beans. Also, any UIInput component is marked
     * as Valid.
     * <p>
     * Note that this method effectively breaks encapsulation; instead of asking
     * each component to update itself and its children, this method just
     * reaches into each component. That makes it impossible for any component
     * to customise its behaviour at this point.
     * <p>
     * This has been filed as an issue against the spec. Until this issue is
     * resolved, we'll add a new marker-interface for components to allow them
     * to define their interest in handling children bindings themselves.
     */
    protected void recursivelyHandleComponentReferencesAndSetValid(
            FacesContext facesContext, UIComponent parent) {
        recursivelyHandleComponentReferencesAndSetValid(facesContext, parent,
                false);
    }

    protected void recursivelyHandleComponentReferencesAndSetValid(
            FacesContext facesContext, UIComponent parent, boolean forceHandle) {
        Method handleBindingsMethod = getBindingMethod(parent);

        if (handleBindingsMethod != null && !forceHandle) {
            try {
                handleBindingsMethod.invoke(parent, new Object[] {});
            } catch (Throwable th) {
                log.error(
                        "Exception while invoking handleBindings on component with client-id:"
                                + parent.getClientId(facesContext), th);
            }
        } else {
            for (Iterator it = parent.getFacetsAndChildren(); it.hasNext();) {
                UIComponent component = (UIComponent) it.next();

                ValueBinding binding = component.getValueBinding("binding"); // TODO:
                // constant
                if (binding != null && !binding.isReadOnly(facesContext)) {
                    binding.setValue(facesContext, component);
                }

                if (component instanceof UIInput) {
                    ((UIInput) component).setValid(true);
                }

                recursivelyHandleComponentReferencesAndSetValid(facesContext,
                        component);
            }
        }
    }

    /**
     * This is all a hack to work around a spec-bug which will be fixed in
     * JSF2.0
     *
     * @param parent
     * @return true if this component is bindingAware (e.g. aliasBean)
     */
    private static Method getBindingMethod(UIComponent parent) {
        Class[] clazzes = parent.getClass().getInterfaces();

        for (int i = 0; i < clazzes.length; i++) {
            Class clazz = clazzes[i];

            if (clazz.getName().indexOf("BindingAware") != -1) {
                try {
                    return parent.getClass().getMethod("handleBindings",
                            new Class[] {});
                } catch (NoSuchMethodException e) {
                    // return
                }
            }
        }

        return null;
    }
}

Other Struts examples (source code examples)

Here is a short list of links related to this Struts RestoreViewInterceptor.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.