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