1 /**
2  * The utillib library.
3  * More information is available at http://www.jinchess.com/.
4  * Copyright (C) 2002, 2003 Alexander Maryanovsky.
5  * All rights reserved.
6  *
7  * The utillib library is free software; you can redistribute
8  * it and/or modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * The utillib library is distributed in the hope that it will
13  * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with utillib library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
20  */
21 
22 package free.util;
23 
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.Locale;
27 import java.util.MissingResourceException;
28 import java.util.Properties;
29 
30 
31 
32 /**
33  * A simple localization utility, backed up by a <code>Properties</code> object
34  * loaded from a <code>localization.properties</code> resource.
35  */
36 
37 public class Localization{
38 
39 
40 
41   /**
42    * The locale used for the application.
43    */
44 
45   public static volatile Locale appLocale = Locale.getDefault();
46 
47 
48 
49   /**
50    * The <code>Property</code> object holding the translations.
51    */
52 
53   private final Properties props;
54 
55 
56 
57   /**
58    * The name of the class this <code>Localization</code> is for.
59    */
60 
61   private final String className;
62 
63 
64 
65   /**
66    * Creates a new <code>Localization</code> backed up by the specified
67    * <code>Properties</code> object for the specified class.
68    * The keys in the properties resource are prefixed by the class name.
69    */
70 
Localization(Properties props, String className)71   private Localization(Properties props, String className){
72     this.props = props;
73     this.className = className;
74   }
75 
76 
77 
78   /**
79    * Sets the locale for this application to the specified locale.
80    */
81 
setAppLocale(Locale locale)82   public static void setAppLocale(Locale locale){
83     if (locale == null)
84       throw new IllegalArgumentException("locale may not be null");
85 
86     Localization.appLocale = locale;
87   }
88 
89 
90 
91   /**
92    * Loads and returns a <code>Localization</code> object for the specified
93    * class and the application's locale. See {@link #load(Class, Locale)} and
94    * {@link #setAppLocale(Locale)} for more details.
95    */
96 
load(Class c)97   public static Localization load(Class c){
98     return load(c, appLocale);
99   }
100 
101 
102 
103   /**
104    * Loads and returns a <code>Localization</code> object for the specified
105    * class and locale. The <code>Localization</code> object is loaded from
106    * property resources located in the package of the specified class. The
107    * resources are looked up in the following order, with each one being the
108    * parent of the following one:
109    * <ol>
110    *   <li><code>localization.properties</code>
111    *   <li><code>localization_[language].properties</code>
112    *   <li><code>localization_[language]_[country].properties</code>.
113    *   <li><code>localization_[language]_[country]_[variant].properties</code>.
114    * </ol>
115    * where <code>[language]</code>, <code>[country]</code> and
116    * <code>[variant]</code> are taken from the locale (if the locale provides
117    * them).
118    * Returns <code>null</code> if all of the resources are missing.
119    */
120 
load(Class c, Locale locale)121   public static Localization load(Class c, Locale locale){
122     Properties props = loadTranslationProperties(c, locale);
123     return props == null ? null : new Localization(props, Utilities.getClassName(c));
124   }
125 
126 
127 
128   /**
129    * Loads and returns the translation <code>Properties</code> for the specified class and locale.
130    */
131 
loadTranslationProperties(Class c, Locale locale)132   private static Properties loadTranslationProperties(Class c, Locale locale){
133     String propsFilenamePrefix = "localization";
134     String language = locale.getLanguage();
135     String country = locale.getCountry();
136     String variant = locale.getVariant();
137 
138     Properties props = null;
139 
140     props = loadProps(c, props, propsFilenamePrefix + ".properties");
141 
142     if ((language != null) && !"".equals(language))
143       props = loadProps(c, props, propsFilenamePrefix + "_" + language + ".properties");
144     if ((country != null) && !"".equals(country))
145       props = loadProps(c, props, propsFilenamePrefix + "_" + language + "_" + country + ".properties");
146     if ((variant != null) && !"".equals(variant))
147       props = loadProps(c, props, propsFilenamePrefix + "_" + language + "_" + country + "_" + variant + ".properties");
148 
149     return props;
150   }
151 
152 
153 
154   /**
155    * Loads and returns a <code>Properties</code> object from the resource with the specified name.
156    * The specified <code>Properties</code> object is used as the default delegate for the returned one.
157    */
158 
loadProps(Class c, Properties props, String resourceName)159   private static Properties loadProps(Class c, Properties props, String resourceName){
160     InputStream in = c.getResourceAsStream(resourceName);
161 
162     if (in != null){
163       props = new Properties(props);
164       try{
165         props.load(in);
166       } catch (IOException e){
167           throw new MissingResourceException("IOException while loading " + resourceName, c.getName(), "");
168         }
169     }
170 
171     return props;
172   }
173 
174 
175 
176   /**
177    * Returns the translation for the specified key.
178    */
179 
getString(String key)180   public String getString(String key){
181     return props.getProperty(className + "." + key);
182   }
183 
184 
185 
186   /**
187    * Returns a new <code>Localization</code> object backed up by the same
188    * resources as this one, but for the specified class. This is useful if
189    * several classes (in the same package) share a localization properties
190    * resource.
191    */
192 
getForClass(Class c)193   public Localization getForClass(Class c){
194     return new Localization(props, Utilities.getClassName(c));
195   }
196 
197 
198 
199 }
200