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