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.application;
20  
21  import java.io.IOException;
22  import java.io.ObjectInputStream;
23  import java.io.ObjectOutputStream;
24  import java.io.Serializable;
25  import java.util.*;
26  
27  /**
28   *see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
29   *<p>
30   * <code>FacesMessage</code> represents a single validation (or other) message, which is typically associated with a
31   * particular component in the view. A {@link FacesMessage} instance may be created based on a specific messageId. The
32   * specification defines the set of messageIds for which there must be {@link FacesMessage} instances.
33   * </p>
34   * 
35   *<ui>The implementation must take the following steps when creating FacesMessage instances given a messageId: <li>Call
36   * {@link Application.getMessageBundle()}. If <code>non-null</code>, locate the named <code>ResourceBundle</code>, using
37   * the <code>Locale</code> from the current {@linkUIViewRoot} and see if it has a value for the argument
38   * <code>messageId</code>. If it does, treat the value as the <code>summary</code> of the {@link FacesMessage}. If it
39   * does not, or if {@link Application.getMessageBundle()} returned null, look in the ResourceBundle named by the value
40   * of the constant {@link FACES_MESSAGES} and see if it has a value for the argument messageId. If it does, treat the
41   * value as the summary of the <code>FacesMessage</code>. If it does not, there is no initialization information for the
42   * <code>FacesMessage</code> instance.</li> <li>In all cases, if a <code>ResourceBundle</code> hit is found for the
43   * <code>{messageId}</code>, look for further hits under the key <code>{messageId}_detail</code>. Use this value, if
44   * present, as the <code>detail</code> for the returned <code>FacesMessage</code>.</li> <li>Make sure to perform any
45   * parameter substitution required for the <code>summary</code> and <code>detail</code> of the <code>FacesMessage</code>
46   * .</li> </ui>
47   * 
48   * @author Manfred Geiler (latest modification by $Author: bommel $)
49   * @version $Revision: 1187700 $ $Date: 2011-10-22 07:19:37 -0500 (Sat, 22 Oct 2011) $
50   * 
51   */
52  public class FacesMessage implements Serializable
53  {
54      private static final long serialVersionUID = 4851488727794169661L;
55  
56      /**
57       * <code>ResourceBundle</code> identifier for messages whose message identifiers are defined in the JavaServer Faces
58       * specification.
59       */
60      public static final String FACES_MESSAGES = "javax.faces.Messages";
61  
62      /**
63       * Message severity level indicating an informational message rather than an error.
64       */
65      public static final FacesMessage.Severity SEVERITY_INFO = new Severity("Info", 1);
66  
67      /**
68       * Message severity level indicating that an error might have occurred.
69       */
70      public static final FacesMessage.Severity SEVERITY_WARN = new Severity("Warn", 2);
71  
72      /**
73       * Message severity level indicating that an error has occurred.
74       */
75      public static final FacesMessage.Severity SEVERITY_ERROR = new Severity("Error", 3);
76  
77      /**
78       * Message severity level indicating that a serious error has occurred.
79       */
80      public static final FacesMessage.Severity SEVERITY_FATAL = new Severity("Fatal", 4);
81  
82      /**
83       * Immutable <code>Lis</code> of valid {@link FacesMessage.Severity}instances, in ascending order of their ordinal
84       * value.
85       */
86      public static final List VALUES;
87  
88      /**
89       * Immutable <code>Map</code> of valid {@link FacesMessage.Severity}instances, keyed by name.
90       */
91      public static final Map VALUES_MAP;
92  
93      static
94      {
95          Map<String, FacesMessage.Severity> map = new HashMap<String, FacesMessage.Severity>(7);
96          map.put(SEVERITY_INFO.toString(), SEVERITY_INFO);
97          map.put(SEVERITY_WARN.toString(), SEVERITY_WARN);
98          map.put(SEVERITY_ERROR.toString(), SEVERITY_ERROR);
99          map.put(SEVERITY_FATAL.toString(), SEVERITY_FATAL);
100         VALUES_MAP = Collections.unmodifiableMap(map);
101 
102         List<FacesMessage.Severity> severityList = new ArrayList<FacesMessage.Severity>(map.values());
103         Collections.sort(severityList); // the JSF spec requires it to be sorted
104         VALUES = Collections.unmodifiableList(severityList);
105     }
106 
107     private transient FacesMessage.Severity _severity;  // transient, b/c FacesMessage.Severity is not Serializable
108     private String _summary;
109     private String _detail;
110     private boolean _rendered;
111 
112     /**
113      *Construct a new {@link FacesMessage} with no initial values. The severity is set to Severity.INFO.
114      */
115     public FacesMessage()
116     {
117         _severity = SEVERITY_INFO;
118         _rendered = false;
119     }
120 
121     /**
122      * Construct a new {@link FacesMessage} with just a summary. The detail is null, the severity is set to
123      * <code>Severity.INFO</code>.
124      */
125     public FacesMessage(String summary)
126     {
127         _summary = summary;
128         _severity = SEVERITY_INFO;
129         _rendered = false;
130     }
131 
132     /**
133      * Construct a new {@link FacesMessage} with the specified initial values. The severity is set to Severity.INFO.
134      * 
135      * @param summary
136      *            - Localized summary message text
137      * @param detail
138      *            - Localized detail message text
139      */
140     public FacesMessage(String summary, String detail)
141     {
142         _summary = summary;
143         _detail = detail;
144         _severity = SEVERITY_INFO;
145         _rendered = false;
146     }
147 
148     /**
149      * Construct a new {@link FacesMessage}with the specified initial values.
150      * 
151      * @param severity
152      *            - the severity
153      * @param summary
154      *            - Localized summary message text
155      * @param detail
156      *            - Localized detail message text
157      */
158     public FacesMessage(FacesMessage.Severity severity, String summary, String detail)
159     {
160         if (severity == null)
161             throw new NullPointerException("severity");
162         _severity = severity;
163         _summary = summary;
164         _detail = detail;
165         _rendered = false;
166     }
167 
168     /**
169      * 
170      * @return
171      */
172     public FacesMessage.Severity getSeverity()
173     {
174         return _severity;
175     }
176 
177     /**
178      * Return the severity level.
179      */
180     public void setSeverity(FacesMessage.Severity severity)
181     {
182         if (severity == null)
183             throw new NullPointerException("severity");
184         _severity = severity;
185     }
186 
187     /**
188      * Return the localized summary text.
189      */
190     public String getSummary()
191     {
192         return _summary;
193     }
194 
195     /**
196      * Set the localized summary text.
197      * 
198      * @param summary
199      *            - The new localized summary text
200      */
201     public void setSummary(String summary)
202     {
203         _summary = summary;
204     }
205 
206     /**
207      * 
208      * @return
209      */
210     public String getDetail()
211     {
212         if (_detail == null)
213         {
214             // Javadoc:
215             // If no localized detail text has been defined for this message, return the localized summary text instead
216             return _summary;
217         }
218         return _detail;
219     }
220 
221     /**
222      * Set the localized detail text.
223      * 
224      * @param detail
225      *            - The new localized detail text
226      */
227     public void setDetail(String detail)
228     {
229         _detail = detail;
230     }
231 
232     public boolean isRendered()
233     {
234         return _rendered;
235     }
236 
237     public void rendered()
238     {
239         this._rendered = true;
240     }
241 
242     private void writeObject(ObjectOutputStream out) throws IOException
243     {
244         out.defaultWriteObject();  // write summary, detail, rendered
245         out.writeInt(_severity._ordinal);  // FacesMessage.Severity is not Serializable, write ordinal only
246     }
247 
248     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
249     {
250         in.defaultReadObject();  // read summary, detail, rendered
251 
252         // FacesMessage.Severity is not Serializable, read ordinal and get related FacesMessage.Severity
253         int severityOrdinal = in.readInt();
254         _severity = (Severity) VALUES.get(severityOrdinal - 1);
255     }
256 
257     public static class Severity implements Comparable
258     {
259         private String _name;
260         private int _ordinal;
261 
262         private Severity(String name, int ordinal)
263         {
264             _name = name;
265             _ordinal = ordinal;
266         }
267 
268         public int getOrdinal()
269         {
270             return _ordinal;
271         }
272 
273         @Override
274         public String toString()
275         {
276             return _name;
277         }
278 
279         public int compareTo(Object o)
280         {
281             return getOrdinal() - ((Severity)o).getOrdinal();
282         }
283     }
284 
285 }