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  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          appBundle = getApplicationBundle(facesContext, locale);
61          summary = getBundleString(appBundle, messageId);
62          if (summary != null)
63          {
64              detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
65          }
66          else
67          {
68              defBundle = getDefaultBundle(facesContext, locale);
69              summary = getBundleString(defBundle, messageId);
70              if (summary != null)
71              {
72                  detail = getBundleString(defBundle, messageId + DETAIL_SUFFIX);
73              }
74              else
75              {
76                  //Try to find detail alone
77                  detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
78                  if (detail != null)
79                  {
80                      summary = null;
81                  }
82                  else
83                  {
84                      detail = getBundleString(defBundle, messageId + DETAIL_SUFFIX);
85                      if (detail != null)
86                      {
87                          summary = null;
88                      }
89                      else
90                      {
91                          //Neither detail nor summary found
92                          facesContext.getExternalContext().log("No message with id " + messageId
93                                                                + " found in any bundle");
94                          return new FacesMessage(severity, messageId, null);
95                      }
96                  }
97              }
98          }
99  
100         if (args != null && args.length > 0)
101         {
102             return new _ParametrizableFacesMessage(severity, summary, detail, args, locale);
103         }
104         else
105         {
106             return new FacesMessage(severity, summary, detail);
107         }
108     }
109 
110     private static String getBundleString(ResourceBundle bundle, String key)
111     {
112         try
113         {
114             return bundle == null ? null : bundle.getString(key);
115         }
116         catch (MissingResourceException e)
117         {
118             return null;
119         }
120     }
121 
122 
123     private static ResourceBundle getApplicationBundle(FacesContext facesContext, Locale locale)
124     {
125         String bundleName = facesContext.getApplication().getMessageBundle();
126         return bundleName != null ? getBundle(facesContext, locale, bundleName) : null;
127     }
128 
129     private static ResourceBundle getDefaultBundle(FacesContext facesContext,
130                                                    Locale locale)
131     {
132         return getBundle(facesContext, locale, FacesMessage.FACES_MESSAGES);
133     }
134 
135     private static ResourceBundle getBundle(FacesContext facesContext,
136                                             Locale locale,
137                                             String bundleName)
138     {
139         try
140         {
141             //First we try the JSF implementation class loader
142             return ResourceBundle.getBundle(bundleName,
143                                             locale,
144                                             facesContext.getClass().getClassLoader());
145         }
146         catch (MissingResourceException ignore1)
147         {
148             try
149             {
150                 //Next we try the JSF API class loader
151                 return ResourceBundle.getBundle(bundleName,
152                                                 locale,
153                                                 _MessageUtils.class.getClassLoader());
154             }
155             catch (MissingResourceException ignore2)
156             {
157                 try
158                 {
159                     //Last resort is the context class loader
160                     if (System.getSecurityManager() != null)
161                     {
162                         Object cl = AccessController.doPrivileged(new PrivilegedExceptionAction()
163                         {
164                             public Object run() throws PrivilegedActionException
165                             {
166                                 return Thread.currentThread().getContextClassLoader();
167                             }
168                         });
169                         return ResourceBundle.getBundle(bundleName,locale,(ClassLoader)cl);
170 
171                     }
172                     else
173                     {
174                         return ResourceBundle.getBundle(bundleName,locale,
175                                                         Thread.currentThread().getContextClassLoader());
176                     }                   
177                 }
178                 catch(PrivilegedActionException pae)
179                 {
180                     throw new FacesException(pae);
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 }