001 /*
002 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.management;
027
028 import java.io.IOException;
029 import java.io.ObjectInputStream;
030 import java.io.ObjectOutputStream;
031 import java.io.ObjectStreamField;
032 import java.util.EventObject;
033
034 import java.security.AccessController;
035
036 import com.sun.jmx.mbeanserver.GetPropertyAction;
037
038 /**
039 * <p>The Notification class represents a notification emitted by an
040 * MBean. It contains a reference to the source MBean: if the
041 * notification has been forwarded through the MBean server, and the
042 * original source of the notification was a reference to the emitting
043 * MBean object, then the MBean server replaces it by the MBean's
044 * ObjectName. If the listener has registered directly with the
045 * MBean, this is either the object name or a direct reference to the
046 * MBean.</p>
047 *
048 * <p>It is strongly recommended that notification senders use the
049 * object name rather than a reference to the MBean object as the
050 * source.</p>
051 *
052 * <p>The <b>serialVersionUID</b> of this class is <code>-7516092053498031989L</code>.
053 *
054 * @since 1.5
055 */
056 @SuppressWarnings("serial")
057 // serialVersionUID is not constant
058 public class Notification extends EventObject {
059
060 // Serialization compatibility stuff:
061 // Two serial forms are supported in this class. The selected form depends
062 // on system property "jmx.serial.form":
063 // - "1.0" for JMX 1.0
064 // - any other value for JMX 1.1 and higher
065 //
066 // Serial version for old serial form
067 private static final long oldSerialVersionUID = 1716977971058914352L;
068 //
069 // Serial version for new serial form
070 private static final long newSerialVersionUID = -7516092053498031989L;
071 //
072 // Serializable fields in old serial form
073 private static final ObjectStreamField[] oldSerialPersistentFields = {
074 new ObjectStreamField("message", String.class),
075 new ObjectStreamField("sequenceNumber", Long.TYPE),
076 new ObjectStreamField("source", Object.class),
077 new ObjectStreamField("sourceObjectName", ObjectName.class),
078 new ObjectStreamField("timeStamp", Long.TYPE),
079 new ObjectStreamField("type", String.class),
080 new ObjectStreamField("userData", Object.class) };
081 //
082 // Serializable fields in new serial form
083 private static final ObjectStreamField[] newSerialPersistentFields = {
084 new ObjectStreamField("message", String.class),
085 new ObjectStreamField("sequenceNumber", Long.TYPE),
086 new ObjectStreamField("source", Object.class),
087 new ObjectStreamField("timeStamp", Long.TYPE),
088 new ObjectStreamField("type", String.class),
089 new ObjectStreamField("userData", Object.class) };
090 //
091 // Actual serial version and serial form
092 private static final long serialVersionUID;
093 /**
094 * @serialField type String The notification type.
095 * A string expressed in a dot notation similar to Java properties.
096 * An example of a notification type is network.alarm.router
097 * @serialField sequenceNumber long The notification sequence number.
098 * A serial number which identify particular instance
099 * of notification in the context of the notification source.
100 * @serialField timeStamp long The notification timestamp.
101 * Indicating when the notification was generated
102 * @serialField userData Object The notification user data.
103 * Used for whatever other data the notification
104 * source wishes to communicate to its consumers
105 * @serialField message String The notification message.
106 * @serialField source Object The object on which the notification initially occurred.
107 */
108 private static final ObjectStreamField[] serialPersistentFields;
109 private static boolean compat = false;
110 static {
111 try {
112 GetPropertyAction act = new GetPropertyAction(
113 "jmx.serial.form");
114 String form = AccessController.doPrivileged(act);
115 compat = (form != null && form.equals("1.0"));
116 } catch (Exception e) {
117 // OK: exception means no compat with 1.0, too bad
118 }
119 if (compat) {
120 serialPersistentFields = oldSerialPersistentFields;
121 serialVersionUID = oldSerialVersionUID;
122 } else {
123 serialPersistentFields = newSerialPersistentFields;
124 serialVersionUID = newSerialVersionUID;
125 }
126 }
127 //
128 // END Serialization compatibility stuff
129
130 /**
131 * @serial The notification type.
132 * A string expressed in a dot notation similar to Java properties.
133 * An example of a notification type is network.alarm.router
134 */
135 private String type;
136
137 /**
138 * @serial The notification sequence number.
139 * A serial number which identify particular instance
140 * of notification in the context of the notification source.
141 */
142 private long sequenceNumber;
143
144 /**
145 * @serial The notification timestamp.
146 * Indicating when the notification was generated
147 */
148 private long timeStamp;
149
150 /**
151 * @serial The notification user data.
152 * Used for whatever other data the notification
153 * source wishes to communicate to its consumers
154 */
155 private Object userData = null;
156
157 /**
158 * @serial The notification message.
159 */
160 private String message = "";
161
162 /**
163 * <p>This field hides the {@link EventObject#source} field in the
164 * parent class to make it non-transient and therefore part of the
165 * serialized form.</p>
166 *
167 * @serial The object on which the notification initially occurred.
168 */
169 protected Object source = null;
170
171 /**
172 * Creates a Notification object.
173 * The notification timeStamp is set to the current date.
174 *
175 * @param type The notification type.
176 * @param source The notification source.
177 * @param sequenceNumber The notification sequence number within the source object.
178 *
179 */
180 public Notification(String type, Object source, long sequenceNumber) {
181 super (source);
182 this .source = source;
183 this .type = type;
184 this .sequenceNumber = sequenceNumber;
185 this .timeStamp = (new java.util.Date()).getTime();
186 }
187
188 /**
189 * Creates a Notification object.
190 * The notification timeStamp is set to the current date.
191 *
192 * @param type The notification type.
193 * @param source The notification source.
194 * @param sequenceNumber The notification sequence number within the source object.
195 * @param message The detailed message.
196 *
197 */
198 public Notification(String type, Object source,
199 long sequenceNumber, String message) {
200 super (source);
201 this .source = source;
202 this .type = type;
203 this .sequenceNumber = sequenceNumber;
204 this .timeStamp = (new java.util.Date()).getTime();
205 this .message = message;
206 }
207
208 /**
209 * Creates a Notification object.
210 *
211 * @param type The notification type.
212 * @param source The notification source.
213 * @param sequenceNumber The notification sequence number within the source object.
214 * @param timeStamp The notification emission date.
215 *
216 */
217 public Notification(String type, Object source,
218 long sequenceNumber, long timeStamp) {
219 super (source);
220 this .source = source;
221 this .type = type;
222 this .sequenceNumber = sequenceNumber;
223 this .timeStamp = timeStamp;
224 }
225
226 /**
227 * Creates a Notification object.
228 *
229 * @param type The notification type.
230 * @param source The notification source.
231 * @param sequenceNumber The notification sequence number within the source object.
232 * @param timeStamp The notification emission date.
233 * @param message The detailed message.
234 *
235 */
236 public Notification(String type, Object source,
237 long sequenceNumber, long timeStamp, String message) {
238 super (source);
239 this .source = source;
240 this .type = type;
241 this .sequenceNumber = sequenceNumber;
242 this .timeStamp = timeStamp;
243 this .message = message;
244 }
245
246 /**
247 * Sets the source.
248 *
249 * @param source the new source for this object.
250 *
251 * @see EventObject#getSource
252 */
253 public void setSource(Object source) {
254 super .source = source;
255 this .source = source;
256 }
257
258 /**
259 * Get the notification sequence number.
260 *
261 * @return The notification sequence number within the source object. It's a serial number
262 * identifying a particular instance of notification in the context of the notification source.
263 * The notification model does not assume that notifications will be received in the same order
264 * that they are sent. The sequence number helps listeners to sort received notifications.
265 *
266 * @see #setSequenceNumber
267 */
268 public long getSequenceNumber() {
269 return sequenceNumber;
270 }
271
272 /**
273 * Set the notification sequence number.
274 *
275 * @param sequenceNumber The notification sequence number within the source object. It is
276 * a serial number identifying a particular instance of notification in the
277 * context of the notification source.
278 *
279 * @see #getSequenceNumber
280 */
281 public void setSequenceNumber(long sequenceNumber) {
282 this .sequenceNumber = sequenceNumber;
283 }
284
285 /**
286 * Get the notification type.
287 *
288 * @return The notification type. It's a string expressed in a dot notation similar
289 * to Java properties. An example of a notification type is network.alarm.router .
290 */
291 public String getType() {
292 return type;
293 }
294
295 /**
296 * Get the notification timestamp.
297 *
298 * @return The notification timestamp.
299 *
300 * @see #setTimeStamp
301 */
302 public long getTimeStamp() {
303 return timeStamp;
304 }
305
306 /**
307 * Set the notification timestamp.
308 *
309 * @param timeStamp The notification timestamp. It indicates when the notification was generated.
310 *
311 * @see #getTimeStamp
312 */
313 public void setTimeStamp(long timeStamp) {
314 this .timeStamp = timeStamp;
315 }
316
317 /**
318 * Get the notification message.
319 *
320 * @return The message string of this notification object. It contains in a string,
321 * which could be the explanation of the notification for displaying to a user
322 *
323 */
324 public String getMessage() {
325 return message;
326 }
327
328 /**
329 * Get the user data.
330 *
331 * @return The user data object. It is used for whatever data
332 * the notification source wishes to communicate to its consumers.
333 *
334 * @see #setUserData
335 */
336 public Object getUserData() {
337 return userData;
338 }
339
340 /**
341 * Set the user data.
342 *
343 * @param userData The user data object. It is used for whatever data
344 * the notification source wishes to communicate to its consumers.
345 *
346 * @see #getUserData
347 */
348 public void setUserData(Object userData) {
349
350 this .userData = userData;
351 }
352
353 /**
354 * Returns a String representation of this notification.
355 *
356 * @return A String representation of this notification.
357 */
358 public String toString() {
359 return super .toString() + "[type=" + type + "][message="
360 + message + "]";
361 }
362
363 /**
364 * Deserializes a {@link Notification} from an {@link ObjectInputStream}.
365 */
366 private void readObject(ObjectInputStream in) throws IOException,
367 ClassNotFoundException {
368 // New serial form ignores extra field "sourceObjectName"
369 in.defaultReadObject();
370 super .source = source;
371 }
372
373 /**
374 * Serializes a {@link Notification} to an {@link ObjectOutputStream}.
375 */
376 private void writeObject(ObjectOutputStream out) throws IOException {
377 if (compat) {
378 // Serializes this instance in the old serial form
379 //
380 ObjectOutputStream.PutField fields = out.putFields();
381 fields.put("type", type);
382 fields.put("sequenceNumber", sequenceNumber);
383 fields.put("timeStamp", timeStamp);
384 fields.put("userData", userData);
385 fields.put("message", message);
386 fields.put("source", source);
387 out.writeFields();
388 } else {
389 // Serializes this instance in the new serial form
390 //
391 out.defaultWriteObject();
392 }
393 }
394 }
|