Package de.danet.an.util.jsf

Source Code of de.danet.an.util.jsf.JSFUtil

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2005 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* $Id: JSFUtil.java 2326 2007-03-27 21:59:44Z mlipp $
*
* $Log$
* Revision 1.12  2006/12/12 13:19:08  drmlipp
* Fixed class casting problem in Ajax calls.
*
* Revision 1.11  2006/12/04 14:16:35  drmlipp
* Fixed handler registration.
*
* Revision 1.10  2006/11/24 08:36:54  drmlipp
* Improved listener maintenance.
*
* Revision 1.9  2006/11/23 14:54:31  drmlipp
* Added advanced listener handling.
*
* Revision 1.8  2006/09/29 12:32:11  drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.7  2006/09/08 11:20:40  drmlipp
* Improved error messages.
*
* Revision 1.6  2005/11/10 20:52:55  mlipp
* Fixed problem with classloader dependend Lifecycle access.
*
* Revision 1.5  2005/10/21 15:05:51  drmlipp
* Continued audit event display and cleaned up some things.
*
* Revision 1.4  2005/10/20 09:54:34  drmlipp
* Improved process selection
*
* Revision 1.3  2005/10/18 15:28:42  drmlipp
* Added method.
*
* Revision 1.2  2005/09/16 13:50:03  drmlipp
* Improved.
*
* Revision 1.1  2005/06/20 15:08:26  drmlipp
* Started new JSF utility library.
*
*/
package de.danet.an.util.jsf;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.WeakHashMap;

import javax.faces.FactoryFinder;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.portlet.PortletSession;

import org.apache.commons.collections.map.ReferenceMap;
import org.apache.commons.collections.set.MapBackedSet;

/**
* This class provides some utility method for use with Java Server
* Faces.
*
* @author <a href="mailto:lipp@danet.de">Michael Lipp</a>
* @version $Revision: 2326 $
*/

public class JSFUtil {

    /** Attribute name for accessing lifecycle as request attribue. */
    public static final String LIFECYCLE
        = JSFUtil.class.getName() + ".LIFECYCLE";

    /**
     * Return the active locale.
     * @return the active locale
     */
    public static Locale activeLocale () {
        return FacesContext.getCurrentInstance().getViewRoot().getLocale();
    }

    /**
     * Return a resource bundle for the given base and the given locale.
     * @param baseName the base name of the resource bundle
     * @param locale the locale
     * @return the resource bundle
     * @see #activeLocale
     */
    public static ResourceBundle resourceBundle
        (String baseName, Locale locale) {
        return ResourceBundle.getBundle
            (baseName, locale,
             Thread.currentThread().getContextClassLoader());
    }

    /**
     * Return the resource from the given resource bundle with the given key
     * using the given locale.
     * @param baseName the base name of the resource bundle
     * @param locale the locale
     * @param key the key of the resource
     * @return the resource
     * @see #resourceBundle
     */
    public static String stringResource
        (String baseName, Locale locale, String key) {
        return resourceBundle(baseName, locale).getString (key);
    }
   
    /**
     * Return the resource from the given resource bundle with the given key
     * using the active locale.
     * @param baseName the base name of the resource bundle
     * @param key the key of the resource
     * @return the resource
     * @see #resourceBundle
     */
    public static String stringResource (String baseName, String key) {
        return resourceBundle(baseName, activeLocale()).getString (key);
    }
   
    /**
     * Add a message to the current faces context.
     * @param severity the message severity
     * @param baseName the base name of the resource bundle with messages
     * @param key the key of the message
     * @param args arguments for message formatting
     */
    public static void addMessage
      (FacesMessage.Severity severity, String baseName,
       String key, Object[] args) {
        String res = MessageFormat.format
            (stringResource(baseName, activeLocale(), key), args);
        FacesMessage msg = new FacesMessage (severity, res, res);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
   
    /**
     * Add a message to the current faces context.
     * @param severity the message severity
     * @param baseName the base name of the resource bundle with messages
     * @param key the key of the message
     * @param args arguments for message formatting
     * @param detail detailed information. This string is not localized.
     */
    public static void addMessage
      (FacesMessage.Severity severity, String baseName,
       String key, Object[] args, String detail) {
        String res = MessageFormat.format
            (stringResource(baseName, activeLocale(), key), args);
        FacesMessage msg = new FacesMessage (severity, res, detail);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
   
    /**
     * Add a message to the current faces context.
     * @param severity the message severity
     * @param the locale to use
     * @param baseName the base name of the resource bundle with messages
     * @param key the key of the message
     * @param args arguments for message formatting
     * @param thrown a throwable providing the message details
     */
    public static void addMessage
        (FacesMessage.Severity severity, Locale locale,
        String baseName, String key, Object[] args, Throwable thrown) {
        String res = MessageFormat
            .format(stringResource(baseName, locale, key), args);
        String tm = null;
        synchronized (Locale.class) {
            Locale cur = Locale.getDefault();
            Locale.setDefault(locale);
            tm = thrown.getLocalizedMessage();
            Locale.setDefault(cur);
        }
        tm = tm.trim();
        tm = tm.substring(0, 1).toUpperCase(locale) + tm.substring(1);
        FacesMessage msg
            = new FacesMessage (severity, res, res + " (" + tm + ")");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    /**
     * Add a message to the current faces context.
     * @param severity the message severity
     * @param baseName the base name of the resource bundle with messages
     * @param key the key of the message
     * @param args arguments for message formatting
     * @param thrown a throwable providing the message details
     */
    public static void addMessage
      (FacesMessage.Severity severity, String baseName,
       String key, Object[] args, Throwable thrown) {
        addMessage (severity, activeLocale (), baseName, key, args, thrown);
    }
   
    /**
     * Get the application message with the given key for the active locale.
     * @return the message or <code>null</code> if not found
     */
    public static String getApplicationMessage (String key) {
        String applMsgClass = FacesContext.getCurrentInstance()
            .getApplication().getMessageBundle();
        if (applMsgClass != null) {
            try {
                ResourceBundle bundle = loadResourceBundle(applMsgClass);
                return bundle.getString(key);
            } catch (MissingResourceException e) {
                // fall though
            }
        }
        try {
            ResourceBundle bundle = loadResourceBundle("javax.faces.Messages");
            return bundle.getString(key);
        } catch (MissingResourceException e) {
            // fall though
        }
        return null;
    }

    private static ResourceBundle loadResourceBundle (String baseName) {
        Locale locale= activeLocale();
        try {
            //First we try the JSF implementation class loader
            return ResourceBundle.getBundle
                (baseName, locale,
                 FacesContext.getCurrentInstance().getClass().getClassLoader());
        } catch (MissingResourceException ignore1) {
            // fall through
        }
        try {
            //Next we try the JSF API class loader
            return ResourceBundle.getBundle
                (baseName, locale, FacesContext.class.getClassLoader());
        } catch (MissingResourceException ignore2) {
            // fall through
        }
        //Last resort is the context class loader
        return ResourceBundle.getBundle
            (baseName, locale,
             Thread.currentThread().getContextClassLoader());
    }
   
    /**
     * Return the <code>Lifecycle</code>.
     * @return the result
     */
    public static Lifecycle lifecycle () {
        Lifecycle res = (Lifecycle)FacesContext.getCurrentInstance()
            .getExternalContext().getRequestMap().get(LIFECYCLE);
        if (res != null) {
            return res;
        }
        LifecycleFactory factory = (LifecycleFactory)
            FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
        return factory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
    }
   
    private static final String LISTENER_REGISTERED
        = JSFUtil.class.getName() + "_LISTENER_REGISTERED";
    private static final String LISTENER_REGISTRY
        = JSFUtil.class.getName() + "_LISTENER_REGISTRY";
   
    /**
     * Adds a phase listener that is associated with the invoking
     * portlet instance. Normally, listeners are associated with a lifecycle
     * with one instance for the complete application. If the application
     * consists of several JSF based portlets, listeners are therefore invoked
     * every time one of the portlets goes through the lifecycle.
     * In contrary, listeners registered with the method provided here are
     * only invoked when the registering portlet goes though its lifecycle.
     *
     * In addition, the listeners are maintained using weak references.
     * Omitting the explicit remove therefore does not prevent the listeners
     * from being garbage collected.
     *
     * @param pl the phase listener
     */
    public static void addPhaseListenerForPortlet (PhaseListener pl) {
        PortletSession session = (PortletSession)FacesContext
            .getCurrentInstance().getExternalContext().getSession(true);
        if (session.getAttribute
            (LISTENER_REGISTERED, PortletSession.APPLICATION_SCOPE) == null) {
            Lifecycle lifecycle = lifecycle();
            lifecycle.addPhaseListener(new PhaseListener () {
                public PhaseId getPhaseId () {
                    return PhaseId.ANY_PHASE;
                }
                public void beforePhase (PhaseEvent e) {
                    handleEvent (false, e);
                }
                public void afterPhase (PhaseEvent e) {
                    handleEvent (true, e);
                }
             });
            session.setAttribute(LISTENER_REGISTERED, Boolean.TRUE);
        }
        Set listeners = (Set)session.getAttribute(LISTENER_REGISTRY);
        if (listeners == null) {
            listeners = MapBackedSet.decorate
                (new ReferenceMap (ReferenceMap.WEAK, ReferenceMap.HARD, true),
                 new Object());
            session.setAttribute(LISTENER_REGISTRY, listeners);
        }
        listeners.add (pl);
    }

    private static void handleEvent (boolean after, PhaseEvent e) {
        Object session = FacesContext
            .getCurrentInstance().getExternalContext().getSession(true);
        if (!(session instanceof PortletSession)) {
            // Calling this with ServletSession, must be Ajax call
            return;
        }
        Set listeners
            = (Set)((PortletSession)session).getAttribute(LISTENER_REGISTRY);
        if (listeners == null) {
            return;
        }
        for (Iterator i = listeners.iterator(); i.hasNext();) {
            PhaseListener pl = (PhaseListener)i.next();
            if (pl.getPhaseId() == PhaseId.ANY_PHASE
                || pl.getPhaseId().equals(e.getPhaseId())) {
                if (!after) {
                    pl.beforePhase(e);
                } else {
                    pl.afterPhase(e);
                }
            }
        }
    }
   
    /**
     * Removes a listener associated with the invoking portlet instance.
     *
     * @see #addPhaseListenerForPortlet(PhaseListener)
     * @param pl
     */
    public void removePhaseListenerForPortlet (PhaseListener pl) {
        PortletSession session = (PortletSession)FacesContext
            .getCurrentInstance().getExternalContext().getSession(true);
        Set listeners = (Set)session.getAttribute(LISTENER_REGISTRY);
        if (listeners == null) {
            return;
        }
        listeners.remove(pl);
    }
}
TOP

Related Classes of de.danet.an.util.jsf.JSFUtil

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.