View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.shared_orchestra.util;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  import javax.faces.application.FacesMessage;
25  import javax.faces.application.ApplicationFactory;
26  import javax.faces.application.Application;
27  import javax.faces.context.FacesContext;
28  import javax.faces.FactoryFinder;
29  
30  import java.text.MessageFormat;
31  import java.util.Locale;
32  import java.util.MissingResourceException;
33  import java.util.ResourceBundle;
34  
35  /**
36   * Utility class to support multilingual FacesMessages using ResourceBundles.
37   * Standard messages are stored at <code>DEFAULT_BUNDLE</code>.<br>
38   * The summary of the message is stored at the requested key value. The detail
39   * of the message is stored at &lt;messageId&gt;_detail.
40   *
41   * @see FacesMessage
42   * @see java.util.ResourceBundle
43   *
44   * @author Thomas Spiegl (latest modification by $Author: lu4242 $)
45   * @author Manfred Geiler
46   * @author Sean Schofield
47   * @author Stpehan Strittmatter
48   * @version $Revision: 940132 $ $Date: 2010-05-01 20:29:23 -0500 (Sat, 01 May 2010) $
49   */
50  public final class MessageUtils
51  {
52      /** Utility class, do not instatiate */
53      private MessageUtils()
54      {
55          // nope
56      }
57  
58      /** Default bundle for messages (<code>javax.faces.Messages</code>) */
59      private static final String DEFAULT_BUNDLE = "javax.faces.Messages";
60  
61      /** Suffix for message details (<code>_detail</code>)*/
62      private static final String DETAIL_SUFFIX = "_detail";
63      private static Log log = LogFactory.getLog(MessageUtils.class);
64  
65      /**
66       * @param severity serverity of message
67       * @param messageId id of message
68       * @param arg arument of message
69       *
70       * @return generated FacesMessage
71       */
72      public static FacesMessage getMessage(FacesMessage.Severity severity,
73                                            String messageId,
74                                            Object arg)
75      {
76          return getMessage(severity,
77                            messageId,
78                            new Object[]{arg},
79                            FacesContext.getCurrentInstance());
80      }
81      
82      public static FacesMessage getMessage(String bundleBaseName, 
83              FacesMessage.Severity severity,
84              String messageId,
85              Object arg)
86      {
87          return getMessage(bundleBaseName,
88                            severity,
89                            messageId,
90                            new Object[]{arg},
91                            FacesContext.getCurrentInstance());
92      }
93  
94      /**
95       * @param severity serverity of message
96       * @param messageId id of message
97       * @param args aruments of message
98       *
99       * @return generated FacesMessage
100      */
101     public static FacesMessage getMessage(FacesMessage.Severity severity,
102                                           String messageId,
103                                           Object[] args)
104     {
105         return getMessage(severity,
106                           messageId,
107                           args,
108                           FacesContext.getCurrentInstance());
109     }
110     
111     public static FacesMessage getMessage(String bundleBaseName, 
112             FacesMessage.Severity severity,
113             String messageId,
114             Object[] args)
115     {
116         return getMessage(bundleBaseName,
117                           severity,
118                           messageId,
119                           args,
120                           FacesContext.getCurrentInstance());
121     }    
122 
123     public static FacesMessage getMessage(FacesMessage.Severity severity,
124                                           String messageId,
125                                           Object[] args,
126                                           FacesContext facesContext)
127     {
128         FacesMessage message = getMessage(facesContext, messageId, args);
129         message.setSeverity(severity);
130 
131         return message;
132     }
133 
134     public static FacesMessage getMessage(String bundleBaseName,
135             FacesMessage.Severity severity,
136             String messageId,
137             Object[] args,
138             FacesContext facesContext)
139     {
140         FacesMessage message = getMessage(bundleBaseName, facesContext, messageId, args);
141         message.setSeverity(severity);
142         
143         return message;
144     }
145 
146     public static void addMessage(FacesMessage.Severity severity,
147                                   String messageId,
148                                   Object[] args)
149     {
150         addMessage(severity, messageId, args, null, FacesContext.getCurrentInstance());
151     }
152 
153     public static void addMessage(String bundleBaseName, 
154             FacesMessage.Severity severity,
155             String messageId,
156             Object[] args)
157     {
158         addMessage(bundleBaseName, severity, messageId, args, null, FacesContext.getCurrentInstance());
159     }
160 
161     public static void addMessage(FacesMessage.Severity severity,
162                                   String messageId,
163                                   Object[] args,
164                                   FacesContext facesContext)
165     {
166         addMessage(severity, messageId, args, null, facesContext);
167     }
168 
169     public static void addMessage(String bundleBaseName, 
170             FacesMessage.Severity severity,
171             String messageId,
172             Object[] args,
173             FacesContext facesContext)
174     {
175         addMessage(bundleBaseName, severity, messageId, args, null, facesContext);
176     }
177 
178     public static void addMessage(FacesMessage.Severity severity,
179                                   String messageId,
180                                   Object[] args,
181                                   String forClientId)
182     {
183         addMessage(severity, messageId, args, forClientId, FacesContext.getCurrentInstance());
184     }
185 
186     public static void addMessage(String bundleBaseName,
187             FacesMessage.Severity severity,
188             String messageId,
189             Object[] args,
190             String forClientId)
191     {
192         addMessage(bundleBaseName, severity, messageId, args, forClientId, FacesContext.getCurrentInstance());
193     }
194 
195     public static void addMessage(FacesMessage.Severity severity,
196                                   String messageId,
197                                   Object[] args,
198                                   String forClientId,
199                                   FacesContext facesContext)
200     {
201         if(log.isTraceEnabled()) {
202           log.trace("adding message " + messageId + " for clientId " + forClientId);
203         }
204         facesContext.addMessage(forClientId,
205                                 getMessage(severity, messageId, args, facesContext));
206     }
207 
208     public static void addMessage(String bundleBaseName,
209             FacesMessage.Severity severity,
210             String messageId,
211             Object[] args,
212             String forClientId,
213             FacesContext facesContext)
214     {
215         if(log.isTraceEnabled()) {
216         log.trace("adding message " + messageId + " for clientId " + forClientId);
217         }
218         facesContext.addMessage(forClientId,
219                   getMessage(bundleBaseName, severity, messageId, args, facesContext));
220     }
221 
222     /**
223      * Uses <code>MessageFormat</code> and the supplied parameters to fill in the param placeholders in the String.
224      *
225      * @param locale The <code>Locale</code> to use when performing the substitution.
226      * @param msgtext The original parameterized String.
227      * @param params The params to fill in the String with.
228      * @return The updated String.
229      */
230     public static String substituteParams(Locale locale, String msgtext, Object params[])
231     {
232         String localizedStr = null;
233         if(params == null || msgtext == null)
234             return msgtext;
235 
236         if(locale != null)
237         {
238             MessageFormat mf = new MessageFormat(msgtext,locale);            
239             localizedStr = mf.format(params);
240         }
241         return localizedStr;
242     }
243 
244     public static FacesMessage getMessage(String messageId, Object params[])
245     {
246         Locale locale = getCurrentLocale();
247         return getMessage(locale, messageId, params);
248     }
249 
250     public static FacesMessage getMessageFromBundle(String bundleBaseName, String messageId, Object params[])
251     {
252         Locale locale = null;
253         FacesContext context = FacesContext.getCurrentInstance();
254         if(context != null && context.getViewRoot() != null)
255         {
256             locale = context.getViewRoot().getLocale();
257             if(locale == null)
258                 locale = Locale.getDefault();
259         } else
260         {
261             locale = Locale.getDefault();
262         }
263         return getMessageFromBundle(bundleBaseName, context , locale, messageId, params);
264     }
265 
266     public static FacesMessage getMessage(Locale locale, String messageId, Object params[])
267     {
268         String summary = null;
269         String detail = null;
270         String bundleName = getApplication().getMessageBundle();
271         ResourceBundle bundle = null;
272 
273         if (bundleName != null)
274         {
275             try
276             {
277                 bundle = ResourceBundle.getBundle(bundleName, locale, org.apache.myfaces.shared_orchestra.util.ClassUtils.getCurrentLoader(bundleName));
278                 summary = bundle.getString(messageId);
279             }
280             catch (MissingResourceException e) {
281                 // NoOp
282             }
283         }
284 
285         if (summary == null)
286         {
287             try
288             {
289                 bundle = ResourceBundle.getBundle(DEFAULT_BUNDLE, locale, org.apache.myfaces.shared_orchestra.util.ClassUtils.getCurrentLoader(DEFAULT_BUNDLE));
290                 if(bundle == null)
291                 {
292                     throw new NullPointerException();
293                 }
294                 summary = bundle.getString(messageId);
295             }
296             catch(MissingResourceException e) {
297                 // NoOp
298             }
299         }
300 
301         if(summary == null)
302         {
303             summary = messageId;
304         }
305 
306         if (bundle == null)
307         {
308             throw new NullPointerException(
309                 "Unable to locate ResourceBundle: bundle is null");
310         }
311         if (params != null && locale != null)
312         {
313             try
314             {
315                 detail = bundle.getString(messageId + DETAIL_SUFFIX);
316             }
317             catch(MissingResourceException e) {
318                 // NoOp
319             }
320             return new ParametrizableFacesMessage(summary, detail, params, locale);
321         }
322         else
323         {
324             summary = substituteParams(locale, summary, params);
325             try
326             {
327                 detail = substituteParams(locale,
328                     bundle.getString(messageId + DETAIL_SUFFIX), params);
329             }
330             catch(MissingResourceException e) {
331                 // NoOp
332             }
333             return new FacesMessage(summary, detail);
334         }
335     }
336     
337     public static FacesMessage getMessageFromBundle(String bundleBaseName, FacesContext context, Locale locale, String messageId, Object params[])
338     {
339         String summary = null;
340         String detail = null;
341         String bundleName = context.getApplication().getMessageBundle();
342         ResourceBundle bundle = null;
343 
344         if (bundleName != null)
345         {
346             try
347             {
348                 bundle = ResourceBundle.getBundle(bundleName, locale, org.apache.myfaces.shared_orchestra.util.ClassUtils.getCurrentLoader(bundleName));
349                 summary = bundle.getString(messageId);
350             }
351             catch (MissingResourceException e) {
352                 // NoOp
353             }
354         }
355 
356         if (summary == null)
357         {
358             try
359             {
360                 bundle = ResourceBundle.getBundle(bundleBaseName, locale, org.apache.myfaces.shared_orchestra.util.ClassUtils.getCurrentLoader(bundleBaseName));
361                 if(bundle == null)
362                 {
363                     throw new NullPointerException();
364                 }
365                 summary = bundle.getString(messageId);
366             }
367             catch(MissingResourceException e) {
368                 // NoOp
369             }
370         }
371         
372         if (summary == null)
373         {
374             try
375             {
376                 bundle = ResourceBundle.getBundle(DEFAULT_BUNDLE, locale, org.apache.myfaces.shared_orchestra.util.ClassUtils.getCurrentLoader(DEFAULT_BUNDLE));
377                 if(bundle == null)
378                 {
379                     throw new NullPointerException();
380                 }
381                 summary = bundle.getString(messageId);
382             }
383             catch(MissingResourceException e) {
384                 // NoOp
385             }
386         }
387 
388         if(summary == null)
389         {
390             summary = messageId;
391         }
392 
393         if (bundle == null)
394         {
395             throw new NullPointerException(
396                 "Unable to locate ResourceBundle: bundle is null");
397         }
398         
399         if (params != null && locale != null)
400         {
401             try
402             {
403                 detail = bundle.getString(messageId + DETAIL_SUFFIX);
404             }
405             catch(MissingResourceException e) {
406                 // NoOp
407             }
408             return new ParametrizableFacesMessage(summary, detail, params, locale);
409         }
410         else
411         {
412             summary = substituteParams(locale, summary, params);
413             try
414             {
415                 detail = substituteParams(locale,
416                     bundle.getString(messageId + DETAIL_SUFFIX), params);
417             }
418             catch(MissingResourceException e) {
419                 // NoOp
420             }
421             return new FacesMessage(summary, detail);
422         }
423     }
424 
425     /**
426      *  Retrieve the message from a specific bundle. It does not look on application message bundle
427      * or default message bundle. If it is required to look on those bundles use getMessageFromBundle instead
428      * 
429      * @param bundleBaseName baseName of ResourceBundle to load localized messages
430      * @param messageId id of message
431      * @param params parameters to set at localized message
432      * @return generated FacesMessage
433      */
434     public static FacesMessage getMessage(String bundleBaseName, String messageId, Object params[])
435     {
436         return getMessage(bundleBaseName, getCurrentLocale(), messageId, params);
437     }
438     
439     /**
440      * 
441      * @return  currently applicable Locale for this request.
442      */
443     public static Locale getCurrentLocale() {
444         return getCurrentLocale(FacesContext.getCurrentInstance());
445     }
446     
447     public static Locale getCurrentLocale(FacesContext context) {
448         Locale locale;
449         if(context != null && context.getViewRoot() != null)
450         {
451             locale = context.getViewRoot().getLocale();
452             if(locale == null)
453                 locale = Locale.getDefault();
454         }
455         else
456         {
457             locale = Locale.getDefault();
458         }
459         
460         return locale;
461     }
462 
463     /**
464      * @param severity severity of message
465      * @param bundleBaseName baseName of ResourceBundle to load localized messages
466      * @param messageId id of message
467      * @param params parameters to set at localized message
468      * @return generated FacesMessage
469      */
470     public static FacesMessage getMessage(FacesMessage.Severity severity, String bundleBaseName, String messageId, Object params[])
471     {
472       FacesMessage msg = getMessage(bundleBaseName, messageId, params);
473       msg.setSeverity(severity);
474 
475       return msg;
476     }
477 
478     /**
479      *  Retrieve the message from a specific bundle. It does not look on application message bundle
480      * or default message bundle. If it is required to look on those bundles use getMessageFromBundle instead
481      * 
482      * @param bundleBaseName baseName of ResourceBundle to load localized messages
483      * @param locale current locale
484      * @param messageId id of message
485      * @param params parameters to set at localized message
486      * @return generated FacesMessage
487      */
488     public static FacesMessage getMessage(String bundleBaseName, Locale locale, String messageId, Object params[])
489     {
490       if (bundleBaseName == null)
491       {
492           throw new NullPointerException(
493               "Unable to locate ResourceBundle: bundle is null");
494       }
495 
496       ResourceBundle bundle = ResourceBundle.getBundle(bundleBaseName, locale);
497 
498       return getMessage(bundle, messageId, params);
499     }
500     /**
501      * @param bundle ResourceBundle to load localized messages
502      * @param messageId id of message
503      * @param params parameters to set at localized message
504      * @return generated FacesMessage
505      */
506     public static FacesMessage getMessage(ResourceBundle bundle, String messageId, Object params[])
507     {
508 
509       String summary = null;
510       String detail = null;
511 
512       try
513       {
514           summary = bundle.getString(messageId);
515       }
516       catch (MissingResourceException e) {
517         // NoOp
518       }
519 
520 
521       if(summary == null)
522       {
523           summary = messageId;
524       }
525 
526       summary = substituteParams(bundle.getLocale(), summary, params);
527 
528       try
529       {
530           detail = substituteParams(bundle.getLocale(),
531               bundle.getString(messageId + DETAIL_SUFFIX), params);
532       }
533       catch(MissingResourceException e) {
534         // NoOp
535       }
536 
537       return new FacesMessage(summary, detail);
538     }
539 
540     /**
541      *
542      * @param context
543      * @param messageId
544      * @return generated FacesMessage
545      */
546     public static FacesMessage getMessage(FacesContext context, String messageId)
547     {
548         return getMessage(context, messageId, ((Object []) (null)));
549     }
550     
551     public static FacesMessage getMessage(String bundleBaseName, FacesContext context, String messageId)
552     {
553         return getMessage(bundleBaseName, context, messageId, ((Object []) (null)));
554     }
555 
556     /**
557      *
558      * @param context
559      * @param messageId
560      * @param params
561      * @return generated FacesMessage
562      */
563     public static FacesMessage getMessage(FacesContext context, String messageId, Object params[])
564     {
565         if(context == null || messageId == null)
566             throw new NullPointerException(" context " + context + " messageId " + messageId);
567         Locale locale = getCurrentLocale(context);
568         if(null == locale)
569             throw new NullPointerException(" locale " + locale);
570         FacesMessage message = getMessage(locale, messageId, params);
571         if(message != null)
572         {
573             return message;
574         } else
575         {
576             // TODO /FIX:  Note that this has fallback behavior to default Locale for message,
577             // but similar behavior above does not.  The methods should probably behave
578             locale = Locale.getDefault();
579             return getMessage(locale, messageId, params);
580         }
581     }
582     
583     public static FacesMessage getMessage(String bundleBaseName, FacesContext context, String messageId, Object params[])
584     {
585         if(context == null || messageId == null)
586             throw new NullPointerException(" context " + context + " messageId " + messageId);
587         Locale locale = getCurrentLocale(context);
588         if(null == locale)
589             throw new NullPointerException(" locale " + locale);
590         FacesMessage message = getMessageFromBundle(bundleBaseName, context, locale, messageId, params);
591         if(message != null)
592         {
593             return message;
594         } else
595         {
596             // TODO /FIX:  Note that this has fallback behavior to default Locale for message,
597             // but similar behavior above does not.  The methods should probably behave
598             locale = Locale.getDefault();
599             return getMessageFromBundle(bundleBaseName, context, locale, messageId, params);
600         }
601     }
602 
603     private static Application getApplication()
604     {
605         FacesContext context = FacesContext.getCurrentInstance();
606         if(context != null)
607         {
608             return context.getApplication();
609         } else
610         {
611             ApplicationFactory afactory = (ApplicationFactory)FactoryFinder.getFactory("javax.faces.application.ApplicationFactory");
612             return afactory.getApplication();
613         }
614     }
615 }