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 }