Package org.apache.shale.view.faces

Source Code of org.apache.shale.view.faces.LifecycleListener

/*
* 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.shale.view.faces;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shale.view.AbstractApplicationBean;
import org.apache.shale.view.AbstractRequestBean;
import org.apache.shale.view.AbstractSessionBean;
import org.apache.shale.view.Constants;
import org.apache.shale.view.ExceptionHandler;
import org.apache.shale.view.ViewController;


/**
* <p><strong>LifecycleListener</strong> implements the lifecycle startup
* and shutdown calls (<code>init()</code> and <code>destroy()</code>) for
* subclasses of {@link AbstractApplicationBean}, {@link AbstractRequestBean},
* and {@link AbstractSessionBean}.</p>
*
* <p>It must be registered with the servlet container as a listener,
* through an entry in either the <code>/WEB-INF/web.xml</code> resource
* or a tag library descriptor included in the web application.</p>
*
* $Id: LifecycleListener.java 489966 2006-12-24 01:43:42Z craigmcc $
*
* @since 1.0.3
*/
public class LifecycleListener
    implements ServletContextAttributeListener,
               ServletContextListener,
               HttpSessionActivationListener,
               HttpSessionAttributeListener,
               HttpSessionListener,
               ServletRequestAttributeListener,
               ServletRequestListener {


    // ------------------------------------------------------------- Constructor


    /**
     * <p>Create a new lifecycle listener.</p>
     */
    public LifecycleListener() {
        if (log.isInfoEnabled()) {
            log.info("Initializing org.apache.shale.view.faces.LifecycleListener");
        }
    }


    // -------------------------------------------------------- Static Variables


    /**
     * <p>The <code>Log</code> instance for this class.</p>
     */
    private static final Log log = LogFactory.getLog(LifecycleListener.class);


    // ------------------------------------------------------ Manifest Constants


    /**
     * <p>The fully qualified class name of the <em>Tiger Extensions</em>
     * verison of this listener class.</p>
     */
    private static final String TIGER_LISTENER =
            "org.apache.shale.tiger.view.faces.LifecycleListener2";


    // ------------------------------------------------------ Instance Variables


    /**
     * <p>The <em>Tiger Extensions</em> implementation of this listener, if
     * such a class exists in the application classpath.  This value is lazily
     * instantiated.</p>
     */
    private LifecycleListener tiger = null;


    /**
     * <p>Flag indicating whether the <code>tiger</code> value has been calculated
     * already.</p>
     */
    private boolean tigerInitialized = false;


    // ------------------------------------------ ServletContextListener Methods


    /**
     * <p>Respond to a context created event.  No special processing
     * is required.</p>
     *
     * @param event Event to be processed
     */
    public void contextInitialized(ServletContextEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.contextInitialized(event);
        }

    }


    /**
     * <p>Respond to a context destroyed event.  Causes any application
     * scope attribute that implements {@link AbstractApplicationBean}
     * to be removed, triggering an <code>attributeRemoved()</code> event.</p>
     *
     * @param event Event to be processed
     */
    public void contextDestroyed(ServletContextEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.contextDestroyed(event);
        }

        // Remove any AbstractApplicationBean attributes, which will
        // trigger an attributeRemoved event
        List list = new ArrayList();
        Enumeration names = event.getServletContext().getAttributeNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            list.add(name);
        }
        Iterator keys = list.iterator();
        while (keys.hasNext()) {
            String key = (String) keys.next();
            event.getServletContext().removeAttribute(key);
        }

    }


    // --------------------------------- ServletContextAttributeListener Methods


    /**
     * <p>Respond to an application scope attribute being added.  If the
     * value is an {@link AbstractApplicationBean}, call its
     * <code>init()</code> method.</p>
     *
     * @param event Event to be processed
     */
    public void attributeAdded(ServletContextAttributeEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeAdded(event);
            return; // Tiger logic replaces our own
        }

        // If the new value is an AbstractApplicationBean, notify it
        Object value = event.getValue();
        if (value != null) {
            fireApplicationInit(value);
        }

    }


    /**
     * <p>Respond to an application scope attribute being replaced.
     * If the old value was an {@link AbstractApplicationBean}, call
     * its <code>destroy()</code> method.  If the new value is an
     * {@link AbstractApplicationBean}, call its <code>init()</code>
     * method.</p>
     *
     * @param event Event to be processed
     */
    public void attributeReplaced(ServletContextAttributeEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeReplaced(event);
            return; // Tiger logic replaces our own
        }

        // If the old value is an AbstractApplicationBean, notify it
        Object value = event.getValue();
        if (value != null) {
            fireApplicationDestroy(value);
        }

        // If the new value is an AbstractApplicationBean, notify it
        value = event.getServletContext().getAttribute(event.getName());
        if (value != null) {
            fireApplicationInit(value);
        }

    }


    /**
     * <p>Respond to an application scope attribute being removed.
     * If the old value was an {@link AbstractApplicationBean}, call
     * its <code>destroy()</code> method.</p>
     *
     * @param event Event to be processed
     */
    public void attributeRemoved(ServletContextAttributeEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeRemoved(event);
            return; // Tiger logic replaces our own
        }

        // If the old value is an AbstractApplicationBean, notify it
        Object value = event.getValue();
        if (value != null) {
            fireApplicationDestroy(value);
        }

    }


    // --------------------------------------------- HttpSessionListener Methods


    /**
     * <p>Respond to a session created event.  No special processing
     * is required.</p>
     *
     * @param event Event to be processed
     */
    public void sessionCreated(HttpSessionEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.sessionCreated(event);
        }

    }


    /**
     * <p>Respond to a session destroyed event.  Causes any session
     * scope attribute that implements {@link AbstractSessionBean}
     * to be removed, triggering an <code>attributeRemoved()</code> event.</p>
     *
     * @param event Event to be processed
     */
    public void sessionDestroyed(HttpSessionEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.sessionDestroyed(event);
        }

        // Remove any AbstractSessionBean attributes, which will
        // trigger an attributeRemoved event
        List list = new ArrayList();
        try {
            Enumeration names = event.getSession().getAttributeNames();
            while (names.hasMoreElements()) {
                String name = (String) names.nextElement();
                list.add(name);
            }
            Iterator keys = list.iterator();
            while (keys.hasNext()) {
                String key = (String) keys.next();
                event.getSession().removeAttribute(key);
            }
        } catch (IllegalStateException e) {
            // If the session has already been invalidated, there is nothing
            // we can do.  In a Servlet 2.4 or later container, this should not
            // happen, because the event handler is supposed to be called before
            // invalidation occurs, rather than after.
            ;
        }

    }


    // ----------------------------------- HttpSessionActivationListener Methods


    /**
     * <p>Respond to a "session will passivate" event.  Notify all session
     * scope attributes that are {@link AbstractSessionBean}s.</p>
     *
     * @param event Event to be processed
     */
    public void sessionWillPassivate(HttpSessionEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.sessionWillPassivate(event);
            return; // Tiger logic replaces our own
        }

        // Notify any AbstractSessionBean attributes
        Enumeration names = event.getSession().getAttributeNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            Object value = event.getSession().getAttribute(name);
            if (value != null) {
                fireSessionPassivate(value);
            }
        }

    }


    /**
     * <p>Respond to a "session did activate" event.  Notify all session
     * scope attributes that are {@link AbstractSessionBean}s.</p>
     *
     * @param event Event to be processed
     */
    public void sessionDidActivate(HttpSessionEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.sessionDidActivate(event);
            return; // Tiger logic replaces our own
        }

        // Notify any AbstractSessionBean attributes
        Enumeration names = event.getSession().getAttributeNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            Object value = event.getSession().getAttribute(name);
            if (value != null) {
                fireSessionActivate(value);
            }
        }

    }


    // ------------------------------------ HttpSessionAttributeListener Methods


    /**
     * <p>Respond to a session scope attribute being added.  If the
     * value is an {@link AbstractSessionBean}, call its
     * <code>init()</code> method.</p>
     *
     * @param event Event to be processed
     */
    public void attributeAdded(HttpSessionBindingEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeAdded(event);
            return; // Tiger logic replaces our own
        }

        // If the new value is an AbstractSessionBean, notify it
        Object value = event.getValue();
        if (value != null) {
            fireSessionInit(value);
        }

    }


    /**
     * <p>Respond to a session scope attribute being replaced.
     * If the old value was an {@link AbstractSessionBean}, call
     * its <code>destroy()</code> method.  If the new value is an
     * {@link AbstractSessionBean}, call its <code>init()</code>
     * method.</p>
     *
     * @param event Event to be processed
     */
    public void attributeReplaced(HttpSessionBindingEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeReplaced(event);
            return; // Tiger logic replaces our own
        }

        // If the old value is an AbstractSessionBean, notify it
        Object value = event.getValue();
        if (value != null) {
            fireSessionDestroy(value);
        }

        // If the new value is an AbstractSessionBean, notify it
        value = event.getSession().getAttribute(event.getName());
        if (value != null) {
            fireSessionInit(value);
        }

    }


    /**
     * <p>Respond to a session scope attribute being removed.
     * If the old value was an {@link AbstractSessionBean}, call
     * its <code>destroy()</code> method.</p>
     *
     * @param event Event to be processed
     */
    public void attributeRemoved(HttpSessionBindingEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeRemoved(event);
            return; // Tiger logic replaces our own
        }

        // If the old value is an AbstractSessionBean, notify it
        Object value = event.getValue();
        if (value != null) {
            fireSessionDestroy(value);
        }

    }


    // ------------------------------------------ ServletRequestListener Methods


    /**
     * <p>Respond to a request created event.  No special processing
     * is required.</p>
     *
     * @param event Event to be processed
     */
    public void requestInitialized(ServletRequestEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.requestInitialized(event);
        }

    }


    /**
     * <p>Respond to a request destroyed event.  Causes any request
     * scope attribute that implements {@link AbstractRequestBean}
     * or {@link AbstractFragmentBean} to be removed, triggering an
     * <code>attributeRemoved()</code> event.</p>
     *
     * @param event Event to be processed
     */
    public void requestDestroyed(ServletRequestEvent event) {

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.requestDestroyed(event);
            return;
        }

        // Remove any AbstractRequestBean or ViewController attributes,
        // which will trigger an attributeRemoved event
        List list = new ArrayList();
        ServletRequest request = event.getServletRequest();
        Enumeration names = request.getAttributeNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            Object value = request.getAttribute(name);
            if ((value instanceof AbstractRequestBean) || (value instanceof ViewController)) {
                list.add(name);
            }
        }
        Iterator keys = list.iterator();
        while (keys.hasNext()) {
            String key = (String) keys.next();
            event.getServletRequest().removeAttribute(key);
        }

    }


    // --------------------------------- ServletRequestAttributeListener Methods


    /**
     * <p>Respond to a request scope attribute being added.  If the
     * value is an {@link AbstractRequestBean}, call its <code>init()</code> method.
     * </p>
     *
     * @param event Event to be processed
     */
    public void attributeAdded(ServletRequestAttributeEvent event) {

        if (log.isDebugEnabled()) {
            log.debug("ServletRequestAttributeAdded(" + event.getName()
              + "," + event.getValue() + ")");
        }

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeAdded(event);
            return; // Tiger logic replaces our own
        }

        Object value = event.getValue();
        if (value != null) {
            fireRequestInit(value);
        }

    }


    /**
     * <p>Respond to a request scope attribute being replaced.
     * If the old value was an {@link AbstractRequestBean},
     * call its <code>destroy()</code> method.  If the new value is an
     * {@link AbstractRequestBean}, call its <code>init()</code> method.</p>
     *
     * @param event Event to be processed
     */
    public void attributeReplaced(ServletRequestAttributeEvent event) {

        if (log.isDebugEnabled()) {
            log.debug("ServletRequestAttributeReplaced(" + event.getName()
              + "," + event.getValue()
              + "," + event.getServletRequest().getAttribute(event.getName())
              + ")");
        }

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeReplaced(event);
            return; // Tiger logic replaces our own
        }

        Object value = event.getValue();
        if (value != null) {
            fireRequestDestroy(value);
        }

        value = event.getServletRequest().getAttribute(event.getName());
        if (value != null) {
            fireRequestInit(value);
        }

    }


    /**
     * <p>Respond to a request scope attribute being removed.
     * If the old value was an {@link AbstractRequestBean},
     * call its <code>destroy()</code> method.</p>
     *
     * @param event Event to be processed
     */
    public void attributeRemoved(ServletRequestAttributeEvent event) {

        if (log.isDebugEnabled()) {
            log.debug("ServletRequestAttributeRemoved(" + event.getName()
              + "," + event.getValue() + ")");
        }

        // Delegate to the Tiger Extensions instance if it exists
        LifecycleListener tiger = tiger();
        if (tiger != null) {
            tiger.attributeRemoved(event);
            return; // Tiger logic replaces our own
        }

        Object value = event.getValue();
        if (value != null) {
            fireRequestDestroy(value);
        }

    }


    // ------------------------------------------------------- Protected Methods


    /**
     * <p>Fire a destroy event on an @{link AbstractApplicationBean}.</p>
     *
     * @param bean {@link AbstractApplicationBean} to fire event on
     */
    protected void fireApplicationDestroy(Object bean) {

        try {
            if (bean instanceof AbstractApplicationBean) {
                ((AbstractApplicationBean) bean).destroy();
            }
        } catch (Exception e) {
            handleException(FacesContext.getCurrentInstance(), e);
        }

    }


    /**
     * <p>Fire an init event on an {@link AbstractApplicationBean}.</p>
     *
     * @param bean {@link AbstractApplicationBean} to fire event on
     */
    protected void fireApplicationInit(Object bean) {

        try {
            if (bean instanceof AbstractApplicationBean) {
                ((AbstractApplicationBean) bean).init();
            }
        } catch (Exception e) {
            handleException(FacesContext.getCurrentInstance(), e);
        }

    }


    /**
     * <p>Fire a destroy event on an @{link AbstractRequestBean}.</p>
     *
     * @param bean {@link AbstractRequestBean} to fire event on
     */
    protected void fireRequestDestroy(Object bean) {

        try {
            if (bean instanceof AbstractRequestBean) {
                ((AbstractRequestBean) bean).destroy();
            } else if (bean instanceof ViewController) {
                ((ViewController) bean).destroy();
            }
        } catch (Exception e) {
            handleException(FacesContext.getCurrentInstance(), e);
        }

    }


    /**
     * <p>Fire an init event on an {@link AbstractRequestBean}.</p>
     *
     * @param bean {@link AbstractRequestBean} to fire event on
     */
    protected void fireRequestInit(Object bean) {

        try {
            if (bean instanceof AbstractRequestBean) {
                ((AbstractRequestBean) bean).init();
            } else if (bean instanceof ViewController) {
                ((ViewController) bean).init();
            }
        } catch (Exception e) {
            handleException(FacesContext.getCurrentInstance(), e);
        }

    }


    /**
     * <p>Fire an activate event on an @{link AbstractSessionBean}.</p>
     *
     * @param bean {@link AbstractSessionBean} to fire event on
     */
    protected void fireSessionActivate(Object bean) {

        try {
            if (bean instanceof AbstractSessionBean) {
                ((AbstractSessionBean) bean).activate();
            }
        } catch (Exception e) {
            handleException(FacesContext.getCurrentInstance(), e);
        }

    }


    /**
     * <p>Fire a destroy event on an @{link AbstractSessionBean}.</p>
     *
     * @param bean {@link AbstractSessionBean} to fire event on
     */
    protected void fireSessionDestroy(Object bean) {

        try {
            if (bean instanceof AbstractSessionBean) {
                ((AbstractSessionBean) bean).destroy();
            }
        } catch (Exception e) {
            handleException(FacesContext.getCurrentInstance(), e);
        }

    }


    /**
     * <p>Fire an init event on an {@link AbstractSessionBean}.</p>
     *
     * @param bean {@link AbstractSessionBean} to fire event on
     */
    protected void fireSessionInit(Object bean) {

        try {
            if (bean instanceof AbstractSessionBean) {
                ((AbstractSessionBean) bean).init();
            }
        } catch (Exception e) {
            handleException(FacesContext.getCurrentInstance(), e);
        }

    }


    /**
     * <p>Fire an passivate event on an @{link AbstractSessionBean}.</p>
     *
     * @param bean {@link AbstractSessionBean} to fire event on
     */
    protected void fireSessionPassivate(Object bean) {

        try {
            if (bean instanceof AbstractSessionBean) {
                ((AbstractSessionBean) bean).passivate();
            }
        } catch (Exception e) {
            handleException(FacesContext.getCurrentInstance(), e);
        }

    }


    /**
     * <p>Handle the specified exception according to the strategy
     * defined by our current {@link ExceptionHandler}.</p>
     *
     * @param context FacesContext for the current request
     * @param exception Exception to be handled
     */
    protected void handleException(FacesContext context, Exception exception) {

        if (context == null) {
            exception.printStackTrace(System.out);
            return;
        }
        ExceptionHandler handler = (ExceptionHandler)
          context.getApplication().getVariableResolver().resolveVariable
                (context, Constants.EXCEPTION_HANDLER);
        handler.handleException(exception);

    }


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


    /**
     * <p>Return the <em>Tiger Extensions</em> implementation of this listener
     * if one exists; otherwise, return <code>null</code>.</p>
     */
    private LifecycleListener tiger() {

        // If we have already attempted to load the Tiger Extensions version
        // of this class, return the calculated result
        if (tigerInitialized) {
            return tiger;
        }

        // Attempt to load the Tiger Extensions version of this class, and
        // instantiate an appropriate instance
        try {
            Class clazz = this.getClass().getClassLoader().loadClass(TIGER_LISTENER);
            tiger = (LifecycleListener) clazz.newInstance();
        } catch (Exception e) {
            ; // Swallow any class not found or instantiation exception
        }

        // Return the calculated result
        tigerInitialized = true;
        return tiger;

    }


}
TOP

Related Classes of org.apache.shale.view.faces.LifecycleListener

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.