KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > tbutils > res > ResourcesFactory


1 package com.tonbeller.tbutils.res;
2
3 import java.io.File JavaDoc;
4 import java.io.FileInputStream JavaDoc;
5 import java.io.FileNotFoundException JavaDoc;
6 import java.io.IOException JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Locale JavaDoc;
9 import java.util.Map JavaDoc;
10 import java.util.MissingResourceException JavaDoc;
11 import java.util.Properties JavaDoc;
12 import java.util.ResourceBundle JavaDoc;
13 import java.util.StringTokenizer JavaDoc;
14
15 import org.apache.log4j.Logger;
16
17 /**
18  * creates and caches {@link Resources}.
19  * <p>
20  * The factory is configured via four variables that are looked up in
21  * <ol>
22  * <li>in JNDI java:/comp/env context</li>
23  * <li>resfactory.properties in root classpath</li>
24  * <li>System.getProperty()</li>
25  * </ol>
26  * in that order. This may be overridden by defining a java system property
27  * <code>tbeller.initialResourceProvider</code>, for example
28  * <code>-Dtbeller.initialResourceProvider=com.tonbeller.tbutils.res.SystemResourceProvider</code>
29  * will look up the initial variables in System properties only. This is meant
30  * for testing outside the web environment.
31  * <p>
32  *
33  * <dl>
34  *
35  * <dt>tbeller.locale</dt>
36  * <dd>A string either 2 characters (e.g. "en") or 5 chars (e.g. "en_US"). If
37  * present, the application will not care about the browsers locale but use this
38  * locale instead.</dd>
39  *
40  * <dt>tbeller.home</dt>
41  * <dd>A directory that contains configuration files that have been modified by
42  * the customer and other resources. If not set the default is
43  * ${user.home}/.tbeller</dd>
44  *
45  * <dt>tbeller.properties</dt>
46  * <dd>whitespace separated list of property file names, relative to
47  * TBELLER_HOME. These files will be loaded via the file system. Should be
48  * defined in web.xml</dd>
49  *
50  * <dt>tbeller.bundles</dt>
51  * <dd>a whitespace separated list of ResourceBundle names that will be loaded
52  * via ResourceBundle.getBundle. Should be defined in web.xml</dd>
53  *
54  * </dl>
55  *
56  * @author av
57  */

58 public class ResourcesFactory {
59   /**
60    * If there is a ServletContext initParameter this provider will be used
61    * instead of the JNDI Provider.
62    */

63   public static final String JavaDoc INITIAL_PROVIDER = "tbeller.InitialResourceProvider";
64
65   // System Property: wenn "false", wird kein JNDIProvider genommen
66
public static final String JavaDoc USE_JNDI_PROVIDER = "tbeller.usejndi";
67
68   public static final String JavaDoc TBELLER_BUNDLES = "tbeller.bundles";
69
70   public static final String JavaDoc TBELLER_PROPERTIES = "tbeller.properties";
71
72   // env-entries to be overridden by deployer
73
public static final String JavaDoc TBELLER_HOME = "tbeller.home";
74
75   public static final String JavaDoc TBELLER_LOCALE = "tbeller.locale";
76
77   private static Logger logger = Logger.getLogger(ResourcesFactory.class);
78
79   Map JavaDoc locale2providerMap = new HashMap JavaDoc();
80
81   File JavaDoc homeDir;
82
83   Locale JavaDoc fixedLocale;
84
85   String JavaDoc[] properties;
86
87   String JavaDoc[] bundles;
88
89   static ResourcesFactory instance = new ResourcesFactory();
90
91   private ResourcesFactory() {
92     initialize();
93   }
94
95   public static ResourcesFactory instance() {
96     return instance;
97   }
98
99   /**
100    * returns a <code>Resources</code> instance in the configured locale, or if
101    * no locale was configured, in the browsers locale. If the package
102    * <code>packg</code> contains a ResourceBundle named "resources.properties"
103    * that bundle will contained in the returned Resources.
104    */

105   Resources getResources(Locale JavaDoc requestLocale, String JavaDoc bundleName) {
106     Locale JavaDoc locale = fixedLocale;
107     if (locale == null)
108       locale = requestLocale;
109     if (locale == null)
110       locale = Locale.getDefault();
111
112     CompositeResourceProvider crp = new CompositeResourceProvider();
113     ResourceProvider baseProvider = getProvider(locale);
114     crp.add(baseProvider);
115
116     ResourceProvider bundleProvider = getProvider(locale, bundleName);
117     if (bundleProvider != null)
118       crp.add(bundleProvider);
119     
120     return new Resources(crp, locale, homeDir);
121   }
122
123   /**
124    * if the application was configured to use a fixed locale independent of the
125    * browsers locale, returns that locale. Returns null otherwise
126    *
127    * @return locale or null
128    */

129   public Locale JavaDoc getFixedLocale() {
130     return fixedLocale;
131   }
132
133   /**
134    * liefert BundleProvider fuer das Package oder null, wenn kein bundle
135    * vorhanden.
136    */

137   static ResourceProvider getProvider(Locale JavaDoc locale, String JavaDoc bundleName) {
138     if (bundleName == null)
139       return null;
140     try {
141       ResourceBundle JavaDoc resb = ResourceBundle.getBundle(bundleName, locale);
142       return new BundleResourceProvider(bundleName, resb);
143     } catch (MissingResourceException JavaDoc e) {
144       return null;
145     }
146   }
147
148   ResourceProvider getProvider(Locale JavaDoc locale) {
149     String JavaDoc key = locale.getLanguage() + locale.getCountry() + locale.getVariant();
150     ResourceProvider p = (ResourceProvider) locale2providerMap.get(key);
151     if (p != null)
152       return p;
153     p = createProvider(locale);
154     locale2providerMap.put(key, p);
155     return p;
156   }
157
158   void initialize() {
159     ResourceProvider p = getInitialProvider();
160     try {
161       initialize(p);
162     } finally {
163       p.close();
164     }
165   }
166   
167   private ResourceProvider getInitialProvider() {
168     ResourceProvider m = new SimpleInitialProvider();
169     String JavaDoc clazz = m.getString(INITIAL_PROVIDER);
170     if (clazz != null) {
171       try {
172         return (ResourceProvider) Class.forName(clazz).newInstance();
173       } catch (Exception JavaDoc e) {
174         logger.error("could not instantiate " + clazz, e);
175       }
176     }
177     if ("false".equals(m.getString(USE_JNDI_PROVIDER)))
178       return new SimpleInitialProvider();
179     return new JNDIInitialProvider();
180   }
181
182   void initialize(ResourceProvider resp) {
183     locale2providerMap.clear();
184     
185     ResourceProvider p = new ReplacingResourceProvider(resp);
186     bundles = tokenize(p.getString(TBELLER_BUNDLES));
187     
188     // home directory may be overridden in ResourceBundle
189
CompositeResourceProvider c = new CompositeResourceProvider();
190     c.add(p);
191     addBundleProviders(Locale.getDefault(), c);
192     p = new ReplacingResourceProvider(c);
193
194     initHome(p);
195     initLocale(p);
196     properties = tokenize(p.getString(TBELLER_PROPERTIES));
197   }
198
199   String JavaDoc[] tokenize(String JavaDoc s) {
200     if (s == null)
201       return new String JavaDoc[0];
202     StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(s);
203     String JavaDoc[] a = new String JavaDoc[st.countTokens()];
204     for (int i = 0; i < a.length; i++)
205       a[i] = st.nextToken();
206     return a;
207   }
208
209   CompositeResourceProvider createProvider(Locale JavaDoc locale) {
210     CompositeResourceProvider c = new CompositeResourceProvider();
211     c.add(new SystemResourceProvider());
212     addPropertyProviders(locale, c);
213     addBundleProviders(locale, c);
214     return c;
215   }
216
217   /**
218    * @param locale
219    * @param c
220    */

221   private void addPropertyProviders(Locale JavaDoc locale, CompositeResourceProvider c) {
222     for (int i = 0; i < properties.length; i++) {
223       File JavaDoc f = propertyFile(properties[i], locale);
224       Properties JavaDoc props = new Properties JavaDoc();
225       FileInputStream JavaDoc fis = null;
226       try {
227         fis = new FileInputStream JavaDoc(f);
228         props.load(fis);
229         c.add(new PropertyResourceProvider(f.getCanonicalPath(), props));
230       } catch (FileNotFoundException JavaDoc e) {
231         // ignore
232
if (logger.isInfoEnabled())
233           logger.info("optional property file not found: " + f.getAbsolutePath());
234       } catch (IOException JavaDoc e) {
235         logger.error("error loading " + f.getAbsolutePath(), e);
236       } finally {
237         try {
238           if (fis != null)
239             fis.close();
240         } catch (IOException JavaDoc e2) {
241           logger.error("error closing " + f.getAbsolutePath(), e2);
242         }
243       }
244     }
245   }
246
247   File JavaDoc propertyFile(String JavaDoc propertyName, Locale JavaDoc locale) {
248     String JavaDoc fn;
249     File JavaDoc f = new File JavaDoc(propertyName);
250     if (f.isAbsolute())
251       fn = f.getAbsolutePath();
252     else
253       fn = homeDir.getAbsolutePath() + File.separator + propertyName;
254     return findFile(fn, locale);
255   }
256   
257   /**
258    * @param locale
259    * @param c
260    */

261   private void addBundleProviders(Locale JavaDoc locale, CompositeResourceProvider c) {
262     for (int i = 0; i < bundles.length; i++) {
263       try {
264         ResourceBundle JavaDoc rb = ResourceBundle.getBundle(bundles[i], locale);
265         c.add(new BundleResourceProvider(bundles[i], rb));
266       } catch (MissingResourceException JavaDoc e) {
267         // ignore
268
if (logger.isInfoEnabled())
269           logger.info("optional resource bundle not found: " + bundles[i]);
270       }
271     }
272   }
273
274   File JavaDoc findFile(String JavaDoc path, Locale JavaDoc locale) {
275     String JavaDoc ext = "";
276
277     int pos = path.lastIndexOf('.');
278     if (pos >= 0)
279       ext = path.substring(pos, path.length()); // including the dot
280
path = path.substring(0, pos);
281
282     File JavaDoc f = new File JavaDoc(path + "_" + locale.getLanguage() + "_" + locale.getCountry() + ext);
283     if (f.exists())
284       return f;
285
286     f = new File JavaDoc(path + "_" + locale.getLanguage() + ext);
287     if (f.exists())
288       return f;
289
290     return new File JavaDoc(path + ext);
291   }
292
293   void initHome(ResourceProvider p) {
294     String JavaDoc dir = p.getString(TBELLER_HOME);
295     if (dir == null || dir.trim().length() == 0)
296       dir = System.getProperty("user.home") + File.separator + ".tonbeller";
297     homeDir = new File JavaDoc(dir);
298     homeDir.mkdirs();
299   }
300
301   void initLocale(ResourceProvider p) {
302     fixedLocale = null;
303     String JavaDoc lang = p.getString(TBELLER_LOCALE);
304     if (lang != null) {
305       lang = lang.trim();
306       if (lang.length() == 2)
307         fixedLocale = new Locale JavaDoc(lang, lang.toUpperCase());
308       else if (lang.length() == 5) {
309         String JavaDoc l = lang.substring(0, 2);
310         String JavaDoc c = lang.substring(3, 5);
311         fixedLocale = new Locale JavaDoc(l, c);
312       } else if ("browser".equals(lang))
313         ; // use browser settings
314
// else use browser settings too.
315
}
316   }
317
318 }
Popular Tags