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