blob: d54af3b5fa13e456b92fe016618ad6eefa11caf3 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-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
26package javax.management.relation;
27
28import javax.management.Notification;
29import javax.management.ObjectName;
30
31import java.io.IOException;
32import java.io.ObjectInputStream;
33import java.io.ObjectOutputStream;
34import java.io.ObjectStreamField;
35
36import java.security.AccessController;
37import java.security.PrivilegedAction;
38
39import java.util.ArrayList;
40import java.util.Collections;
41import java.util.List;
42
43import com.sun.jmx.mbeanserver.GetPropertyAction;
44import static com.sun.jmx.mbeanserver.Util.cast;
45
46/**
47 * A notification of a change in the Relation Service.
48 * A RelationNotification notification is sent when a relation is created via
49 * the Relation Service, or an MBean is added as a relation in the Relation
50 * Service, or a role is updated in a relation, or a relation is removed from
51 * the Relation Service.
52 *
53 * <p>The <b>serialVersionUID</b> of this class is <code>-6871117877523310399L</code>.
54 *
55 * @since 1.5
56 */
57@SuppressWarnings("serial") // serialVersionUID not constant
58public class RelationNotification extends Notification {
59
60 // Serialization compatibility stuff:
61 // Two serial forms are supported in this class. The selected form depends
62 // on system property "jmx.serial.form":
63 // - "1.0" for JMX 1.0
64 // - any other value for JMX 1.1 and higher
65 //
66 // Serial version for old serial form
67 private static final long oldSerialVersionUID = -2126464566505527147L;
68 //
69 // Serial version for new serial form
70 private static final long newSerialVersionUID = -6871117877523310399L;
71 //
72 // Serializable fields in old serial form
73 private static final ObjectStreamField[] oldSerialPersistentFields =
74 {
75 new ObjectStreamField("myNewRoleValue", ArrayList.class),
76 new ObjectStreamField("myOldRoleValue", ArrayList.class),
77 new ObjectStreamField("myRelId", String.class),
78 new ObjectStreamField("myRelObjName", ObjectName.class),
79 new ObjectStreamField("myRelTypeName", String.class),
80 new ObjectStreamField("myRoleName", String.class),
81 new ObjectStreamField("myUnregMBeanList", ArrayList.class)
82 };
83 //
84 // Serializable fields in new serial form
85 private static final ObjectStreamField[] newSerialPersistentFields =
86 {
87 new ObjectStreamField("newRoleValue", List.class),
88 new ObjectStreamField("oldRoleValue", List.class),
89 new ObjectStreamField("relationId", String.class),
90 new ObjectStreamField("relationObjName", ObjectName.class),
91 new ObjectStreamField("relationTypeName", String.class),
92 new ObjectStreamField("roleName", String.class),
93 new ObjectStreamField("unregisterMBeanList", List.class)
94 };
95 //
96 // Actual serial version and serial form
97 private static final long serialVersionUID;
98 /**
99 * @serialField relationId String Relation identifier of
100 * created/removed/updated relation
101 * @serialField relationTypeName String Relation type name of
102 * created/removed/updated relation
103 * @serialField relationObjName ObjectName {@link ObjectName} of
104 * the relation MBean of created/removed/updated relation (only if
105 * the relation is represented by an MBean)
106 * @serialField unregisterMBeanList List List of {@link
107 * ObjectName}s of referenced MBeans to be unregistered due to
108 * relation removal
109 * @serialField roleName String Name of updated role (only for role update)
110 * @serialField oldRoleValue List Old role value ({@link
111 * ArrayList} of {@link ObjectName}s) (only for role update)
112 * @serialField newRoleValue List New role value ({@link
113 * ArrayList} of {@link ObjectName}s) (only for role update)
114 */
115 private static final ObjectStreamField[] serialPersistentFields;
116 private static boolean compat = false;
117 static {
118 try {
119 GetPropertyAction act = new GetPropertyAction("jmx.serial.form");
120 String form = AccessController.doPrivileged(act);
121 compat = (form != null && form.equals("1.0"));
122 } catch (Exception e) {
123 // OK : Too bad, no compat with 1.0
124 }
125 if (compat) {
126 serialPersistentFields = oldSerialPersistentFields;
127 serialVersionUID = oldSerialVersionUID;
128 } else {
129 serialPersistentFields = newSerialPersistentFields;
130 serialVersionUID = newSerialVersionUID;
131 }
132 }
133 //
134 // END Serialization compatibility stuff
135
136 //
137 // Notification types
138 //
139
140 /**
141 * Type for the creation of an internal relation.
142 */
143 public static final String RELATION_BASIC_CREATION = "jmx.relation.creation.basic";
144 /**
145 * Type for the relation MBean added into the Relation Service.
146 */
147 public static final String RELATION_MBEAN_CREATION = "jmx.relation.creation.mbean";
148 /**
149 * Type for an update of an internal relation.
150 */
151 public static final String RELATION_BASIC_UPDATE = "jmx.relation.update.basic";
152 /**
153 * Type for the update of a relation MBean.
154 */
155 public static final String RELATION_MBEAN_UPDATE = "jmx.relation.update.mbean";
156 /**
157 * Type for the removal from the Relation Service of an internal relation.
158 */
159 public static final String RELATION_BASIC_REMOVAL = "jmx.relation.removal.basic";
160 /**
161 * Type for the removal from the Relation Service of a relation MBean.
162 */
163 public static final String RELATION_MBEAN_REMOVAL = "jmx.relation.removal.mbean";
164
165 //
166 // Private members
167 //
168
169 /**
170 * @serial Relation identifier of created/removed/updated relation
171 */
172 private String relationId = null;
173
174 /**
175 * @serial Relation type name of created/removed/updated relation
176 */
177 private String relationTypeName = null;
178
179 /**
180 * @serial {@link ObjectName} of the relation MBean of created/removed/updated relation
181 * (only if the relation is represented by an MBean)
182 */
183 private ObjectName relationObjName = null;
184
185 /**
186 * @serial List of {@link ObjectName}s of referenced MBeans to be unregistered due to
187 * relation removal
188 */
189 private List<ObjectName> unregisterMBeanList = null;
190
191 /**
192 * @serial Name of updated role (only for role update)
193 */
194 private String roleName = null;
195
196 /**
197 * @serial Old role value ({@link ArrayList} of {@link ObjectName}s) (only for role update)
198 */
199 private List<ObjectName> oldRoleValue = null;
200
201 /**
202 * @serial New role value ({@link ArrayList} of {@link ObjectName}s) (only for role update)
203 */
204 private List<ObjectName> newRoleValue = null;
205
206 //
207 // Constructors
208 //
209
210 /**
211 * Creates a notification for either a relation creation (RelationSupport
212 * object created internally in the Relation Service, or an MBean added as a
213 * relation) or for a relation removal from the Relation Service.
214 *
215 * @param notifType type of the notification; either:
216 * <P>- RELATION_BASIC_CREATION
217 * <P>- RELATION_MBEAN_CREATION
218 * <P>- RELATION_BASIC_REMOVAL
219 * <P>- RELATION_MBEAN_REMOVAL
220 * @param sourceObj source object, sending the notification. This is either
221 * an ObjectName or a RelationService object. In the latter case it must be
222 * the MBean emitting the notification; the MBean Server will rewrite the
223 * source to be the ObjectName under which that MBean is registered.
224 * @param sequence sequence number to identify the notification
225 * @param timeStamp time stamp
226 * @param message human-readable message describing the notification
227 * @param id relation id identifying the relation in the Relation
228 * Service
229 * @param typeName name of the relation type
230 * @param objectName ObjectName of the relation object if it is an MBean
231 * (null for relations internally handled by the Relation Service)
232 * @param unregMBeanList list of ObjectNames of referenced MBeans
233 * expected to be unregistered due to relation removal (only for removal,
234 * due to CIM qualifiers, can be null)
235 *
236 * @exception IllegalArgumentException if:
237 * <P>- no value for the notification type
238 * <P>- the notification type is not RELATION_BASIC_CREATION,
239 * RELATION_MBEAN_CREATION, RELATION_BASIC_REMOVAL or
240 * RELATION_MBEAN_REMOVAL
241 * <P>- no source object
242 * <P>- the source object is not a Relation Service
243 * <P>- no relation id
244 * <P>- no relation type name
245 */
246 public RelationNotification(String notifType,
247 Object sourceObj,
248 long sequence,
249 long timeStamp,
250 String message,
251 String id,
252 String typeName,
253 ObjectName objectName,
254 List<ObjectName> unregMBeanList)
255 throws IllegalArgumentException {
256
257 super(notifType, sourceObj, sequence, timeStamp, message);
258
259 // Can throw IllegalArgumentException
260 initMembers(1,
261 notifType,
262 sourceObj,
263 sequence,
264 timeStamp,
265 message,
266 id,
267 typeName,
268 objectName,
269 unregMBeanList,
270 null,
271 null,
272 null);
273 return;
274 }
275
276 /**
277 * Creates a notification for a role update in a relation.
278 *
279 * @param notifType type of the notification; either:
280 * <P>- RELATION_BASIC_UPDATE
281 * <P>- RELATION_MBEAN_UPDATE
282 * @param sourceObj source object, sending the notification. This is either
283 * an ObjectName or a RelationService object. In the latter case it must be
284 * the MBean emitting the notification; the MBean Server will rewrite the
285 * source to be the ObjectName under which that MBean is registered.
286 * @param sequence sequence number to identify the notification
287 * @param timeStamp time stamp
288 * @param message human-readable message describing the notification
289 * @param id relation id identifying the relation in the Relation
290 * Service
291 * @param typeName name of the relation type
292 * @param objectName ObjectName of the relation object if it is an MBean
293 * (null for relations internally handled by the Relation Service)
294 * @param name name of the updated role
295 * @param newValue new role value (List of ObjectName objects)
296 * @param oldValue old role value (List of ObjectName objects)
297 *
298 * @exception IllegalArgumentException if null parameter
299 */
300 public RelationNotification(String notifType,
301 Object sourceObj,
302 long sequence,
303 long timeStamp,
304 String message,
305 String id,
306 String typeName,
307 ObjectName objectName,
308 String name,
309 List<ObjectName> newValue,
310 List<ObjectName> oldValue
311 )
312 throws IllegalArgumentException {
313
314 super(notifType, sourceObj, sequence, timeStamp, message);
315
316 // Can throw IllegalArgumentException
317 initMembers(2,
318 notifType,
319 sourceObj,
320 sequence,
321 timeStamp,
322 message,
323 id,
324 typeName,
325 objectName,
326 null,
327 name,
328 newValue,
329 oldValue);
330 return;
331 }
332
333 //
334 // Accessors
335 //
336
337 /**
338 * Returns the relation identifier of created/removed/updated relation.
339 *
340 * @return the relation id.
341 */
342 public String getRelationId() {
343 return relationId;
344 }
345
346 /**
347 * Returns the relation type name of created/removed/updated relation.
348 *
349 * @return the relation type name.
350 */
351 public String getRelationTypeName() {
352 return relationTypeName;
353 }
354
355 /**
356 * Returns the ObjectName of the
357 * created/removed/updated relation.
358 *
359 * @return the ObjectName if the relation is an MBean, otherwise null.
360 */
361 public ObjectName getObjectName() {
362 return relationObjName;
363 }
364
365 /**
366 * Returns the list of ObjectNames of MBeans expected to be unregistered
367 * due to a relation removal (only for relation removal).
368 *
369 * @return a {@link List} of {@link ObjectName}.
370 */
371 public List<ObjectName> getMBeansToUnregister() {
372 List<ObjectName> result = null;
373 if (unregisterMBeanList != null) {
374 result = new ArrayList<ObjectName>(unregisterMBeanList);
375 } else {
376 result = Collections.emptyList();
377 }
378 return result;
379 }
380
381 /**
382 * Returns name of updated role of updated relation (only for role update).
383 *
384 * @return the name of the updated role.
385 */
386 public String getRoleName() {
387 String result = null;
388 if (roleName != null) {
389 result = roleName;
390 }
391 return result;
392 }
393
394 /**
395 * Returns old value of updated role (only for role update).
396 *
397 * @return the old value of the updated role.
398 */
399 public List<ObjectName> getOldRoleValue() {
400 List<ObjectName> result = null;
401 if (oldRoleValue != null) {
402 result = new ArrayList<ObjectName>(oldRoleValue);
403 } else {
404 result = Collections.emptyList();
405 }
406 return result;
407 }
408
409 /**
410 * Returns new value of updated role (only for role update).
411 *
412 * @return the new value of the updated role.
413 */
414 public List<ObjectName> getNewRoleValue() {
415 List<ObjectName> result = null;
416 if (newRoleValue != null) {
417 result = new ArrayList<ObjectName>(newRoleValue);
418 } else {
419 result = Collections.emptyList();
420 }
421 return result;
422 }
423
424 //
425 // Misc
426 //
427
428 // Initializes members
429 //
430 // -param notifKind 1 for creation/removal, 2 for update
431 // -param notifType type of the notification; either:
432 // - RELATION_BASIC_UPDATE
433 // - RELATION_MBEAN_UPDATE
434 // for an update, or:
435 // - RELATION_BASIC_CREATION
436 // - RELATION_MBEAN_CREATION
437 // - RELATION_BASIC_REMOVAL
438 // - RELATION_MBEAN_REMOVAL
439 // for a creation or removal
440 // -param sourceObj source object, sending the notification. Will always
441 // be a RelationService object.
442 // -param sequence sequence number to identify the notification
443 // -param timeStamp time stamp
444 // -param message human-readable message describing the notification
445 // -param id relation id identifying the relation in the Relation
446 // Service
447 // -param typeName name of the relation type
448 // -param objectName ObjectName of the relation object if it is an MBean
449 // (null for relations internally handled by the Relation Service)
450 // -param unregMBeanList list of ObjectNames of MBeans expected to be
451 // removed due to relation removal
452 // -param name name of the updated role
453 // -param newValue new value (List of ObjectName objects)
454 // -param oldValue old value (List of ObjectName objects)
455 //
456 // -exception IllegalArgumentException if:
457 // - no value for the notification type
458 // - incorrect notification type
459 // - no source object
460 // - the source object is not a Relation Service
461 // - no relation id
462 // - no relation type name
463 // - no role name (for role update)
464 // - no role old value (for role update)
465 // - no role new value (for role update)
466 private void initMembers(int notifKind,
467 String notifType,
468 Object sourceObj,
469 long sequence,
470 long timeStamp,
471 String message,
472 String id,
473 String typeName,
474 ObjectName objectName,
475 List<ObjectName> unregMBeanList,
476 String name,
477 List<ObjectName> newValue,
478 List<ObjectName> oldValue)
479 throws IllegalArgumentException {
480
481 boolean badInitFlg = false;
482
483 if (notifType == null ||
484 sourceObj == null ||
485 (!(sourceObj instanceof RelationService) &&
486 !(sourceObj instanceof ObjectName)) ||
487 id == null ||
488 typeName == null) {
489
490 badInitFlg = true;
491 }
492
493 if (notifKind == 1) {
494
495 if ((!(notifType.equals(RelationNotification.RELATION_BASIC_CREATION)))
496 &&
497 (!(notifType.equals(RelationNotification.RELATION_MBEAN_CREATION)))
498 &&
499 (!(notifType.equals(RelationNotification.RELATION_BASIC_REMOVAL)))
500 &&
501 (!(notifType.equals(RelationNotification.RELATION_MBEAN_REMOVAL)))
502 ) {
503
504 // Creation/removal
505 badInitFlg = true;
506 }
507
508 } else if (notifKind == 2) {
509
510 if (((!(notifType.equals(RelationNotification.RELATION_BASIC_UPDATE)))
511 &&
512 (!(notifType.equals(RelationNotification.RELATION_MBEAN_UPDATE))))
513 || name == null ||
514 oldValue == null ||
515 newValue == null) {
516
517 // Role update
518 badInitFlg = true;
519 }
520 }
521
522 if (badInitFlg) {
523 String excMsg = "Invalid parameter.";
524 throw new IllegalArgumentException(excMsg);
525 }
526
527 relationId = id;
528 relationTypeName = typeName;
529 relationObjName = objectName;
530 if (unregMBeanList != null) {
531 unregisterMBeanList = new ArrayList<ObjectName>(unregMBeanList);
532 }
533 if (name != null) {
534 roleName = name;
535 }
536 if (oldValue != null) {
537 oldRoleValue = new ArrayList<ObjectName>(oldValue);
538 }
539 if (newValue != null) {
540 newRoleValue = new ArrayList<ObjectName>(newValue);
541 }
542 return;
543 }
544
545 /**
546 * Deserializes a {@link RelationNotification} from an {@link ObjectInputStream}.
547 */
548 private void readObject(ObjectInputStream in)
549 throws IOException, ClassNotFoundException {
550 if (compat)
551 {
552 // Read an object serialized in the old serial form
553 //
554 ObjectInputStream.GetField fields = in.readFields();
555 newRoleValue = cast(fields.get("myNewRoleValue", null));
556 if (fields.defaulted("myNewRoleValue"))
557 {
558 throw new NullPointerException("newRoleValue");
559 }
560 oldRoleValue = cast(fields.get("myOldRoleValue", null));
561 if (fields.defaulted("myOldRoleValue"))
562 {
563 throw new NullPointerException("oldRoleValue");
564 }
565 relationId = (String) fields.get("myRelId", null);
566 if (fields.defaulted("myRelId"))
567 {
568 throw new NullPointerException("relationId");
569 }
570 relationObjName = (ObjectName) fields.get("myRelObjName", null);
571 if (fields.defaulted("myRelObjName"))
572 {
573 throw new NullPointerException("relationObjName");
574 }
575 relationTypeName = (String) fields.get("myRelTypeName", null);
576 if (fields.defaulted("myRelTypeName"))
577 {
578 throw new NullPointerException("relationTypeName");
579 }
580 roleName = (String) fields.get("myRoleName", null);
581 if (fields.defaulted("myRoleName"))
582 {
583 throw new NullPointerException("roleName");
584 }
585 unregisterMBeanList = cast(fields.get("myUnregMBeanList", null));
586 if (fields.defaulted("myUnregMBeanList"))
587 {
588 throw new NullPointerException("unregisterMBeanList");
589 }
590 }
591 else
592 {
593 // Read an object serialized in the new serial form
594 //
595 in.defaultReadObject();
596 }
597 }
598
599
600 /**
601 * Serializes a {@link RelationNotification} to an {@link ObjectOutputStream}.
602 */
603 private void writeObject(ObjectOutputStream out)
604 throws IOException {
605 if (compat)
606 {
607 // Serializes this instance in the old serial form
608 //
609 ObjectOutputStream.PutField fields = out.putFields();
610 fields.put("myNewRoleValue", newRoleValue);
611 fields.put("myOldRoleValue", oldRoleValue);
612 fields.put("myRelId", relationId);
613 fields.put("myRelObjName", relationObjName);
614 fields.put("myRelTypeName", relationTypeName);
615 fields.put("myRoleName",roleName);
616 fields.put("myUnregMBeanList", unregisterMBeanList);
617 out.writeFields();
618 }
619 else
620 {
621 // Serializes this instance in the new serial form
622 //
623 out.defaultWriteObject();
624 }
625 }
626}