1. /*
  2. * @(#)RoleInfo.java 1.34 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 java.io.IOException;
  9. import java.io.ObjectInputStream;
  10. import java.io.ObjectOutputStream;
  11. import java.io.ObjectStreamField;
  12. import java.io.Serializable;
  13. import java.security.AccessController;
  14. import java.security.PrivilegedAction;
  15. import javax.management.NotCompliantMBeanException;
  16. import javax.management.MBeanInfo;
  17. import javax.management.MBeanServer;
  18. import javax.management.loading.ClassLoaderRepository;
  19. import com.sun.jmx.mbeanserver.GetPropertyAction;
  20. import com.sun.jmx.mbeanserver.Introspector;
  21. /**
  22. * A RoleInfo object summarises a role in a relation type.
  23. *
  24. * @since 1.5
  25. */
  26. public class RoleInfo implements Serializable {
  27. // Serialization compatibility stuff:
  28. // Two serial forms are supported in this class. The selected form depends
  29. // on system property "jmx.serial.form":
  30. // - "1.0" for JMX 1.0
  31. // - any other value for JMX 1.1 and higher
  32. //
  33. // Serial version for old serial form
  34. private static final long oldSerialVersionUID = 7227256952085334351L;
  35. //
  36. // Serial version for new serial form
  37. private static final long newSerialVersionUID = 2504952983494636987L;
  38. //
  39. // Serializable fields in old serial form
  40. private static final ObjectStreamField[] oldSerialPersistentFields =
  41. {
  42. new ObjectStreamField("myName", String.class),
  43. new ObjectStreamField("myIsReadableFlg", boolean.class),
  44. new ObjectStreamField("myIsWritableFlg", boolean.class),
  45. new ObjectStreamField("myDescription", String.class),
  46. new ObjectStreamField("myMinDegree", int.class),
  47. new ObjectStreamField("myMaxDegree", int.class),
  48. new ObjectStreamField("myRefMBeanClassName", String.class)
  49. };
  50. //
  51. // Serializable fields in new serial form
  52. private static final ObjectStreamField[] newSerialPersistentFields =
  53. {
  54. new ObjectStreamField("name", String.class),
  55. new ObjectStreamField("isReadable", boolean.class),
  56. new ObjectStreamField("isWritable", boolean.class),
  57. new ObjectStreamField("description", String.class),
  58. new ObjectStreamField("minDegree", int.class),
  59. new ObjectStreamField("maxDegree", int.class),
  60. new ObjectStreamField("referencedMBeanClassName", String.class)
  61. };
  62. //
  63. // Actual serial version and serial form
  64. private static final long serialVersionUID;
  65. /**
  66. * @serialField name String Role name
  67. * @serialField isReadable boolean Read access mode: <code>true</code> if role is readable
  68. * @serialField isWritable boolean Write access mode: <code>true</code> if role is writable
  69. * @serialField description String Role description
  70. * @serialField minDegree int Minimum degree (i.e. minimum number of referenced MBeans in corresponding role)
  71. * @serialField maxDegree int Maximum degree (i.e. maximum number of referenced MBeans in corresponding role)
  72. * @serialField referencedMBeanClassName String Name of class of MBean(s) expected to be referenced in corresponding role
  73. */
  74. private static final ObjectStreamField[] serialPersistentFields;
  75. private static boolean compat = false;
  76. static {
  77. try {
  78. PrivilegedAction act = new GetPropertyAction("jmx.serial.form");
  79. String form = (String) AccessController.doPrivileged(act);
  80. compat = (form != null && form.equals("1.0"));
  81. } catch (Exception e) {
  82. // OK : Too bad, no compat with 1.0
  83. }
  84. if (compat) {
  85. serialPersistentFields = oldSerialPersistentFields;
  86. serialVersionUID = oldSerialVersionUID;
  87. } else {
  88. serialPersistentFields = newSerialPersistentFields;
  89. serialVersionUID = newSerialVersionUID;
  90. }
  91. }
  92. //
  93. // END Serialization compatibility stuff
  94. //
  95. // Public constants
  96. //
  97. /**
  98. * To specify an unlimited cardinality.
  99. */
  100. public static int ROLE_CARDINALITY_INFINITY = -1;
  101. //
  102. // Private members
  103. //
  104. /**
  105. * @serial Role name
  106. */
  107. private String name = null;
  108. /**
  109. * @serial Read access mode: <code>true</code> if role is readable
  110. */
  111. private boolean isReadable;
  112. /**
  113. * @serial Write access mode: <code>true</code> if role is writable
  114. */
  115. private boolean isWritable;
  116. /**
  117. * @serial Role description
  118. */
  119. private String description = null;
  120. /**
  121. * @serial Minimum degree (i.e. minimum number of referenced MBeans in corresponding role)
  122. */
  123. private int minDegree;
  124. /**
  125. * @serial Maximum degree (i.e. maximum number of referenced MBeans in corresponding role)
  126. */
  127. private int maxDegree;
  128. /**
  129. * @serial Name of class of MBean(s) expected to be referenced in corresponding role
  130. */
  131. private String referencedMBeanClassName = null;
  132. //
  133. // Constructors
  134. //
  135. /**
  136. * Constructor.
  137. *
  138. * @param theName name of the role.
  139. * @param theRefMBeanClassName name of the class of MBean(s) expected to
  140. * be referenced in corresponding role. If an MBean <em>M</em> is in
  141. * this role, then the MBean server must return true for
  142. * {@link MBeanServer#isInstanceOf isInstanceOf(M, theRefMBeanClassName)}.
  143. * @param theIsReadable flag to indicate if the corresponding role
  144. * can be read
  145. * @param theIsWritable flag to indicate if the corresponding role
  146. * can be set
  147. * @param theMinDegree minimum degree for role, i.e. minimum number of
  148. * MBeans to provide in corresponding role
  149. * Must be less or equal than theMaxDegree.
  150. * (ROLE_CARDINALITY_INFINITY for unlimited)
  151. * @param theMaxDegree maximum degree for role, i.e. maximum number of
  152. * MBeans to provide in corresponding role
  153. * Must be greater or equal than theMinDegree
  154. * (ROLE_CARDINALITY_INFINITY for unlimited)
  155. * @param theDescription description of the role (can be null)
  156. *
  157. * @exception IllegalArgumentException if null parameter
  158. * @exception InvalidRoleInfoException if the minimum degree is
  159. * greater than the maximum degree.
  160. * @exception ClassNotFoundException As of JMX 1.2, this exception
  161. * can no longer be thrown. It is retained in the declaration of
  162. * this class for compatibility with existing code.
  163. * @exception NotCompliantMBeanException if the class theRefMBeanClassName
  164. * is not a MBean class.
  165. */
  166. public RoleInfo(String theName,
  167. String theRefMBeanClassName,
  168. boolean theIsReadable,
  169. boolean theIsWritable,
  170. int theMinDegree,
  171. int theMaxDegree,
  172. String theDescription)
  173. throws IllegalArgumentException,
  174. InvalidRoleInfoException,
  175. ClassNotFoundException,
  176. NotCompliantMBeanException {
  177. init(theName,
  178. theRefMBeanClassName,
  179. theIsReadable,
  180. theIsWritable,
  181. theMinDegree,
  182. theMaxDegree,
  183. theDescription);
  184. return;
  185. }
  186. /**
  187. * Constructor.
  188. *
  189. * @param theName name of the role
  190. * @param theRefMBeanClassName name of the class of MBean(s) expected to
  191. * be referenced in corresponding role. If an MBean <em>M</em> is in
  192. * this role, then the MBean server must return true for
  193. * {@link MBeanServer#isInstanceOf isInstanceOf(M, theRefMBeanClassName)}.
  194. * @param theIsReadable flag to indicate if the corresponding role
  195. * can be read
  196. * @param theIsWritable flag to indicate if the corresponding role
  197. * can be set
  198. *
  199. * <P>Minimum and maximum degrees defaulted to 1.
  200. * <P>Description of role defaulted to null.
  201. *
  202. * @exception IllegalArgumentException if null parameter
  203. * @exception ClassNotFoundException As of JMX 1.2, this exception
  204. * can no longer be thrown. It is retained in the declaration of
  205. * this class for compatibility with existing code.
  206. * @exception NotCompliantMBeanException As of JMX 1.2, this
  207. * exception can no longer be thrown. It is retained in the
  208. * declaration of this class for compatibility with existing code.
  209. */
  210. public RoleInfo(String theName,
  211. String theRefMBeanClassName,
  212. boolean theIsReadable,
  213. boolean theIsWritable)
  214. throws IllegalArgumentException,
  215. ClassNotFoundException,
  216. NotCompliantMBeanException {
  217. try {
  218. init(theName,
  219. theRefMBeanClassName,
  220. theIsReadable,
  221. theIsWritable,
  222. 1,
  223. 1,
  224. null);
  225. } catch (InvalidRoleInfoException exc) {
  226. // OK : Can never happen as the minimum
  227. // degree equals the maximum degree.
  228. }
  229. return;
  230. }
  231. /**
  232. * Constructor.
  233. *
  234. * @param theName name of the role
  235. * @param theRefMBeanClassName name of the class of MBean(s) expected to
  236. * be referenced in corresponding role. If an MBean <em>M</em> is in
  237. * this role, then the MBean server must return true for
  238. * {@link MBeanServer#isInstanceOf isInstanceOf(M, theRefMBeanClassName)}.
  239. *
  240. * <P>IsReadable and IsWritable defaulted to true.
  241. * <P>Minimum and maximum degrees defaulted to 1.
  242. * <P>Description of role defaulted to null.
  243. *
  244. * @exception IllegalArgumentException if null parameter
  245. * @exception ClassNotFoundException As of JMX 1.2, this exception
  246. * can no longer be thrown. It is retained in the declaration of
  247. * this class for compatibility with existing code.
  248. * @exception NotCompliantMBeanException As of JMX 1.2, this
  249. * exception can no longer be thrown. It is retained in the
  250. * declaration of this class for compatibility with existing code.
  251. */
  252. public RoleInfo(String theName,
  253. String theRefMBeanClassName)
  254. throws IllegalArgumentException,
  255. ClassNotFoundException,
  256. NotCompliantMBeanException {
  257. try {
  258. init(theName,
  259. theRefMBeanClassName,
  260. true,
  261. true,
  262. 1,
  263. 1,
  264. null);
  265. } catch (InvalidRoleInfoException exc) {
  266. // OK : Can never happen as the minimum
  267. // degree equals the maximum degree.
  268. }
  269. return;
  270. }
  271. /**
  272. * Copy constructor.
  273. *
  274. * @param theRoleInfo the RoleInfo to be copied.
  275. *
  276. * @exception IllegalArgumentException if null parameter
  277. */
  278. public RoleInfo(RoleInfo theRoleInfo)
  279. throws IllegalArgumentException {
  280. if (theRoleInfo == null) {
  281. // Revisit [cebro] Localize message
  282. String excMsg = "Invalid parameter.";
  283. throw new IllegalArgumentException(excMsg);
  284. }
  285. try {
  286. init(theRoleInfo.getName(),
  287. theRoleInfo.getRefMBeanClassName(),
  288. theRoleInfo.isReadable(),
  289. theRoleInfo.isWritable(),
  290. theRoleInfo.getMinDegree(),
  291. theRoleInfo.getMaxDegree(),
  292. theRoleInfo.getDescription());
  293. } catch (InvalidRoleInfoException exc3) {
  294. // OK : Can never happen as the minimum degree and the maximum
  295. // degree were already checked at the time the theRoleInfo
  296. // instance was created.
  297. }
  298. }
  299. //
  300. // Accessors
  301. //
  302. /**
  303. * Returns the name of the role.
  304. *
  305. * @return the name of the role.
  306. */
  307. public String getName() {
  308. return name;
  309. }
  310. /**
  311. * Returns read access mode for the role (true if it is readable).
  312. *
  313. * @return true if the role is readable.
  314. */
  315. public boolean isReadable() {
  316. return isReadable;
  317. }
  318. /**
  319. * Returns write access mode for the role (true if it is writable).
  320. *
  321. * @return true if the role is writable.
  322. */
  323. public boolean isWritable() {
  324. return isWritable;
  325. }
  326. /**
  327. * Returns description text for the role.
  328. *
  329. * @return the description of the role.
  330. */
  331. public String getDescription() {
  332. return description;
  333. }
  334. /**
  335. * Returns minimum degree for corresponding role reference.
  336. *
  337. * @return the minimum degree.
  338. */
  339. public int getMinDegree() {
  340. return minDegree;
  341. }
  342. /**
  343. * Returns maximum degree for corresponding role reference.
  344. *
  345. * @return the maximum degree.
  346. */
  347. public int getMaxDegree() {
  348. return maxDegree;
  349. }
  350. /**
  351. * <p>Returns name of type of MBean expected to be referenced in
  352. * corresponding role.</p>
  353. *
  354. * @return the name of the referenced type.
  355. */
  356. public String getRefMBeanClassName() {
  357. return referencedMBeanClassName;
  358. }
  359. /**
  360. * Returns a boolean to specify if given value is greater or equal than
  361. * expected minimum degree (true if yes).
  362. *
  363. * @param theValue value
  364. *
  365. * @return true if greater or equal than minimum degree, false otherwise.
  366. */
  367. public boolean checkMinDegree(int theValue) {
  368. if (theValue >= ROLE_CARDINALITY_INFINITY &&
  369. (minDegree == ROLE_CARDINALITY_INFINITY
  370. || theValue >= minDegree)) {
  371. return true;
  372. } else {
  373. return false;
  374. }
  375. }
  376. /**
  377. * Returns a boolean to specify if given value is less or equal than
  378. * expected maximum degree (true if yes).
  379. *
  380. * @param theValue value
  381. *
  382. * @return true if less or equal than maximum degree, false otherwise.
  383. */
  384. public boolean checkMaxDegree(int theValue) {
  385. if (theValue >= ROLE_CARDINALITY_INFINITY &&
  386. (maxDegree == ROLE_CARDINALITY_INFINITY ||
  387. (theValue != ROLE_CARDINALITY_INFINITY &&
  388. theValue <= maxDegree))) {
  389. return true;
  390. } else {
  391. return false;
  392. }
  393. }
  394. /**
  395. * Returns a string describing the role info.
  396. *
  397. * @return a description of the role info.
  398. */
  399. public String toString() {
  400. StringBuffer result = new StringBuffer();
  401. result.append("role info name: " + name);
  402. result.append("; isReadable: " + isReadable);
  403. result.append("; isWritable: " + isWritable);
  404. result.append("; description: " + description);
  405. result.append("; minimum degree: " + minDegree);
  406. result.append("; maximum degree: " + maxDegree);
  407. result.append("; MBean class: " + referencedMBeanClassName);
  408. return result.toString();
  409. }
  410. //
  411. // Misc
  412. //
  413. // Initialisation
  414. private void init(String theName,
  415. String theRefMBeanClassName,
  416. boolean theIsReadable,
  417. boolean theIsWritable,
  418. int theMinDegree,
  419. int theMaxDegree,
  420. String theDescription)
  421. throws IllegalArgumentException,
  422. InvalidRoleInfoException {
  423. if (theName == null ||
  424. theRefMBeanClassName == null) {
  425. // Revisit [cebro] Localize message
  426. String excMsg = "Invalid parameter.";
  427. throw new IllegalArgumentException(excMsg);
  428. }
  429. name = theName;
  430. isReadable = theIsReadable;
  431. isWritable = theIsWritable;
  432. if (theDescription != null) {
  433. description = theDescription;
  434. }
  435. boolean invalidRoleInfoFlg = false;
  436. StringBuffer excMsgStrB = new StringBuffer();
  437. if (theMaxDegree != ROLE_CARDINALITY_INFINITY &&
  438. (theMinDegree == ROLE_CARDINALITY_INFINITY ||
  439. theMinDegree > theMaxDegree)) {
  440. // Revisit [cebro] Localize message
  441. excMsgStrB.append("Minimum degree ");
  442. excMsgStrB.append(theMinDegree);
  443. excMsgStrB.append(" is greater than maximum degree ");
  444. excMsgStrB.append(theMaxDegree);
  445. invalidRoleInfoFlg = true;
  446. } else if (theMinDegree < ROLE_CARDINALITY_INFINITY ||
  447. theMaxDegree < ROLE_CARDINALITY_INFINITY) {
  448. // Revisit [cebro] Localize message
  449. excMsgStrB.append("Minimum or maximum degree has an illegal value, must be [0, ROLE_CARDINALITY_INFINITY].");
  450. invalidRoleInfoFlg = true;
  451. }
  452. if (invalidRoleInfoFlg) {
  453. throw new InvalidRoleInfoException(excMsgStrB.toString());
  454. }
  455. minDegree = theMinDegree;
  456. maxDegree = theMaxDegree;
  457. referencedMBeanClassName = theRefMBeanClassName;
  458. return;
  459. }
  460. /**
  461. * Deserializes a {@link RoleInfo} from an {@link ObjectInputStream}.
  462. */
  463. private void readObject(ObjectInputStream in)
  464. throws IOException, ClassNotFoundException {
  465. if (compat)
  466. {
  467. // Read an object serialized in the old serial form
  468. //
  469. ObjectInputStream.GetField fields = in.readFields();
  470. name = (String) fields.get("myName", null);
  471. if (fields.defaulted("myName"))
  472. {
  473. throw new NullPointerException("myName");
  474. }
  475. isReadable = fields.get("myIsReadableFlg", false);
  476. if (fields.defaulted("myIsReadableFlg"))
  477. {
  478. throw new NullPointerException("myIsReadableFlg");
  479. }
  480. isWritable = fields.get("myIsWritableFlg", false);
  481. if (fields.defaulted("myIsWritableFlg"))
  482. {
  483. throw new NullPointerException("myIsWritableFlg");
  484. }
  485. description = (String) fields.get("myDescription", null);
  486. if (fields.defaulted("myDescription"))
  487. {
  488. throw new NullPointerException("myDescription");
  489. }
  490. minDegree = fields.get("myMinDegree", (int)0);
  491. if (fields.defaulted("myMinDegree"))
  492. {
  493. throw new NullPointerException("myMinDegree");
  494. }
  495. maxDegree = fields.get("myMaxDegree", (int)0);
  496. if (fields.defaulted("myMaxDegree"))
  497. {
  498. throw new NullPointerException("myMaxDegree");
  499. }
  500. referencedMBeanClassName = (String) fields.get("myRefMBeanClassName", null);
  501. if (fields.defaulted("myRefMBeanClassName"))
  502. {
  503. throw new NullPointerException("myRefMBeanClassName");
  504. }
  505. }
  506. else
  507. {
  508. // Read an object serialized in the new serial form
  509. //
  510. in.defaultReadObject();
  511. }
  512. }
  513. /**
  514. * Serializes a {@link RoleInfo} to an {@link ObjectOutputStream}.
  515. */
  516. private void writeObject(ObjectOutputStream out)
  517. throws IOException {
  518. if (compat)
  519. {
  520. // Serializes this instance in the old serial form
  521. //
  522. ObjectOutputStream.PutField fields = out.putFields();
  523. fields.put("myName", name);
  524. fields.put("myIsReadableFlg", isReadable);
  525. fields.put("myIsWritableFlg", isWritable);
  526. fields.put("myDescription", description);
  527. fields.put("myMinDegree", minDegree);
  528. fields.put("myMaxDegree", maxDegree);
  529. fields.put("myRefMBeanClassName", referencedMBeanClassName);
  530. out.writeFields();
  531. }
  532. else
  533. {
  534. // Serializes this instance in the new serial form
  535. //
  536. out.defaultWriteObject();
  537. }
  538. }
  539. }