1 /*
2 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package javax.management;
27
28 import java.io.IOException;
29 import java.io.ObjectInputStream;
30 import java.io.ObjectOutputStream;
31 import java.io.ObjectStreamField;
32 import java.util.EventObject;
33
34 import java.security.AccessController;
35
36 import com.sun.jmx.mbeanserver.GetPropertyAction;
37
38 /**
39 * <p>The Notification class represents a notification emitted by an
40 * MBean. It contains a reference to the source MBean: if the
41 * notification has been forwarded through the MBean server, and the
42 * original source of the notification was a reference to the emitting
43 * MBean object, then the MBean server replaces it by the MBean's
44 * ObjectName. If the listener has registered directly with the
45 * MBean, this is either the object name or a direct reference to the
46 * MBean.</p>
47 *
48 * <p>It is strongly recommended that notification senders use the
49 * object name rather than a reference to the MBean object as the
50 * source.</p>
51 *
52 * <p>The <b>serialVersionUID</b> of this class is <code>-7516092053498031989L</code>.
53 *
54 * @since 1.5
55 */
56 @SuppressWarnings("serial") // serialVersionUID is not constant
57 public class Notification extends EventObject {
58
59 // Serialization compatibility stuff:
60 // Two serial forms are supported in this class. The selected form depends
61 // on system property "jmx.serial.form":
62 // - "1.0" for JMX 1.0
63 // - any other value for JMX 1.1 and higher
64 //
65 // Serial version for old serial form
66 private static final long oldSerialVersionUID = 1716977971058914352L;
67 //
68 // Serial version for new serial form
69 private static final long newSerialVersionUID = -7516092053498031989L;
70 //
71 // Serializable fields in old serial form
72 private static final ObjectStreamField[] oldSerialPersistentFields =
73 {
74 new ObjectStreamField("message", String.class),
75 new ObjectStreamField("sequenceNumber", Long.TYPE),
76 new ObjectStreamField("source", Object.class),
77 new ObjectStreamField("sourceObjectName", ObjectName.class),
78 new ObjectStreamField("timeStamp", Long.TYPE),
79 new ObjectStreamField("type", String.class),
80 new ObjectStreamField("userData", Object.class)
81 };
82 //
83 // Serializable fields in new serial form
84 private static final ObjectStreamField[] newSerialPersistentFields =
85 {
86 new ObjectStreamField("message", String.class),
87 new ObjectStreamField("sequenceNumber", Long.TYPE),
88 new ObjectStreamField("source", Object.class),
89 new ObjectStreamField("timeStamp", Long.TYPE),
90 new ObjectStreamField("type", String.class),
91 new ObjectStreamField("userData", Object.class)
92 };
93 //
94 // Actual serial version and serial form
95 private static final long serialVersionUID;
96 /**
97 * @serialField type String The notification type.
98 * A string expressed in a dot notation similar to Java properties.
99 * An example of a notification type is network.alarm.router
100 * @serialField sequenceNumber long The notification sequence number.
101 * A serial number which identify particular instance
102 * of notification in the context of the notification source.
103 * @serialField timeStamp long The notification timestamp.
104 * Indicating when the notification was generated
105 * @serialField userData Object The notification user data.
106 * Used for whatever other data the notification
107 * source wishes to communicate to its consumers
108 * @serialField message String The notification message.
109 * @serialField source Object The object on which the notification initially occurred.
110 */
111 private static final ObjectStreamField[] serialPersistentFields;
112 private static boolean compat = false;
113 static {
114 try {
115 GetPropertyAction act = new GetPropertyAction("jmx.serial.form");
116 String form = AccessController.doPrivileged(act);
117 compat = (form != null && form.equals("1.0"));
118 } catch (Exception e) {
119 // OK: exception means no compat with 1.0, too bad
120 }
121 if (compat) {
122 serialPersistentFields = oldSerialPersistentFields;
123 serialVersionUID = oldSerialVersionUID;
124 } else {
125 serialPersistentFields = newSerialPersistentFields;
126 serialVersionUID = newSerialVersionUID;
127 }
128 }
129 //
130 // END Serialization compatibility stuff
131
132 /**
133 * @serial The notification type.
134 * A string expressed in a dot notation similar to Java properties.
135 * An example of a notification type is network.alarm.router
136 */
137 private String type;
138
139 /**
140 * @serial The notification sequence number.
141 * A serial number which identify particular instance
142 * of notification in the context of the notification source.
143 */
144 private long sequenceNumber;
145
146 /**
147 * @serial The notification timestamp.
148 * Indicating when the notification was generated
149 */
150 private long timeStamp;
151
152 /**
153 * @serial The notification user data.
154 * Used for whatever other data the notification
155 * source wishes to communicate to its consumers
156 */
157 private Object userData = null;
158
159 /**
160 * @serial The notification message.
161 */
162 private String message = "";
163
164 /**
165 * <p>This field hides the {@link EventObject#source} field in the
166 * parent class to make it non-transient and therefore part of the
167 * serialized form.</p>
168 *
169 * @serial The object on which the notification initially occurred.
170 */
171 protected Object source = null;
172
173
174 /**
175 * Creates a Notification object.
176 * The notification timeStamp is set to the current date.
177 *
178 * @param type The notification type.
179 * @param source The notification source.
180 * @param sequenceNumber The notification sequence number within the source object.
181 *
182 */
183 public Notification(String type, Object source, long sequenceNumber) {
184 super (source) ;
185 this.source = source;
186 this.type = type;
187 this.sequenceNumber = sequenceNumber ;
188 this.timeStamp = (new java.util.Date()).getTime() ;
189 }
190
191 /**
192 * Creates a Notification object.
193 * The notification timeStamp is set to the current date.
194 *
195 * @param type The notification type.
196 * @param source The notification source.
197 * @param sequenceNumber The notification sequence number within the source object.
198 * @param message The detailed message.
199 *
200 */
201 public Notification(String type, Object source, long sequenceNumber, String message) {
202 super (source) ;
203 this.source = source;
204 this.type = type;
205 this.sequenceNumber = sequenceNumber ;
206 this.timeStamp = (new java.util.Date()).getTime() ;
207 this.message = message ;
208 }
209
210 /**
211 * Creates a Notification object.
212 *
213 * @param type The notification type.
214 * @param source The notification source.
215 * @param sequenceNumber The notification sequence number within the source object.
216 * @param timeStamp The notification emission date.
217 *
218 */
219 public Notification(String type, Object source, long sequenceNumber, long timeStamp) {
220 super (source) ;
221 this.source = source;
222 this.type = type ;
223 this.sequenceNumber = sequenceNumber ;
224 this.timeStamp = timeStamp ;
225 }
226
227 /**
228 * Creates a Notification object.
229 *
230 * @param type The notification type.
231 * @param source The notification source.
232 * @param sequenceNumber The notification sequence number within the source object.
233 * @param timeStamp The notification emission date.
234 * @param message The detailed message.
235 *
236 */
237 public Notification(String type, Object source, 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="+message+"]";
360 }
361
362 /**
363 * Deserializes a {@link Notification} from an {@link ObjectInputStream}.
364 */
365 private void readObject(ObjectInputStream in)
366 throws IOException, ClassNotFoundException {
367 // New serial form ignores extra field "sourceObjectName"
368 in.defaultReadObject();
369 super.source = source;
370 }
371
372
373 /**
374 * Serializes a {@link Notification} to an {@link ObjectOutputStream}.
375 */
376 private void writeObject(ObjectOutputStream out)
377 throws IOException {
378 if (compat) {
379 // Serializes this instance in the old serial form
380 //
381 ObjectOutputStream.PutField fields = out.putFields();
382 fields.put("type", type);
383 fields.put("sequenceNumber", sequenceNumber);
384 fields.put("timeStamp", timeStamp);
385 fields.put("userData", userData);
386 fields.put("message", message);
387 fields.put("source", source);
388 out.writeFields();
389 } else {
390 // Serializes this instance in the new serial form
391 //
392 out.defaultWriteObject();
393 }
394 }
395 }