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