View Javadoc
1   /*
2    * Created on May 19, 2004
3    * 
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    * 
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   * 
14   * Full GNU LGPL license terms : http://www.gnu.org/copyleft/lesser.txt
15   * 
16   * Project : iky-container
17   * Package : net.wmind.commons
18   * Author : mchaplin@users.sourceforge.net
19   */
20  package net.mchaplin.commons.i18n;
21  
22  import java.io.BufferedReader;
23  import java.io.BufferedWriter;
24  import java.io.File;
25  import java.io.FileReader;
26  import java.io.FileWriter;
27  import java.io.IOException;
28  import java.util.HashMap;
29  import java.util.Hashtable;
30  import java.util.Iterator;
31  import java.util.Locale;
32  import java.util.Map;
33  import java.util.ResourceBundle;
34  
35  import net.mchaplin.commons.WmindObject;
36  
37  
38  
39  /***
40   * Helper Class for reading messages from properties file.
41   * Keeps in memory ResourceBundle instances. 
42   * 
43   * @author mchaplin@users.sourceforge.net
44   *
45   * $Header: 
46   * $Revision: 
47   * $Date:
48   */
49  public class PropertyResourceHelper extends WmindObject implements PropertyResourceHelperI {
50      
51      private transient Map<String, ResourceBundle> msgResources = null; // hastable of known ResourceBundle
52      private transient ResourceBundle source = null; // for unique resource bundle use
53      private transient String bundleName = null;
54      
55      /***
56       * Constructor for use
57       * with multiple resource
58       * bundles
59       *
60       */
61      public PropertyResourceHelper() {
62          super();
63          msgResources = new Hashtable<String, ResourceBundle>();
64      }
65      
66      /***
67       * Constructor for usage
68       * with a unique resource bundle
69       * 
70       * @param resource resource bundle name
71       * @param locale ISO-639 locale to use
72       */
73      public PropertyResourceHelper(String resource, String locale) {
74          super();
75          bundleName = resource+locale;
76          source = getBundleFromDisk(resource, locale);
77          if (source != null) {
78              log.info("ResourceBundle ["+bundleName+"] retrieved.");
79          } else {
80              log.warn("Couldn't retrieve ResourceBundle ["+bundleName+"] !");
81          }
82      }
83      
84      /***
85       * Constructor for usage with 
86       * a unique resource bundle
87       * 
88       * @param resource ResourceBundle instance to use
89       */
90      public PropertyResourceHelper(ResourceBundle resource) {
91          source = resource;
92      }
93      
94      /***
95       * To be used in unique resource
96       * bundle mode
97       * 
98       * @param key key to lookup value for
99       * 
100      * @return value of given key
101      */
102     public String getMessage(String key) {
103         String ret = "";
104         if (source != null) {
105             ret = source.getString(key);
106         }
107         log.debug("i18n : ["+bundleName+"."+key+"="+ret+"]");
108         return ret;
109     }
110     
111     
112     /***
113      * Retrieve a message in a properties file according to
114      * the given key
115      * 
116      * @param propsFile name of the property file to load message from
117      * @param key name of the key identifying the message
118      * @return message identified by key or ""
119      */
120     public String getMessage(String propsFile, String key) {
121         return getMessage(propsFile, key, null);
122     }
123     
124     /***
125      * Retrieve a message in a properties file according to
126      * the given key & locale
127      * 
128      * @param propsFile name of the property file to load message from
129      * @param key name of the key identifying the message
130      * @param locale ISO-639 locale to use
131      * @return message identified by key or ""
132      */
133     public String getMessage(String propsFile, String key, String locale) {
134         ResourceBundle props = null;
135         String message = null;
136         if (msgResources.containsKey(propsFile+locale)) {
137             props = (ResourceBundle) msgResources.get(propsFile);
138         } else {
139             props = getBundleFromDisk(propsFile, locale);
140         }
141         message = props.getString(key);
142         log.debug(propsFile+"."+key+"=["+message+"]");
143         return message;
144     }
145 
146     /***
147      * Load a ResourceBundle from Disk
148      * 
149      * @param propsFile name of the property file to load.
150      * @param locale ISO-639 locale to use, if any.
151      * 
152      * @return a ResourceBundle instance or null.
153      */
154     private ResourceBundle getBundleFromDisk(String propsFile, String locale) {
155         ResourceBundle props = null;
156         if (locale != null) {
157             props = ResourceBundle.getBundle(propsFile, new Locale(locale));
158         } else {
159             props = ResourceBundle.getBundle(propsFile);
160         }
161         //locale = props.getLocale().getCountry();
162         
163         if (props != null) {
164             log.debug("Adding ["+propsFile+"("+locale != null ? locale : "unknown_locale"+")] to know properties file list.");    
165             if (msgResources != null) {
166                 msgResources.put(propsFile+locale, props);
167             }
168         }
169         return props;
170     }
171     
172         /***
173      * Write a ResourceBundle from Disk
174      * 
175      * @param fileName
176      *            file name of target Bundle.
177      * @param values
178      *            Hashtable of key/values pair, which will be written in
179      *            key=value format
180      */
181     public static void writeBundleToDisk(String fileName, HashMap<String, String> values) {
182         try {
183             // Let's first add existing entries to Hashtable 'value'
184             
185             File fPersistent = new File(fileName);
186             if (fPersistent.exists()) {
187                 BufferedReader bReader = new BufferedReader(new FileReader(fPersistent));
188                 String sCurLine;
189                 String sKey;
190                 String sValue;
191                 while ((sCurLine = bReader.readLine()) != null) {
192                     int pos = sCurLine.indexOf("=");
193                     sKey = sCurLine.substring(0, pos);
194                     sValue = sCurLine.substring(pos+1);
195                     values.put(sKey, sValue);
196                 }
197                 bReader.close();
198             }
199             
200             // Write hashtable to file
201             BufferedWriter bWriter = new BufferedWriter(new FileWriter(fileName));
202             Iterator<String> keys = values.keySet().iterator();
203             //Iterator<String> elements = values.entrySet().iterator();
204             while (keys.hasNext()) {
205                 String key = (String) keys.next();
206                 //String value = (String) elements.next();
207                 //bWriter.write(key + "=" + value);
208                 bWriter.newLine();
209             }
210             bWriter.close();
211         } catch (IOException e) {
212             // TODO Auto-generated catch block
213             e.printStackTrace();
214         }
215     }
216 
217     public Map<String, ResourceBundle> getMessageResources() {
218         return this.msgResources;
219     }
220     /***
221      * @see net.mchaplin.ioc.ComponentI#reset()
222      */
223     public void reset() {
224         if (msgResources != null) {
225             msgResources = null;
226         }
227         if (source != null) {
228             source = null;
229         }
230     }
231 }