View Javadoc
1   /*
2    * Copyright (c) 1999, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * 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
289      * similar to Java properties. It is recommended that the notification type
290      * should follow the reverse-domain-name convention used by Java package
291      * names.  An example of a notification type is com.example.alarm.router.
292      */
293     public String getType() {
294         return type ;
295     }
296 
297     /**
298      * Get the notification timestamp.
299      *
300      * @return The notification timestamp.
301      *
302      * @see #setTimeStamp
303      */
304     public long getTimeStamp() {
305         return timeStamp ;
306     }
307 
308     /**
309      * Set the notification timestamp.
310      *
311      * @param timeStamp The notification timestamp. It indicates when the notification was generated.
312      *
313      * @see #getTimeStamp
314      */
315     public void setTimeStamp(long timeStamp) {
316         this.timeStamp = timeStamp;
317     }
318 
319     /**
320      * Get the notification message.
321      *
322      * @return The message string of this notification object.
323      *
324      */
325     public String getMessage() {
326         return message ;
327     }
328 
329     /**
330      * Get the user data.
331      *
332      * @return The user data object. It is used for whatever data
333      * the notification source wishes to communicate to its consumers.
334      *
335      * @see #setUserData
336      */
337     public Object getUserData() {
338         return userData ;
339     }
340 
341     /**
342      * Set the user data.
343      *
344      * @param userData The user data object. It is used for whatever data
345      * the notification source wishes to communicate to its consumers.
346      *
347      * @see #getUserData
348      */
349     public void setUserData(Object userData) {
350 
351         this.userData = userData ;
352     }
353 
354     /**
355      * Returns a String representation of this notification.
356      *
357      * @return A String representation of this notification.
358      */
359     @Override
360     public String toString() {
361         return super.toString()+"[type="+type+"][message="+message+"]";
362     }
363 
364     /**
365      * Deserializes a {@link Notification} from an {@link ObjectInputStream}.
366      */
367     private void readObject(ObjectInputStream in)
368             throws IOException, ClassNotFoundException {
369       // New serial form ignores extra field "sourceObjectName"
370       in.defaultReadObject();
371       super.source = source;
372     }
373 
374 
375     /**
376      * Serializes a {@link Notification} to an {@link ObjectOutputStream}.
377      */
378     private void writeObject(ObjectOutputStream out)
379             throws IOException {
380         if (compat) {
381             // Serializes this instance in the old serial form
382             //
383             ObjectOutputStream.PutField fields = out.putFields();
384             fields.put("type", type);
385             fields.put("sequenceNumber", sequenceNumber);
386             fields.put("timeStamp", timeStamp);
387             fields.put("userData", userData);
388             fields.put("message", message);
389             fields.put("source", source);
390             out.writeFields();
391         } else {
392             // Serializes this instance in the new serial form
393             //
394             out.defaultWriteObject();
395         }
396     }
397 }