001: /*
002:
003: ============================================================================
004: The Apache Software License, Version 1.1
005: ============================================================================
006:
007: Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
008:
009: Redistribution and use in source and binary forms, with or without modifica-
010: tion, are permitted provided that the following conditions are met:
011:
012: 1. Redistributions of source code must retain the above copyright notice,
013: this list of conditions and the following disclaimer.
014:
015: 2. Redistributions in binary form must reproduce the above copyright notice,
016: this list of conditions and the following disclaimer in the documentation
017: and/or other materials provided with the distribution.
018:
019: 3. The end-user documentation included with the redistribution, if any, must
020: include the following acknowledgment: "This product includes software
021: developed by the Apache Software Foundation (http://www.apache.org/)."
022: Alternately, this acknowledgment may appear in the software itself, if
023: and wherever such third-party acknowledgments normally appear.
024:
025: 4. The names "Batik" and "Apache Software Foundation" must not be
026: used to endorse or promote products derived from this software without
027: prior written permission. For written permission, please contact
028: apache@apache.org.
029:
030: 5. Products derived from this software may not be called "Apache", nor may
031: "Apache" appear in their name, without prior written permission of the
032: Apache Software Foundation.
033:
034: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
035: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
036: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
037: APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
038: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
039: DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
040: OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
041: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
042: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
043: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
044:
045: This software consists of voluntary contributions made by many individuals
046: on behalf of the Apache Software Foundation. For more information on the
047: Apache Software Foundation, please see <http://www.apache.org/>.
048:
049: */
050:
051: package org.apache.batik.i18n;
052:
053: import java.text.MessageFormat;
054: import java.util.Locale;
055: import java.util.ResourceBundle;
056:
057: /**
058: * This class provides a default implementation of the Localizable interface.
059: * You can use it as a base class or as a member field and delegates various
060: * work to it.<p>
061: * For example, to implement Localizable, the following code can be used:
062: * <pre>
063: * package mypackage;
064: * ...
065: * public class MyClass implements Localizable {
066: * // This code fragment requires a file named
067: * // 'mypackage/resources/Messages.properties', or a
068: * // 'mypackage.resources.Messages' class which extends
069: * // java.util.ResourceBundle, accessible using the current
070: * // classpath.
071: * LocalizableSupport localizableSupport =
072: * new LocalizableSupport("mypackage.resources.Messages");
073: *
074: * public void setLocale(Locale l) {
075: * localizableSupport.setLocale(l);
076: * }
077: * public Local getLocale() {
078: * return localizableSupport.getLocale();
079: * }
080: * public String formatMessage(String key, Object[] args) {
081: * return localizableSupport.formatMessage(key, args);
082: * }
083: * }
084: * </pre>
085: * The algorithm for the Locale lookup in a LocalizableSupport object is:
086: * <ul>
087: * <li>
088: * if a Locale has been set by a call to setLocale(), use this Locale,
089: * else,
090: * <li/>
091: * <li>
092: * if a Locale has been set by a call to the setDefaultLocale() method
093: * of a LocalizableSupport object in the current LocaleGroup, use this
094: * Locale, else,
095: * </li>
096: * <li>
097: * use the object returned by Locale.getDefault() (and set by
098: * Locale.setDefault()).
099: * <li/>
100: * </ul>
101: * This offers the possibility to have a different Locale for each object,
102: * a Locale for a group of object and/or a Locale for the JVM instance.
103: * <p>
104: * Note: if no group is specified a LocalizableSupport object belongs to a
105: * default group common to each instance of LocalizableSupport.
106: *
107: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
108: * @version $Id$
109: */
110: public class LocalizableSupport implements Localizable {
111: /**
112: * The locale group to which this object belongs.
113: */
114: protected LocaleGroup localeGroup = LocaleGroup.DEFAULT;
115:
116: /**
117: * The resource bundle classname.
118: */
119: protected String bundleName;
120:
121: /**
122: * The classloader to use to create the resource bundle.
123: */
124: protected ClassLoader classLoader;
125:
126: /**
127: * The current locale.
128: */
129: protected Locale locale;
130:
131: /**
132: * The locale in use.
133: */
134: protected Locale usedLocale;
135:
136: /**
137: * The resources
138: */
139: protected ResourceBundle resourceBundle;
140:
141: /**
142: * Same as LocalizableSupport(s, null).
143: */
144: public LocalizableSupport(String s) {
145: this (s, null);
146: }
147:
148: /**
149: * Creates a new Localizable object.
150: * The resource bundle class name is required allows the use of custom
151: * classes of resource bundles.
152: * @param s must be the name of the class to use to get the appropriate
153: * resource bundle given the current locale.
154: * @param cl is the classloader used to create the resource bundle,
155: * or null.
156: * @see java.util.ResourceBundle
157: */
158: public LocalizableSupport(String s, ClassLoader cl) {
159: bundleName = s;
160: classLoader = cl;
161: }
162:
163: /**
164: * Implements {@link org.apache.batik.i18n.Localizable#setLocale(Locale)}.
165: */
166: public void setLocale(Locale l) {
167: if (locale != l) {
168: locale = l;
169: resourceBundle = null;
170: }
171: }
172:
173: /**
174: * Implements {@link org.apache.batik.i18n.Localizable#getLocale()}.
175: */
176: public Locale getLocale() {
177: return locale;
178: }
179:
180: /**
181: * Implements {@link
182: * org.apache.batik.i18n.ExtendedLocalizable#setLocaleGroup(LocaleGroup)}.
183: */
184: public void setLocaleGroup(LocaleGroup lg) {
185: localeGroup = lg;
186: }
187:
188: /**
189: * Implements {@link
190: * org.apache.batik.i18n.ExtendedLocalizable#getLocaleGroup()}.
191: */
192: public LocaleGroup getLocaleGroup() {
193: return localeGroup;
194: }
195:
196: /**
197: * Implements {@link
198: * org.apache.batik.i18n.ExtendedLocalizable#setDefaultLocale(Locale)}.
199: * Later invocations of the instance methods will lead to update the
200: * resource bundle used.
201: */
202: public void setDefaultLocale(Locale l) {
203: localeGroup.setLocale(l);
204: }
205:
206: /**
207: * Implements {@link
208: * org.apache.batik.i18n.ExtendedLocalizable#getDefaultLocale()}.
209: */
210: public Locale getDefaultLocale() {
211: return localeGroup.getLocale();
212: }
213:
214: /**
215: * Implements {@link
216: * org.apache.batik.i18n.Localizable#formatMessage(String,Object[])}.
217: */
218: public String formatMessage(String key, Object[] args) {
219: getResourceBundle();
220: return MessageFormat
221: .format(resourceBundle.getString(key), args);
222: }
223:
224: /**
225: * Implements {@link
226: * org.apache.batik.i18n.ExtendedLocalizable#getResourceBundle()}.
227: */
228: public ResourceBundle getResourceBundle() {
229: Locale l;
230:
231: if (resourceBundle == null) {
232: if (locale == null) {
233: if ((l = localeGroup.getLocale()) == null) {
234: usedLocale = Locale.getDefault();
235: } else {
236: usedLocale = l;
237: }
238: } else {
239: usedLocale = locale;
240: }
241: if (classLoader == null) {
242: resourceBundle = ResourceBundle.getBundle(bundleName,
243: usedLocale);
244: } else {
245: resourceBundle = ResourceBundle.getBundle(bundleName,
246: usedLocale, classLoader);
247: }
248: } else if (locale == null) {
249: // Check for group Locale and JVM default locale changes.
250: if ((l = localeGroup.getLocale()) == null) {
251: if (usedLocale != (l = Locale.getDefault())) {
252: usedLocale = l;
253: if (classLoader == null) {
254: resourceBundle = ResourceBundle.getBundle(
255: bundleName, usedLocale);
256: } else {
257: resourceBundle = ResourceBundle.getBundle(
258: bundleName, usedLocale, classLoader);
259: }
260: }
261: } else if (usedLocale != l) {
262: usedLocale = l;
263: if (classLoader == null) {
264: resourceBundle = ResourceBundle.getBundle(
265: bundleName, usedLocale);
266: } else {
267: resourceBundle = ResourceBundle.getBundle(
268: bundleName, usedLocale, classLoader);
269: }
270: }
271: }
272:
273: return resourceBundle;
274: }
275: }
|