bundletag.java
来自「jakarta-taglibs」· Java 代码 · 共 325 行
JAVA
325 行
/*
* Copyright 1999,2004 The Apache Software Foundation.
*
* 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.apache.taglibs.i18n;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Enumeration;
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.Tag;
import javax.servlet.jsp.tagext.TagSupport;
/**
* This class implements an empty tag that allows you to use a resource
* bundle to internationalize content in a web page. If a specific locale
* is not provided, the user's locale (language and country) are determined
* based on the browser settings. The response content-type is automatically
* set based on the locale.<br>
* This tag must be used very early in the page, prior to any html output.
* <P>
* <H2>Examples</H2>
* <PRE>
* <i18n:bundle basename="test"/>
* etc...
* </PRE>
* <P>
*
* @author <a href="mailto:tdawson@wamnet.com">Tim Dawson</a>
*/
public class BundleTag extends TagSupport
{
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;
/**
* 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.)
*/
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 = ResourceBundle.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 =
ResourceBundle.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 = ResourceBundle.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;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?