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 javax.faces.component.html;
20  
21  import javax.el.ValueExpression;
22  import javax.faces.application.FacesMessage;
23  import javax.faces.context.FacesContext;
24  
25  import java.util.Locale;
26  import java.util.MissingResourceException;
27  import java.util.ResourceBundle;
28  import javax.faces.component.UIComponent;
29  
30  class _MessageUtils
31  {
32      private static final String DETAIL_SUFFIX = "_detail";
33  
34      static void addErrorMessage(FacesContext facesContext,
35                                  UIComponent component,
36                                  String messageId)
37      {
38          facesContext.addMessage(component.getClientId(facesContext),
39                                  getMessage(facesContext,
40                                             facesContext.getViewRoot().getLocale(),
41                                             FacesMessage.SEVERITY_ERROR,
42                                             messageId,
43                                             null));
44      }
45  
46      static void addErrorMessage(FacesContext facesContext,
47                                  UIComponent component,
48                                  String messageId, Object[] args)
49      {
50          facesContext.addMessage(component.getClientId(facesContext),
51                                  getMessage(facesContext,
52                                             facesContext.getViewRoot().getLocale(),
53                                             FacesMessage.SEVERITY_ERROR,
54                                             messageId,
55                                             args));
56      }
57  
58      static void addErrorMessage(FacesContext facesContext,
59              UIComponent component, Throwable cause)
60      {
61          facesContext.addMessage(component.getClientId(facesContext),
62                  new FacesMessage(FacesMessage.SEVERITY_ERROR, cause
63                          .getLocalizedMessage(), cause.getLocalizedMessage()));
64      }
65  
66      
67      static FacesMessage getMessage(FacesContext facesContext,
68                                     Locale locale,
69                                     FacesMessage.Severity severity,
70                                     String messageId,
71                                     Object args[])
72      {
73          ResourceBundle appBundle;
74          ResourceBundle defBundle;
75          String summary;
76          String detail;
77  
78          appBundle = getApplicationBundle(facesContext, locale);
79          summary = getBundleString(appBundle, messageId);
80          if (summary != null)
81          {
82              detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
83          }
84          else
85          {
86              defBundle = getDefaultBundle(facesContext, locale);
87              summary = getBundleString(defBundle, messageId);
88              if (summary != null)
89              {
90                  detail = getBundleString(defBundle, messageId + DETAIL_SUFFIX);
91              }
92              else
93              {
94                  //Try to find detail alone
95                  detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
96                  if (detail != null)
97                  {
98                      summary = null;
99                  }
100                 else
101                 {
102                     detail = getBundleString(defBundle, messageId + DETAIL_SUFFIX);
103                     if (detail != null)
104                     {
105                         summary = null;
106                     }
107                     else
108                     {
109                         //Neither detail nor summary found
110                         facesContext.getExternalContext().log("No message with id " + messageId
111                                                               + " found in any bundle");
112                         return new FacesMessage(severity, messageId, null);
113                     }
114                 }
115             }
116         }
117 
118         if (args != null && args.length > 0)
119         {
120             return new _ParametrizableFacesMessage(severity, summary, detail, args, locale);
121         }
122         else
123         {
124             return new FacesMessage(severity, summary, detail);
125         }
126     }
127 
128     private static String getBundleString(ResourceBundle bundle, String key)
129     {
130         try
131         {
132             return bundle == null ? null : bundle.getString(key);
133         }
134         catch (MissingResourceException e)
135         {
136             return null;
137         }
138     }
139 
140 
141     private static ResourceBundle getApplicationBundle(FacesContext facesContext, Locale locale)
142     {
143         String bundleName = facesContext.getApplication().getMessageBundle();
144         return bundleName != null ? getBundle(facesContext, locale, bundleName) : null;
145     }
146 
147     private static ResourceBundle getDefaultBundle(FacesContext facesContext,
148                                                    Locale locale)
149     {
150         return getBundle(facesContext, locale, FacesMessage.FACES_MESSAGES);
151     }
152 
153     private static ResourceBundle getBundle(FacesContext facesContext,
154                                             Locale locale,
155                                             String bundleName)
156     {
157         try
158         {
159             //First we try the JSF implementation class loader
160             return ResourceBundle.getBundle(bundleName,
161                                             locale,
162                                             facesContext.getClass().getClassLoader());
163         }
164         catch (MissingResourceException ignore1)
165         {
166             try
167             {
168                 //Next we try the JSF API class loader
169                 return ResourceBundle.getBundle(bundleName,
170                                                 locale,
171                                                 _MessageUtils.class.getClassLoader());
172             }
173             catch (MissingResourceException ignore2)
174             {
175                 try
176                 {
177                     //Last resort is the context class loader
178                     return ResourceBundle.getBundle(bundleName,
179                                                     locale,
180                                                     _ClassUtils.getContextClassLoader());
181                 }
182                 catch (MissingResourceException damned)
183                 {
184                     facesContext.getExternalContext().log("resource bundle " + bundleName + " could not be found");
185                     return null;
186                 }
187             }
188         }
189     }
190     
191     static Object getLabel(FacesContext facesContext, UIComponent component)
192     {
193         Object label = component.getAttributes().get("label");
194         ValueExpression expression = null;
195         if (label != null && 
196             label instanceof String && ((String)label).length() == 0 )
197         {
198             // Note component.getAttributes().get("label") internally try to 
199             // evaluate the EL expression for the label, but in some cases, 
200             // when PSS is disabled and f:loadBundle is used, when the view is 
201             // restored the bundle is not set to the EL expression returns an 
202             // empty String. It is not possible to check if there is a 
203             // hardcoded label, but we can check if there is
204             // an EL expression set, so the best in this case is use that, and if
205             // there is an EL expression set, use it, otherwise use the hardcoded
206             // value. See MYFACES-3591 for details.
207             expression = component.getValueExpression("label");
208             if (expression != null)
209             {
210                 // Set the label to null and use the EL expression instead.
211                 label = null;
212             }
213         }
214             
215         if(label != null)
216         {
217             return label;
218         }
219         
220         expression = (expression == null) ? component.getValueExpression("label") : expression;
221         if(expression != null)
222         {
223             return expression;
224         }
225         
226         //If no label is not specified, use clientId
227         return component.getClientId( facesContext );
228     }
229 }