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   */
53  public class FacesMessage implements Serializable
54  {
55      private static final long serialVersionUID = 4851488727794169661L;
56  
57      /**
58       * <code>ResourceBundle</code> identifier for messages whose message identifiers are defined in the JavaServer Faces
59       * specification.
60       */
61      public static final String FACES_MESSAGES = "javax.faces.Messages";
62  
63      /**
64       * Message severity level indicating an informational message rather than an error.
65       */
66      public static final FacesMessage.Severity SEVERITY_INFO = new Severity("INFO", 0);
67  
68      /**
69       * Message severity level indicating that an error might have occurred.
70       */
71      public static final FacesMessage.Severity SEVERITY_WARN = new Severity("WARN", 1);
72  
73      /**
74       * Message severity level indicating that an error has occurred.
75       */
76      public static final FacesMessage.Severity SEVERITY_ERROR = new Severity("ERROR", 2);
77  
78      /**
79       * Message severity level indicating that a serious error has occurred.
80       */
81      public static final FacesMessage.Severity SEVERITY_FATAL = new Severity("FATAL", 3);
82  
83      /**
84       * Immutable <code>Lis</code> of valid {@link FacesMessage.Severity}instances, in ascending order of their ordinal
85       * value.
86       */
87      public static final List VALUES;
88  
89      /**
90       * Immutable <code>Map</code> of valid {@link FacesMessage.Severity}instances, keyed by name.
91       */
92      public static final Map VALUES_MAP;
93  
94      static
95      {
96          Map<String, FacesMessage.Severity> map = new HashMap<String, Severity>(7);
97          map.put(SEVERITY_INFO.toString(), SEVERITY_INFO);
98          map.put(SEVERITY_WARN.toString(), SEVERITY_WARN);
99          map.put(SEVERITY_ERROR.toString(), SEVERITY_ERROR);
100         map.put(SEVERITY_FATAL.toString(), SEVERITY_FATAL);
101         VALUES_MAP = Collections.unmodifiableMap(map);
102 
103         List<FacesMessage.Severity> severityList = new ArrayList<Severity>(map.values());
104         Collections.sort(severityList); // the JSF spec requires it to be sorted
105         VALUES = Collections.unmodifiableList(severityList);
106     }
107 
108     private transient FacesMessage.Severity _severity;  // transient, b/c FacesMessage.Severity is not Serializable
109     private String _summary;
110     private String _detail;
111     private boolean _rendered;
112 
113     /**
114      *Construct a new {@link FacesMessage} with no initial values. The severity is set to Severity.INFO.
115      */
116     public FacesMessage()
117     {
118         _severity = SEVERITY_INFO;
119         _rendered = false;
120     }
121 
122     /**
123      * Construct a new {@link FacesMessage} with just a summary. The detail is null, the severity is set to
124      * <code>Severity.INFO</code>.
125      */
126     public FacesMessage(String summary)
127     {
128         _summary = summary;
129         _severity = SEVERITY_INFO;
130         _rendered = false;
131     }
132 
133     /**
134      * Construct a new {@link FacesMessage} with the specified initial values. The severity is set to Severity.INFO.
135      * 
136      * @param summary
137      *            - Localized summary message text
138      * @param detail
139      *            - Localized detail message text
140      */
141     public FacesMessage(String summary, String detail)
142     {
143         _summary = summary;
144         _detail = detail;
145         _severity = SEVERITY_INFO;
146         _rendered = false;
147     }
148 
149     /**
150      * Construct a new {@link FacesMessage}with the specified initial values.
151      * 
152      * @param severity
153      *            - the severity
154      * @param summary
155      *            - Localized summary message text
156      * @param detail
157      *            - Localized detail message text
158      */
159     public FacesMessage(FacesMessage.Severity severity, String summary, String detail)
160     {
161         if (severity == null)
162         {
163             throw new NullPointerException("severity");
164         }
165         _severity = severity;
166         _summary = summary;
167         _detail = detail;
168         _rendered = false;
169     }
170 
171     /**
172      * 
173      * @return
174      */
175     public FacesMessage.Severity getSeverity()
176     {
177         return _severity;
178     }
179 
180     /**
181      * Return the severity level.
182      */
183     public void setSeverity(FacesMessage.Severity severity)
184     {
185         if (severity == null)
186         {
187             throw new NullPointerException("severity");
188         }
189         _severity = severity;
190     }
191 
192     /**
193      * Return the localized summary text.
194      */
195     public String getSummary()
196     {
197         return _summary;
198     }
199 
200     /**
201      * Set the localized summary text.
202      * 
203      * @param summary
204      *            - The new localized summary text
205      */
206     public void setSummary(String summary)
207     {
208         _summary = summary;
209     }
210 
211     /**
212      * 
213      * @return
214      */
215     public String getDetail()
216     {
217         if (_detail == null)
218         {
219             // Javadoc:
220             // If no localized detail text has been defined for this message, return the localized summary text instead
221             return _summary;
222         }
223         return _detail;
224     }
225 
226     /**
227      * Set the localized detail text.
228      * 
229      * @param detail
230      *            - The new localized detail text
231      */
232     public void setDetail(String detail)
233     {
234         _detail = detail;
235     }
236 
237     public boolean isRendered()
238     {
239         return _rendered;
240     }
241 
242     public void rendered()
243     {
244         this._rendered = true;
245     }
246 
247     private void writeObject(ObjectOutputStream out) throws IOException
248     {
249         out.defaultWriteObject();  // write summary, detail, rendered
250         out.writeInt(_severity._ordinal);  // FacesMessage.Severity is not Serializable, write ordinal only
251     }
252 
253     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
254     {
255         in.defaultReadObject();  // read summary, detail, rendered
256 
257         // FacesMessage.Severity is not Serializable, read ordinal and get related FacesMessage.Severity
258         int severityOrdinal = in.readInt();
259         _severity = (Severity) VALUES.get(severityOrdinal);
260     }
261 
262     public static class Severity implements Comparable
263     {
264         private String _name;
265         private int _ordinal;
266 
267         private Severity(String name, int ordinal)
268         {
269             _name = name;
270             _ordinal = ordinal;
271         }
272 
273         public int getOrdinal()
274         {
275             return _ordinal;
276         }
277 
278         @Override
279         public String toString()
280         {
281             return _name;
282         }
283 
284         public int compareTo(Object o)
285         {
286             return getOrdinal() - ((Severity)o).getOrdinal();
287         }
288     }
289 
290 }