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 java.lang.reflect.Method;
22  import java.util.Locale;
23  import java.util.MissingResourceException;
24  import java.util.ResourceBundle;
25  
26  import javax.faces.application.FacesMessage;
27  import javax.faces.context.FacesContext;
28  
29  /**
30   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
31   * @version $Revision: 940131 $ $Date: 2010-05-01 20:29:02 -0500 (Sat, 01 May 2010) $
32   */
33  class _MessageUtils
34  {
35      private static final String DETAIL_SUFFIX = "_detail";
36      private static final Class[] NO_ARGS = new Class[0];
37  
38      static void addErrorMessage(FacesContext facesContext,
39                                  UIComponent component,
40                                  String messageId)
41      {
42          facesContext.addMessage(component.getClientId(facesContext),
43                                  getMessage(facesContext,
44                                             facesContext.getViewRoot().getLocale(),
45                                             FacesMessage.SEVERITY_ERROR,
46                                             messageId,
47                                             null));
48      }
49  
50      static void addErrorMessage(FacesContext facesContext,
51                                  UIComponent component,
52                                  String messageId, Object[] args)
53      {
54          facesContext.addMessage(component.getClientId(facesContext),
55                                  getMessage(facesContext,
56                                             facesContext.getViewRoot().getLocale(),
57                                             FacesMessage.SEVERITY_ERROR,
58                                             messageId,
59                                             args));
60      }
61  
62      static void addErrorMessage(FacesContext facesContext,
63              UIComponent component, Throwable cause)
64      {
65          StringBuffer buf = new StringBuffer();
66  
67          while(cause != null)
68          {
69              Throwable parentCause = getCause(cause);
70              if (parentCause == cause)
71              {
72                  break;
73              }
74  
75              if(buf.length()>0)
76              {
77                  buf.append(", ");
78              }
79              
80              buf.append(cause.getLocalizedMessage());
81  
82              cause = parentCause;
83          }
84  
85          facesContext.addMessage(component.getClientId(facesContext),
86                  new FacesMessage(FacesMessage.SEVERITY_ERROR, buf.toString(), buf.toString()));
87      }
88  
89  
90      /**
91       * Get the cause of an exception, if available. Reflection must be used because
92       * JSF11 supports java1.3 but Throwable.getCause was added in java1.4.
93       */
94      static Throwable getCause(Throwable ex)
95      {
96          try
97          {
98              Method causeGetter = ex.getClass().getMethod("getCause", NO_ARGS);
99              Throwable cause = (Throwable) causeGetter.invoke(ex, NO_ARGS);
100             return cause;
101         }
102         catch (Exception e1)
103         {
104             return null;
105         }
106     }
107     
108     static FacesMessage getMessage(FacesContext facesContext,
109                                    Locale locale,
110                                    FacesMessage.Severity severity,
111                                    String messageId,
112                                    Object args[])
113     {
114         ResourceBundle appBundle;
115         ResourceBundle defBundle;
116         String summary;
117         String detail;
118 
119         appBundle = getApplicationBundle(facesContext, locale);
120         summary = getBundleString(appBundle, messageId);
121         if (summary != null)
122         {
123             detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
124         }
125         else
126         {
127             defBundle = getDefaultBundle(facesContext, locale);
128             summary = getBundleString(defBundle, messageId);
129             if (summary != null)
130             {
131                 detail = getBundleString(defBundle, messageId + DETAIL_SUFFIX);
132             }
133             else
134             {
135                 //Try to find detail alone
136                 detail = getBundleString(appBundle, messageId + DETAIL_SUFFIX);
137                 if (detail != null)
138                 {
139                     summary = null;
140                 }
141                 else
142                 {
143                     detail = getBundleString(defBundle, messageId + DETAIL_SUFFIX);
144                     if (detail != null)
145                     {
146                         summary = null;
147                     }
148                     else
149                     {
150                         //Neither detail nor summary found
151                         facesContext.getExternalContext().log("No message with id " + messageId + " found in any bundle");
152                         return new FacesMessage(severity, messageId, null);
153                     }
154                 }
155             }
156         }
157 
158         if (args != null && args.length > 0)
159         {
160             return new _ParametrizableFacesMessage(severity, summary, detail, args, locale);
161         }
162         else
163         {
164             return new FacesMessage(severity, summary, detail);
165         }
166     }
167 
168     private static String getBundleString(ResourceBundle bundle, String key)
169     {
170         try
171         {
172             return bundle == null ? null : bundle.getString(key);
173         }
174         catch (MissingResourceException e)
175         {
176             return null;
177         }
178     }
179 
180 
181     private static ResourceBundle getApplicationBundle(FacesContext facesContext, Locale locale)
182     {
183         String bundleName = facesContext.getApplication().getMessageBundle();
184         if (bundleName != null)
185         {
186             return getBundle(facesContext, locale, bundleName);
187         }
188         else
189         {
190             return null;
191         }
192     }
193 
194     private static ResourceBundle getDefaultBundle(FacesContext facesContext,
195                                                    Locale locale)
196     {
197         return getBundle(facesContext, locale, FacesMessage.FACES_MESSAGES);
198     }
199 
200     private static ResourceBundle getBundle(FacesContext facesContext,
201                                             Locale locale,
202                                             String bundleName)
203     {
204         try
205         {
206             //First we try the JSF implementation class loader
207             return ResourceBundle.getBundle(bundleName,
208                                             locale,
209                                             facesContext.getClass().getClassLoader());
210         }
211         catch (MissingResourceException ignore1)
212         {
213             try
214             {
215                 //Next we try the JSF API class loader
216                 return ResourceBundle.getBundle(bundleName,
217                                                 locale,
218                                                 _MessageUtils.class.getClassLoader());
219             }
220             catch (MissingResourceException ignore2)
221             {
222                 try
223                 {
224                     //Last resort is the context class loader
225                     return ResourceBundle.getBundle(bundleName,
226                                                     locale,
227                                                     Thread.currentThread().getContextClassLoader());
228                 }
229                 catch (MissingResourceException damned)
230                 {
231                     facesContext.getExternalContext().log("resource bundle " + bundleName + " could not be found");
232                     return null;
233                 }
234             }
235         }
236     }
237 
238 }