View Javadoc

1   // 
2   //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   //All rights reserved. 
4   //   
5   //Redistribution and use in source and binary forms, with or without modification,  
6   //are permitted provided that the following conditions are met: 
7   //   
8   //* Redistributions of source code must retain the above copyright notice,  
9   //this list of conditions and the following disclaimer. 
10  //* Redistributions in binary form must reproduce the above copyright notice,  
11  //this list of conditions and the following disclaimer in the documentation  
12  //and/or other materials provided with the distribution. 
13  //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //nor the names of its contributors may be used to endorse or promote products  
15  //derived from this software without specific prior written permission. 
16  // 
17  //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  //POSSIBILITY OF SUCH DAMAGE. 
27  //
28  
29  package org.objectledge.i18n.impl;
30  
31  import org.jcontainer.dna.Configuration;
32  import org.jcontainer.dna.ConfigurationException;
33  import org.jcontainer.dna.Logger;
34  import org.objectledge.i18n.I18n;
35  import org.objectledge.utils.StringUtils;
36  
37  import java.util.Collection;
38  import java.util.HashMap;
39  import java.util.HashSet;
40  import java.util.List;
41  import java.util.Locale;
42  import java.util.Map;
43  
44  /**
45   * Base implementation of I18n component.
46   * 
47   * @author <a href="mailto:pablo@caltha.pl">Pawel Potempski</a>
48   * @author <a href="mailto:dgajda@caltha.pl">Damian Gajda</a>
49   * @version $Id: AbstractI18n.java,v 1.22 2006/03/23 09:54:53 pablo Exp $
50   */
51  public abstract class AbstractI18n implements I18n
52  {
53  	/*** undefinied value. */
54  	public static final String DEFAULT_UNDEFINED_VALUE = "[?]";
55  	
56  	/*** default locale. */
57  	public static final String DEFAULT_LOCALE = "en_US";
58      
59      /*** default locale. */
60      public static final String PREFERED_LOCALE = "en_US";
61  	
62  	/*** default setting for locale defaulting. */
63  	public static final boolean DEFAULT_USE_DEFAULT_LOCALE = true;
64  	
65  	/*** default setting for using key as undefinied value. */
66  	public static final boolean DEFAULT_USE_KEY_IF_UNDEFINED = true;
67  	
68  	/*** logger. */
69  	protected Logger logger;
70  	
71  	/*** string returned when a key has no defined value */
72  	private String undefinedValue;
73  
74  	/*** default locale */
75  	private Locale defaultLocale;
76      
77      /*** prefered locale */
78      private Locale preferedLocale;
79      	
80  	/*** use default locale */
81  	private boolean useDefaultLocale;
82  	
83  	/*** use key if undefined switch */
84  	private boolean useKeyIfUndefined;
85  	
86  	/*** the localization bundles map. */
87  	protected Map<String, Map<String, String>> localeMap;
88  	
89  	/*** supported locale. */
90  	protected Locale[] supportedLocales;
91  	
92  	/*** names of the supported locales. */
93  	protected Map<Locale,String> localeNames = new HashMap<Locale,String>();
94  	
95  	/***
96  	 * Component constructor.
97  	 *
98  	 * @param config the configuration.
99  	 * @param logger the logger. 
100      * @throws ConfigurationException if the component configutation is malformed.
101 	 */
102 	public AbstractI18n(Configuration config, Logger logger)
103 		throws ConfigurationException
104 	{
105 		this.logger = logger;
106 		undefinedValue = config.getChild("undefined-value-marker").
107 			getValue(DEFAULT_UNDEFINED_VALUE);
108 		useDefaultLocale = config.getChild("default-locale-fallback").
109 			getAttributeAsBoolean("enabled", DEFAULT_USE_DEFAULT_LOCALE);
110 		useKeyIfUndefined = config.getChild("key-fallback").
111 			getAttributeAsBoolean("enabled", DEFAULT_USE_KEY_IF_UNDEFINED);
112 		localeMap = new HashMap<String, Map<String, String>>();
113 
114 		if(config.getChild("supported-locales", false) != null)
115 		{
116 			Configuration[] locales = config.getChild("supported-locales").getChildren(); 
117 			supportedLocales =  new Locale[locales.length];
118 			for(int i=0; i<locales.length; i++)
119 			{
120 			    supportedLocales[i] = StringUtils.getLocale(locales[i].getValue());
121 			    if(locales[i].getAttributeAsBoolean("default", false))
122 			    {
123 			        defaultLocale = supportedLocales[i];
124 			    }
125                 if(locales[i].getAttributeAsBoolean("prefered", false))
126                 {
127                     preferedLocale = supportedLocales[i];
128                 }
129                 String localeName = locales[i].getAttribute("name", locales[i].getValue());
130 			    localeNames.put(supportedLocales[i], localeName);
131 			}
132 			if(defaultLocale == null && supportedLocales.length > 0)
133 			{
134 			    defaultLocale = supportedLocales[0];
135 			}
136             if(preferedLocale == null)
137             {
138                 preferedLocale = defaultLocale;
139             }
140 		}
141 		else
142 		{
143 		    supportedLocales = new Locale[]{ StringUtils.getLocale(DEFAULT_LOCALE) };
144 		    defaultLocale = StringUtils.getLocale(DEFAULT_LOCALE);
145             preferedLocale = StringUtils.getLocale(PREFERED_LOCALE);
146 		}
147 	}
148 	
149 	/***
150 	 * {@inheritDoc}
151 	 */
152 	public Locale getDefaultLocale()
153 	{
154 		return defaultLocale;
155 	}
156 
157     /***
158      * {@inheritDoc}
159      */
160     public Locale getPreferedLocale()
161     {
162         return preferedLocale;
163     }
164     
165 	/***
166 	 * {@inheritDoc}
167 	 */
168 	public Locale[] getSupportedLocales()
169 	{
170 	    return supportedLocales;
171 	}
172 	
173 	/***
174 	 * {@inheritDoc}
175 	 */
176 	public String getLocaleName(Locale locale)
177 	{
178 	    return (String)localeNames.get(locale);
179 	}
180 	
181     /***
182      * {@inheritDoc}
183      */
184     public boolean defined(Locale locale, String key)
185     {
186         String value = getInternal(locale, key);
187         return value != null;
188     }
189     /***
190      * {@inheritDoc}
191      */
192     public boolean defined(String key)
193     {
194         return defined(this.defaultLocale, key);
195     }
196     
197     /***
198      * {@inheritDoc}
199      */
200     public String get(Locale locale, String key)
201     {
202         String value = getInternal(locale, key);
203         if(value == null)
204         {
205             value = useKeyIfUndefined ? key : undefinedValue;
206         }
207         return value;
208     }
209 
210     /***
211      * {@inheritDoc}
212      */
213     public String get(Locale locale, String key, String defaultValue)
214     {
215         String value = getInternal(locale, key);
216         if(value == null)
217         {
218             value = defaultValue;
219         }
220         return value;
221     }
222     
223     /***
224      * {@inheritDoc}
225      */
226     protected String getInternal(Locale locale, String key)
227     {
228         String value = null;
229         // get selected bundle
230         Map bundle = (Map)localeMap.get(locale.toString());
231         if(bundle != null)
232         {
233             value = (String)bundle.get(key);
234             if(value != null)
235             {
236                 return value;
237             }
238             if(locale.equals(defaultLocale) || !useDefaultLocale)
239             {
240                 return null;
241             }
242         }
243         // get default bundle
244         bundle = (Map)localeMap.get(defaultLocale.toString());
245         if(bundle != null)
246         {
247             value = (String)bundle.get(key);
248         }
249         return value;
250     }
251     
252     /***
253      * {@inheritDoc}
254      */
255     public Collection<String> getKeys(Locale locale)
256     {
257         Map<String, String> bundle = localeMap.get(locale.toString());
258         if(bundle != null)
259         {
260             return bundle.keySet();
261         }
262         return new HashSet<String>();
263     }
264     
265 	/***
266 	 * {@inheritDoc}
267 	 */
268     public String get(Locale locale, String key, String ... values)
269 	{
270 		String template = get(locale, key);
271 		return StringUtils.substitute(template, values);
272 	}
273 
274 	/***
275 	 * {@inheritDoc}
276 	 */
277     public String get(Locale locale, String key, List<String> values)
278 	{
279         String[] strValues = new String[values.size()];
280         values.toArray(strValues);
281 		return get(locale, key, strValues);
282 	}
283     
284 	/***
285 	 * {@inheritDoc}
286 	 */
287 	public abstract void reload();
288 }