KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > turbine > tool > LocalizationTool


1 package org.apache.turbine.tool;
2
3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Apache" and "Apache Software Foundation" and
29  * "Apache Turbine" must not be used to endorse or promote products
30  * derived from this software without prior written permission. For
31  * written permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * "Apache Turbine", nor may "Apache" appear in their name, without
35  * prior written permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 import java.util.List JavaDoc;
58 import java.util.Locale JavaDoc;
59 import java.util.MissingResourceException JavaDoc;
60
61 import org.apache.fulcrum.TurbineServices;
62 import org.apache.fulcrum.localization.LocalizationService;
63 import org.apache.turbine.RunData;
64 import org.apache.turbine.services.pull.ApplicationTool;
65 import org.apache.turbine.services.yaaficomponent.YaafiComponentService;
66
67 /**
68  * A pull tool which provides lookups for localized text by delegating
69  * to the configured <code>LocalizationService</code>.
70  *
71  * <p><ul>Enhancement(s) suggested by Daniel Rall and Jacopo
72  * Cappellato &lt;jaco@libero.it>:
73  *
74  * <li><ol>Add Language negotiation overrides the following order
75  * <li>user temporary language</li>
76  * <li>user permanent language</li>
77  * <li>application context language</li>
78  * <li>automatic language negotiation (already supported)</li>
79  * </ol></li>
80  *
81  * <li>Missing key message format pulled from TR.props.</li>
82  *
83  * </ul></p>
84  *
85  * @author <a HREF="mailto:dlr@collab.net">Daniel Rall</a>
86  * @author <a HREF="mailto:jon@collab.net">Jon Stevens</a>
87  * @author <a HREF="mailto:leonardr@collab.net">Leonard Richardson</a>
88  */

89 public class LocalizationTool implements ApplicationTool
90 {
91     /**
92      * The language and country information parsed from the request's
93      * <code>Accept-Language</code> header. Reset on each request.
94      */

95     private Locale JavaDoc locale;
96
97     /**
98      * The name of the bundle for this tool to use.
99      */

100     private String JavaDoc bundleName;
101
102     /**
103      * The prefix to prepend to localization keys.
104      */

105     private String JavaDoc keyPrefix;
106
107     /**
108      * Creates a new instance. Used by <code>PullService</code>.
109      */

110     public LocalizationTool()
111     {
112     }
113
114     /**
115      * <p>Performs text lookups for localization.</p>
116      *
117      * <p>Assuming there is a instance of this class with a HTTP
118      * request set in your template's context named <code>l10n</code>,
119      * the VTL <code>$l10n.HELLO</code> would render to
120      * <code>hello</code> for English requests and <code>hola</code>
121      * in Spanish (depending on the value of the HTTP request's
122      * <code>Accept-Language</code> header).</p>
123      *
124      * @param key The identifier for the localized text to retrieve,
125      * prepended by key prefix returned by {@link #getPrefix(String)}
126      * (if not <code>null</code>).
127      * @return The localized text.
128      * @see #get(String, String)
129      */

130     public String JavaDoc get(String JavaDoc key)
131     {
132         return get(null, key);
133     }
134
135     /**
136      * @param prefix A key prefix override which is passed to {@link
137      * #getPrefix(String)}.
138      * @param key The identifier for the localized text to retrieve,
139      * prepended by key prefix (if not <code>null</code>).
140      * @return The localized text.
141      * @see #get(String)
142      */

143     public String JavaDoc get(String JavaDoc prefix, String JavaDoc key)
144     {
145         // Determine prefix, and prepend to key (if necessary).
146
key = applyPrefix(prefix, key);
147
148         try
149         {
150             return getLocalizationService().getString(getBundleName(), getLocale(), key);
151         }
152         catch (MissingResourceException JavaDoc noKey)
153         {
154             return formatErrorMessage(key, noKey);
155         }
156     }
157
158     /**
159      * Gets the current locale.
160      *
161      * @return The locale currently in use.
162      */

163     public Locale JavaDoc getLocale()
164     {
165         return locale;
166     }
167
168     /**
169      * Formats a localized value using the provided object.
170      *
171      * @param key The identifier for the localized text to retrieve,
172      * @param arg1 The object to use as {0} when formatting the localized text.
173      * @return Formatted localized text.
174      * @see #format(String, List)
175      */

176     public String JavaDoc format(String JavaDoc key, Object JavaDoc arg1)
177     {
178         key = applyPrefix(null, key);
179         return getLocalizationService().format(getBundleName(), getLocale(), key, arg1);
180     }
181
182     /**
183      * Formats a localized value using the provided objects.
184      *
185      * @param key The identifier for the localized text to retrieve,
186      * @param arg1 The object to use as {0} when formatting the localized text.
187      * @param arg2 The object to use as {1} when formatting the localized text.
188      * @return Formatted localized text.
189      * @see #format(String, List)
190      */

191     public String JavaDoc format(String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2)
192     {
193         key = applyPrefix(null, key);
194         return getLocalizationService().format(getBundleName(), getLocale(), key,
195                                    arg1, arg2);
196     }
197
198     /**
199      * Formats a localized value using the provided objects.
200      *
201      * @param key The identifier for the localized text to retrieve,
202      * @param args The <code>MessageFormat</code> data used when
203      * formatting the localized text.
204      * @return Formatted localized text.
205      * @see #format(String, List)
206      */

207     public String JavaDoc format(String JavaDoc key, Object JavaDoc[] args)
208     {
209         key = applyPrefix(null, key);
210         return getLocalizationService().format(getBundleName(), getLocale(), key, args);
211     }
212
213     /**
214      * <p>Formats a localized value using the provided objects.</p>
215      *
216      * <p>ResourceBundle:
217      * <blockquote><code><pre>
218      * VelocityUsersNotWrong={0} out of {1} users can't be wrong!
219      * </pre></code></blockquote>
220      *
221      * Template:
222      * <blockquote><code><pre>
223      * $l10n.format("VelocityUsersNotWrong", ["9", "10"])
224      * </pre></code></blockquote>
225      *
226      * Result:
227      * <blockquote><code><pre>
228      * 9 out of 10 Velocity users can't be wrong!
229      * </pre></code></blockquote></p>
230      *
231      * @param key The identifier for the localized text to retrieve,
232      * @param args The objects to use as {0}, {1}, etc. when
233      * formatting the localized text.
234      * @return Formatted localized text.
235      */

236     public String JavaDoc format(String JavaDoc key, List JavaDoc args)
237     {
238         key = applyPrefix(null, key);
239         return getLocalizationService().format(getBundleName(), getLocale(), key,
240                                    args.toArray());
241     }
242
243     /**
244      * The return value of this method is used to set the name of the
245      * bundle used by this tool. Useful as a hook for using a
246      * different bundle than specifed in your
247      * <code>LocalizationService</code> configuration.
248      *
249      * @param data The inputs passed from {@link #init(Object)}.
250      * (ignored by this implementation).
251      */

252     protected String JavaDoc determineBundleName(Object JavaDoc data)
253     {
254         return getLocalizationService().getDefaultBundleName();
255     }
256
257     /**
258      * Returns the name of the bundle currently in use.
259      *
260      * @param The resource bundle name.
261      */

262     protected String JavaDoc getBundleName()
263     {
264         return bundleName;
265     }
266
267     /**
268      * Returns the prefix prepended to keys used to retrieve localized
269      * text. This method could be overridden to introduce separator
270      * text between prefix and key (i.e. <code>prefix__key</code>).
271      *
272      * @param override Overrides the key prefix set for this instance,
273      * or ignored if <code>null</code>.
274      * @return The prefix to prepend to localization keys.
275      */

276     protected String JavaDoc getPrefix(String JavaDoc override)
277     {
278         return (override == null ? keyPrefix : override);
279     }
280
281     /**
282      * Appends the current prefix (if any) to the supplied key.
283      *
284      * @param prefix An override for the current prefix.
285      * @param key The key to apply a prefix to.
286      * @return The prefixed key, or the same key if no prefix.
287      */

288     private String JavaDoc applyPrefix(String JavaDoc prefix, String JavaDoc key)
289     {
290         prefix = getPrefix(prefix);
291         if (prefix != null)
292         {
293             key = prefix + key;
294         }
295         return key;
296     }
297
298     /**
299      * Sets the prefix prepended to keys used to retrieve localized
300      * text. Subclasses may wish to call this method in {@link
301      * #init(Object)} to auto-negotiate a call to this method (thus
302      * automatically setting up the key prefix).
303      *
304      * @param keyPrefix The prefix to prepend to localization keys, or
305      * <code>null</code> for no prefix.
306      */

307     public void setPrefix(String JavaDoc keyPrefix)
308     {
309         this.keyPrefix = keyPrefix;
310     }
311
312     /**
313      * Returns <code>null</code> by default, which causes Velocity to
314      * render your reference literally (i.e. <code>$l10n.FooKey</code>
315      * will render as exactly that). Useful as a hook for providing a
316      * formatted error message.
317      *
318      * <p>TODO: Pull alternate error text from a TR.props value, or
319      * return <code>null</code> if not available.</p>
320      *
321      * @param key The name of the key whose attempted retrieval caused
322      * an error.
323      * @param e The exception thrown when the named key was not
324      * available.
325      */

326     protected String JavaDoc formatErrorMessage(String JavaDoc key, MissingResourceException JavaDoc e)
327     {
328         return null;
329     }
330
331
332     // ------ ApplicationTool implementation -------------------------------
333

334     /**
335      * Sets the request to get the <code>Accept-Language</code> header
336      * from (reset on each request).
337      */

338     public void init(Object JavaDoc data)
339     {
340         if (data instanceof RunData)
341         {
342             // Request-scoped initialization. Pull necessary
343
// information out of RunData while we have a reference to
344
// it.
345
locale = getLocalizationService().getLocale( ((RunData) data).getRequest() );
346         }
347         bundleName = determineBundleName(data);
348     }
349
350     /**
351      * Zero everything out.
352      */

353     public void refresh()
354     {
355         locale = null;
356         bundleName = null;
357         setPrefix(null);
358     }
359     
360     /**
361      * Utility method for accessing the service implementation
362      *
363      * @return a LocalizationService implementation instance
364      */

365     protected static LocalizationService getLocalizationService() {
366         try {
367             YaafiComponentService yaafi = (YaafiComponentService) TurbineServices.getInstance().getService(
368                     YaafiComponentService.SERVICE_NAME);
369             return (LocalizationService) yaafi.lookup(LocalizationService.class.getName());
370         } catch (Exception JavaDoc e) {
371             throw new RuntimeException JavaDoc("Problem looking up localization service", e);
372         }
373     }
374 }
375
Popular Tags