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  
20  package org.apache.myfaces.tobago.util;
21  
22  import org.apache.myfaces.tobago.application.LabelValueExpressionFacesMessage;
23  import org.apache.myfaces.tobago.context.TobagoContext;
24  import org.apache.myfaces.tobago.context.TobagoMessageBundle;
25  import org.apache.myfaces.tobago.context.TobagoResourceBundle;
26  
27  import javax.el.ValueExpression;
28  import javax.faces.application.FacesMessage;
29  import javax.faces.component.UIComponent;
30  import javax.faces.context.FacesContext;
31  import java.text.MessageFormat;
32  import java.util.Locale;
33  import java.util.MissingResourceException;
34  import java.util.ResourceBundle;
35  
36  /**
37   * Utility to create and add {@link FacesMessage} object to the context. The message will be internationalized with a
38   * bundle in the following order: <ol> <li>Application bundle</li> <li>Tobago bundle</li> <li>Default JSF bundle</li>
39   * </ol>
40   */
41  public final class MessageUtils {
42  
43    private static final String DETAIL_SUFFIX = "_detail";
44  
45    private MessageUtils() {
46    }
47  
48    public static void addMessage(
49        final FacesContext facesContext, final UIComponent component, final FacesMessage.Severity severity,
50        final String messageId, final Object[] args) {
51      facesContext.addMessage(component != null ? component.getClientId(facesContext) : null,
52          getMessage(facesContext, facesContext.getViewRoot().getLocale(), severity, messageId, args));
53    }
54  
55    public static FacesMessage getMessage(
56        final FacesContext facesContext, final Locale locale,
57        final FacesMessage.Severity severity, final String messageId, final Object... args) {
58  
59      final ResourceBundle appBundle = getApplicationBundle(facesContext, locale);
60      String summary = getBundleString(appBundle, messageId);
61      String detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
62  
63      if (summary == null || detail == null) {
64        final TobagoMessageBundle tobagoMessages = TobagoContext.getInstance(facesContext).getMessageBundle();
65        if (summary == null) {
66          summary = getBundleString(tobagoMessages, messageId);
67        }
68        if (detail == null) {
69          detail = getBundleString(tobagoMessages, messageId + DETAIL_SUFFIX);
70        }
71  
72        if (summary == null || detail == null) {
73          final TobagoResourceBundle tobagoBundle = TobagoContext.getInstance(facesContext).getResourceBundle();
74          if (summary == null) {
75            summary = getBundleString(tobagoBundle, messageId);
76          }
77          if (detail == null) {
78            detail = getBundleString(tobagoBundle, messageId + DETAIL_SUFFIX);
79          }
80  
81          if (summary == null || detail == null) {
82            final ResourceBundle defBundle = getDefaultBundle(facesContext, locale);
83            if (summary == null) {
84              summary = getBundleString(defBundle, messageId);
85            }
86            if (detail == null) {
87              detail = getBundleString(defBundle, messageId + DETAIL_SUFFIX);
88            }
89          }
90        }
91      }
92  
93      if (summary == null && detail == null) {
94        //Neither detail nor summary found
95        facesContext.getExternalContext().log("No message with id " + messageId + " found in any bundle");
96        return new FacesMessage(severity, messageId, null);
97      }
98  
99      if (args != null && args.length > 0) {
100       MessageFormat format;
101       if (summary != null) {
102         format = new MessageFormat(summary, locale);
103         summary = format.format(args);
104       }
105 
106       if (detail != null) {
107         format = new MessageFormat(detail, locale);
108         detail = format.format(args);
109       }
110     }
111     return new LabelValueExpressionFacesMessage(severity, summary, detail);
112   }
113 
114   private static String getBundleString(final ResourceBundle bundle, final String key) {
115     try {
116       return bundle == null ? null : bundle.getString(key);
117     } catch (final MissingResourceException e) {
118       // ignore
119       return null;
120     }
121   }
122 
123   private static ResourceBundle getApplicationBundle(final FacesContext facesContext, final Locale locale) {
124     final String bundleName = facesContext.getApplication().getMessageBundle();
125     return bundleName != null ? getBundle(facesContext, locale, bundleName) : null;
126   }
127 
128   private static ResourceBundle getDefaultBundle(final FacesContext facesContext, final Locale locale) {
129     return getBundle(facesContext, locale, FacesMessage.FACES_MESSAGES);
130   }
131 
132   private static ResourceBundle getBundle(
133       final FacesContext facesContext, final Locale locale, final String bundleName) {
134     try {
135       return ResourceBundle.getBundle(bundleName, locale, MessageUtils.class.getClassLoader());
136     } catch (final MissingResourceException ignore2) {
137       try {
138         return ResourceBundle.getBundle(bundleName, locale, Thread.currentThread().getContextClassLoader());
139       } catch (final MissingResourceException damned) {
140         facesContext.getExternalContext().log("resource bundle " + bundleName + " could not be found");
141         return null;
142       }
143     }
144   }
145 
146   public static String getLabel(final FacesContext facesContext, final UIComponent component) {
147     if (component == null) {
148       return null;
149     }
150     final Object label = component.getAttributes().get("label");
151     if (label != null) {
152       return label.toString();
153     }
154     final ValueExpression expression = component.getValueExpression("label");
155     if (expression != null) {
156       return expression.getExpressionString();
157     }
158     return component.getClientId(facesContext);
159   }
160 }