View Javadoc

1   package org.apache.velocity.tools.struts;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.List;
23  import java.util.Locale;
24  import org.apache.struts.util.MessageResources;
25  import org.apache.velocity.tools.Scope;
26  import org.apache.velocity.tools.config.DefaultKey;
27  import org.apache.velocity.tools.config.ValidScope;
28  
29  /**
30   * <p>
31   * The MessageTool is used to render internationalized message strings. Source
32   * of the strings are the message resource bundles of the Struts framework. The
33   * following methods operate on these message resources.
34   * </p>
35   *
36   * <p><pre>
37   * Template example(s):
38   *   #if( $text.greeting.exists )
39   *     $text.greeting
40   *   #end
41   *
42   * Toolbox configuration:
43   * &lt;tools&gt;
44   *   &lt;toolbox scope="request"&gt;
45   *     &lt;tool class="org.apache.velocity.tools.struts.MessageTool"/&gt;
46   *   &lt;/toolbox&gt;
47   * &lt;/tools&gt;
48   * </pre></p>
49   *
50   * <p>This tool should only be used in the request scope.</p>
51   *
52   * @author <a href="mailto:sidler@teamup.com">Gabe Sidler</a>
53   * @since VelocityTools 1.0
54   * @version $Id: MessageTool.java 601976 2007-12-07 03:50:51Z nbubna $
55   */
56  @DefaultKey("text")
57  @ValidScope(Scope.REQUEST)
58  public class MessageTool extends MessageResourcesTool
59  {
60      /**
61       * Looks up and returns the localized message for the specified key.
62       * The user's locale is consulted to determine the language of the
63       * message.
64       *
65       * <p><pre>Example use: $text.forms.profile.title</pre></p>
66       *
67       * @param key message key
68       */
69      public TextKey get(String key)
70      {
71          return new TextKey(key, null, null, getLocale());
72      }
73  
74  
75      /**
76       * Looks up and returns the localized message for the specified key.
77       * The user's locale is consulted to determine the language of the
78       * message.
79       *
80       * @param key message key
81       * @param bundle The bundle name to look for.
82       *
83       * @return the localized message for the specified key or
84       * <code>null</code> if no such message exists
85       * @since VelocityTools 1.1
86       */
87      public String get(String key, String bundle)
88      {
89          return get(key, bundle, (Object[])null);
90      }
91  
92  
93      /**
94       * Looks up and returns the localized message for the specified key.
95       * Replacement parameters passed with <code>args</code> are
96       * inserted into the message. The user's locale is consulted to
97       * determine the language of the message.
98       *
99       * @param key message key
100      * @param args replacement parameters for this message
101      *
102      * @return the localized message for the specified key or
103      * <code>null</code> if no such message exists
104      */
105     public String get(String key, Object args[])
106     {
107        return get(key, null, args);
108     }
109 
110     /**
111      * Looks up and returns the localized message for the specified key.
112      * Replacement parameters passed with <code>args</code> are
113      * inserted into the message. The user's locale is consulted to
114      * determine the language of the message.
115      *
116      * @param key message key
117      * @param bundle The bundle name to look for.
118      * @param args replacement parameters for this message
119      * @since VelocityTools 1.1
120      * @return the localized message for the specified key or
121      * <code>null</code> if no such message exists
122      */
123     public String get(String key, String bundle, Object args[])
124     {
125         return this.get(key, bundle, args, getLocale());
126     }
127 
128     /**
129      * Looks up and returns the localized message for the specified key.
130      * Replacement parameters passed with <code>args</code> are
131      * inserted into the message.
132      *
133      * @param key message key
134      * @param bundle The bundle name to look for.
135      * @param args replacement parameters for this message
136      * @param locale The locale to use for this message.
137      *
138      * @return the localized message for the specified key or
139      * <code>null</code> if no such message exists
140      * @since VelocityTools 1.4
141      */
142     public String get(String key, String bundle, Object[] args, Locale locale)
143     {
144         MessageResources res = getResources(bundle);
145         if (res == null)
146         {
147             return null;
148         }
149 
150         // return the requested message
151         if (args == null)
152         {
153             return res.getMessage(locale, key);
154         }
155         else
156         {
157             return res.getMessage(locale, key, args);
158         }
159     }
160 
161     /**
162      * Same as {@link #get(String key, Object[] args)}, but takes a
163      * <code>java.util.List</code> instead of an array. This is more
164      * Velocity friendly.
165      *
166      * @param key message key
167      * @param args replacement parameters for this message
168      *
169      * @return the localized message for the specified key or
170      * <code>null</code> if no such message exists
171      */
172     public String get(String key, List args)
173     {
174         return get(key, null, args);
175     }
176 
177     /**
178      * Same as {@link #get(String key, Object[] args)}, but takes a
179      * <code>java.util.List</code> instead of an array. This is more
180      * Velocity friendly.
181      *
182      * @param key message key
183      * @param bundle The bundle name to look for.
184      * @param args replacement parameters for this message
185      * @since VelocityTools 1.1
186      * @return the localized message for the specified key or
187      * <code>null</code> if no such message exists
188      */
189     public String get(String key, String bundle, List args)
190     {
191         return get(key, bundle, args.toArray());
192     }
193 
194     /**
195      * Looks up and returns the localized message for the specified key.
196      * Replacement parameters passed with <code>args</code> are
197      * inserted into the message.
198      *
199      * @param key message key
200      * @param bundle The bundle name to look for.
201      * @param args replacement parameters for this message
202      * @param locale The locale to use for this message.
203      *
204      * @since VelocityTools 1.4
205      * @return the localized message for the specified key or
206      * <code>null</code> if no such message exists
207      */
208     public String get(String key, String bundle, List args, Locale locale)
209     {
210         return get(key, bundle, args.toArray(), locale);
211     }
212 
213     /**
214      * Checks if a message string for a specified message key exists
215      * for the user's locale.
216      *
217      * @param key message key
218      *
219      * @return <code>true</code> if a message strings exists,
220      * <code>false</code> otherwise
221      */
222     public boolean exists(String key)
223     {
224         return exists(key, null);
225     }
226 
227     /**
228      * Checks if a message string for a specified message key exists
229      * for the user's locale.
230      *
231      * @param key message key
232      * @param bundle The bundle name to look for.
233      * @since VelocityTools 1.1
234      * @return <code>true</code> if a message strings exists,
235      * <code>false</code> otherwise
236      */
237     public boolean exists(String key, String bundle)
238     {
239         MessageResources res = getResources(bundle);
240         if (res == null)
241         {
242             return false;
243         }
244 
245         // Return the requested message presence indicator
246         return res.isPresent(getLocale(), key);
247     }
248 
249 
250     /**
251      * Helper class to simplify tool usage when retrieving
252      * no-arg messages from the default bundle that have periods
253      * in their key.
254      *
255      * <p>So instead of <code>$text.get("forms.profile.title")</code>,1
256      * you can just type <code>$text.forms.profile.title</code>. Also,
257      * this lets you do things like:
258      * <pre>
259      *   #if( $text.forms.profile.exists )
260      *      #set( $profiletext = $text.forms.profile )
261      *      &lt;h1&gt;$profiletext.title&lt;/h1&gt;
262      *      &lt;h3&gt;$profiletext.subtitle&lt;/h3&gt;
263      *   #end
264      * </pre>
265      * </p>
266      *
267      * @since VelocityTools 1.2
268      */
269     public class TextKey
270     {
271         private final String key;
272         private final String bundle;
273         private final Object[] args;
274         private final Locale locale;
275 
276         /**
277          * @since VelocityTools 1.4
278          */
279         public TextKey(String key, String bundle,
280                        Object[] args, Locale locale)
281         {
282             this.key = key;
283             this.bundle = bundle;
284             this.args = args;
285             this.locale = locale;
286         }
287 
288         /**
289          * Appends a period and the new key to the current
290          * key and returns a new TextKey instance with the
291          * combined result as its key.
292          */
293         public TextKey get(String appendme)
294         {
295             StringBuilder sb = new StringBuilder(this.key);
296             sb.append('.');
297             sb.append(appendme);
298             return new TextKey(sb.toString(), this.bundle, this.args, this.locale);
299         }
300 
301         /**
302          * Returns a new TextKey with the specified resource bundle set.
303          * @since VelocityTools 1.3
304          */
305         public TextKey bundle(String setme)
306         {
307             return new TextKey(this.key, setme, this.args, this.locale);
308         }
309 
310         /**
311          * Returns a new TextKey with the specified resource bundle set.
312          * @since VelocityTools 1.4
313          */
314         public TextKey locale(Locale setme)
315         {
316             return new TextKey(this.key, this.bundle, this.args, setme);
317         }
318 
319         /**
320          * Returns a new TextKey with the specified argument
321          * to be inserted into the text output.  If arguments already
322          * exist for this TextKey, the new arguments will be appended
323          * to the old ones in the new TextKey that is returned.
324          *
325          * @since VelocityTools 1.3
326          */
327         public TextKey insert(Object addme)
328         {
329             return insert(new Object[] { addme });
330         }
331 
332         /**
333          * Returns a new TextKey with the specified arguments
334          * to be inserted into the text output.  If arguments already
335          * exist for this TextKey, the new arguments will be appended
336          * to the old ones in the new TextKey that is returned.
337          *
338          * @since VelocityTools 1.3
339          */
340         public TextKey insert(Object addme, Object metoo)
341         {
342             return insert(new Object[] { addme, metoo });
343         }
344 
345         /**
346          * Returns a new TextKey with the specified arguments
347          * to be inserted into the text output.  If arguments already
348          * exist for this TextKey, the new arguments will be appended
349          * to the old ones in the new TextKey that is returned.
350          *
351          * @since VelocityTools 1.3
352          */
353         public TextKey insert(Object addme, Object metoo, Object methree)
354         {
355             return insert(new Object[] { addme, metoo, methree });
356         }
357 
358         /**
359          * Returns a new TextKey with the specified List of arguments
360          * to be inserted into the text output.  If arguments already
361          * exist for this TextKey, the new arguments will be appended
362          * to the old ones in the new TextKey that is returned.
363          *
364          * @since VelocityTools 1.3
365          */
366         public TextKey insert(List addme)
367         {
368             // convert the list to an array
369             Object[] newargs = ((List)addme).toArray();
370             return insert(newargs);
371         }
372 
373         /**
374          * Returns a new TextKey with the specified array of arguments
375          * to be inserted into the text output.  If arguments already
376          * exist for this TextKey, the new arguments will be appended
377          * to the old ones in the new TextKey that is returned.
378          *
379          * @since VelocityTools 1.3
380          */
381         public TextKey insert(Object[] addme)
382         {
383             Object[] newargs;
384             if (this.args == null)
385             {
386                 // we can just use the ones we're adding
387                 newargs = addme;
388             }
389             else
390             {
391                 // create the new array to hold both the new and old ones
392                 newargs = new Object[this.args.length + addme.length];
393                 // copy the old args into the newargs array
394                 System.arraycopy(this.args, 0, newargs, 0, this.args.length);
395                 // copy the args to be inserted into the newargs array
396                 System.arraycopy(addme, 0, newargs, this.args.length, addme.length);
397             }
398             // return an new TextKey
399             return new TextKey(this.key, this.bundle, newargs, this.locale);
400         }
401 
402         /**
403          * This will return a new TextKey that has <b>no</b> arguments to
404          * be inserted into the text output.
405          *
406          * @since VelocityTools 1.3
407          */
408         public TextKey clearArgs()
409         {
410             return new TextKey(this.key, this.bundle, null, this.locale);
411         }
412 
413         /**
414          * Convenience method to allow <code>$text.key.exists</code> syntax.
415          * @since VelocityTools 1.3
416          */
417         public boolean getExists()
418         {
419             return exists();
420         }
421 
422         /**
423          * Checks for the existence of the key that we've built up.
424          * @since VelocityTools 1.3
425          */
426         public boolean exists()
427         {
428             return MessageTool.this.exists(key, bundle);
429         }
430 
431         /**
432          * Renders the text output according to the collected key value,
433          * bundle, and arguments.
434          */
435         public String toString()
436         {
437             return MessageTool.this.get(key, bundle, args, locale);
438         }
439     }
440 
441 }