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