Package org.jboss.dashboard.ui.taglib

Source Code of org.jboss.dashboard.ui.taglib.BundleTag$ResourceHelper

/**
* Copyright (C) 2012 JBoss Inc
*
* Licensed 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.jboss.dashboard.ui.taglib;

import org.jboss.dashboard.LocaleManager;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.VariableInfo;
import java.util.Enumeration;
import java.util.Locale;
import java.util.ResourceBundle;

/**
* Custom Tag which is used to provide URLs to invoke panels actions
*/
public class BundleTag extends BaseTag {

    /**
     * Logger
     */
    private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BundleTag.class.getName());

    public static class TEI extends TagExtraInfo {
        /**
         * Returns two VariableInfo objects that define the following
         * body objects
         * <UL>
         * <LI>A variable that represents the current value of the iterator.
         * The name to reference this object is defined in the iterator tag
         * with the value "varName". The type of this object is defined by
         * the "varType" value passed in the iterator tag.
         * </UL>
         *
         * @param data a value of type 'TagData'
         * @return a value of type 'VariableInfo[]'
         */
        public VariableInfo[] getVariableInfo( TagData data )
        {
            String varName = data.getAttributeString("id");
            if ( varName == null ) {
                return new VariableInfo[] {
                };
            } else {
                return new VariableInfo[] {
                        new VariableInfo( varName,
                                "java.util.ResourceBundle",
                                true,
                                VariableInfo.AT_BEGIN ),
                };
            }
        }
    }

    private String         _baseName = null;
    private String         _localeAttribute = null;
    private Locale _locale = null;
    private boolean        _changeResponseLocale = true;
    private ResourceBundle _bundle = null;
    private int            _scope = PageContext.PAGE_SCOPE;
    private boolean        _debug = false;
    private LocaleManager _localeManager = null;


    public BundleTag() {
        _localeManager = LocaleManager.lookup();
    }

    /**
     *  Sets the baseName of the bundle that the MessageTags will use when
     *  retrieving keys for this page.
     */
    public final void setBaseName(String value)
    {
        _baseName = value;
    }

    /**
     *  Set to true to enable debug logging.
     */
    public final void setDebug(boolean value)
    {
        _debug = value;
    }

    /**
     *  Sets the locale of the bundle that the MessageTags will use when
     *  retrieving keys for this page.
     */
    public void setLocale(Locale value)
    {
        _locale = value;
    }

    /**
     *  Provides a key to search the page context for in order to get the
     *  locale of the bundle that the MessageTags will use when retrieving
     *  keys for this page.
     *  @deprecated
     */
    public void setLocaleAttribute(String value)
    {
        _localeAttribute = value;
    }

    /**
     *  Provides a key to search the page context for in order to get the
     *  locale of the bundle that the MessageTags will use when retrieving
     *  keys for this page.
     */
    public void setLocaleRef(String value)
    {
        _localeAttribute = value;
    }

    /**
     *  Sets the scope that the bundle will be available to message tags.
     *  By default page scope is used.
     */
    public void setScope(String value) throws JspException
    {
        if (value == null)
        {
            throw new JspTagException("i18n:bundle tag invalid scope attribute of null");
        }
        else if (value.toLowerCase().equals("application"))
        {
            _scope = PageContext.APPLICATION_SCOPE;
        }
        else if (value.toLowerCase().equals("session"))
        {
            _scope = PageContext.SESSION_SCOPE;
        }
        else if (value.toLowerCase().equals("request"))
        {
            _scope = PageContext.REQUEST_SCOPE;
        }
        else if (value.toLowerCase().equals("page"))
        {
            _scope = PageContext.PAGE_SCOPE;
        }
        else
        {
            throw new JspTagException("i18n:bundle tag invalid scope attribute=" + value);
        }
    }

    /**
     *  Specifies whether or not the response locale should be changed to match
     *  the locale used by this tag.
     */
    public void setChangeResponseLocale(boolean value)
    {
        _changeResponseLocale = value;
    }

    public void release()
    {
        super.release();
        _baseName = null;
        _localeAttribute = null;
        _locale = null;
        _changeResponseLocale = true;
        _bundle = null;
        _scope = PageContext.PAGE_SCOPE;
        _debug = false;
    }

    /**
     * Get the bundle created by this bundle tag, used by nested tags.
     *
     * @return ResourceBundle bundle
     */
    protected final ResourceBundle getBundle()
    {
        return _bundle;
    }

    /**
     *  Locates and prepares a ResourceBundle for use within this request by
     *  message tags.  The bundle is located as specified by the given bundle
     *  name and the user's browser locale settings. The first preferred
     *  locale available that matches at least on basis of language is
     *  used. If an exact match is found for both locale and country, it is used.
     *
     *  Once a preferred locale has been determined for the given bundle name,
     *  the locale is cached in the user's session, so that the above computation
     *  can be avoided the next time the user requests a page with this bundle.
     *  (The entire bundle could be cached in the session, but large bundles would
     *  be problematic in servlet containers that serialize the session to provide
     *  clustering.)
     *
     *  The bundle is obtained using org.jboss.dashboard.LocaleManager#getBunle method
     *  in order to use the custom fallback control for the dashbuilder webapp.
     */
    private void findBundle() throws JspException
    {
        // the bundle name is required. if not provided, throw an exception
        if (_baseName == null) {
            throw new JspTagException(
                    "i18n:bundle tag, a baseName attribute must be specified.");
        }

        // Add a local variable to keep _locale unchanged.
        Locale locale = _locale;

        // if locale not provided, but an attribute was, search for it
        if (locale == null && _localeAttribute != null) {
            locale = (Locale)pageContext.findAttribute(_localeAttribute);
        }

        // if we now have a locale, grab the resource bundle
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        if (locale != null) {
            _bundle = _localeManager.getBundle(_baseName,locale,cl);
            if (_debug) {
                ServletContext sc = pageContext.getServletContext();
                sc.log("i18n:bundle tag debug: found locale " + locale);
            }
        }

        // attempt to load the bundle and compute the locale by looping through
        // the browser's preferred locales; cache the final locale for future use
        else {
            Enumeration localeEnumerator = pageContext.getRequest().getLocales();
            while (localeEnumerator.hasMoreElements()) {
                locale = (Locale)localeEnumerator.nextElement();

                if (_debug) {
                    ServletContext sc = pageContext.getServletContext();
                    sc.log("i18n:bundle tag debug: enumerating locale = " + locale);
                }

                // get a bundle and see whether it has a good locale
                ResourceBundle test = _localeManager.getBundle(_baseName,locale,cl);
                String language = test.getLocale().getLanguage();
                String country = test.getLocale().getCountry();

                // if the requested locale isn't available, the above call will
                // return a bundle with a locale for the same language, or will
                // return the default locale, so we need to compare the locale
                // of the bundle we got back with the one we asked for
                if (test.getLocale().equals(locale)) {
                    // exactly what we were looking for - stop here and use this
                    _bundle = test;
                    break;
                } else if (locale.getLanguage().equals(language)) {
                    // the language matches; see if the country matches as well
                    if (locale.getCountry().equals(country)) {
                        // keep looking but this is a good option. it only gets
                        // better if the variant matches too!  (note: we will only
                        // get to this statement if a variant has been provided)
                        _bundle = test;
                        continue;
                    } else {
                        // if we don't already have a candidate, this is a good
                        // one otherwise, don't change it because the current
                        // candidate might match the country but not the variant
                        if (_bundle == null) {
                            _bundle = test;
                        }
                        continue;
                    }
                } else if (_debug) {
                    ServletContext sc = pageContext.getServletContext();
                    sc.log("i18n:bundle tag requested locale not available: " + locale);
                }
            }

            // bundle should never be null at this point - if the last locale on
            // the list wasn't available, the default locale should have kicked
            // in, but I like being safe, hence the code below.
            if (_bundle == null) {
                _bundle = _localeManager.getBundle(_baseName);
            }

            if (_debug) {
                ServletContext sc = pageContext.getServletContext();
                sc.log("i18n:bundle tag debug: bundle (sensed locale) = " + _bundle);
            }

            // if the localeAttribute was provided, but didn't have a value,
            // go ahead and remember the value for next time
            if (_localeAttribute != null) {
                HttpSession session = pageContext.getSession();
                session.setAttribute(_localeAttribute,_bundle.getLocale());
            }
        }

    }

    /**
     *  Called upon invocation of the tag. If an id is specified, sets the
     *  bundle into the page context.
     */
    public int doStartTag() throws JspException
    {
        // initialize internal member variables
        _bundle = null;
        findBundle();

        if (_debug) {
            ServletContext sc = pageContext.getServletContext();
            sc.log("i18n:bundle tag debug: basename =" + _baseName);
        }

        // set the bundle as a variable in the page
        if (this.getId() != null) {
            pageContext.setAttribute(this.getId(),_bundle);
        }

        return EVAL_BODY_INCLUDE;
    }

    /**
     *  Sets the response locale if changeResponseLocale attribute is true
     */
    public int doEndTag() throws JspException
    {
        if (_changeResponseLocale) {
            // set the locale for the response
            Locale bundleLocale = _bundle.getLocale();
            if ((bundleLocale != null) && !("".equals(bundleLocale.getLanguage()))) {
                pageContext.getResponse().setLocale(bundleLocale);
            }
        }

        // cache the bundle for use by message tags within this request

        ResourceHelper.setBundle(pageContext, _bundle, _scope);

        return EVAL_PAGE;
    }

    public static class ResourceHelper
    {
        public static final String BUNDLE_REQUEST_KEY =
                "org.jboss.dashboard.ui.taglib.BundleTag.ResourceHelper.Bundle";

        /**
         *  Retrieves the bundle cached in the page by a previous call to
         *  getBundle(PageContext,String).  This is used by the MessageTag since
         *  the bundle name is provided once, by the BundleTag.
         *  @return java.util.ResourceBundle the cached bundle
         */
        static public ResourceBundle getBundle(PageContext pageContext)
        {
            return (ResourceBundle)pageContext.findAttribute(BUNDLE_REQUEST_KEY);
        }

        /**
         *  Caches the Bundle in the request using the BUNDLE_REQUEST_KEY.
         */
        static public void setBundle(PageContext pageContext,
                                     ResourceBundle bundle,
                                     int scope)
        {
            // put this in the page so that the getMessage tag can get it quickly
            pageContext.setAttribute(BUNDLE_REQUEST_KEY,bundle,scope);
        }

    }
}
TOP

Related Classes of org.jboss.dashboard.ui.taglib.BundleTag$ResourceHelper

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.