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