1. /*
  2. * @(#)file ModelMBeanInfoSupport.java
  3. * @(#)author IBM Corp.
  4. * @(#)version 1.38
  5. * @(#)lastedit 04/02/10
  6. *
  7. * Copyright IBM Corp. 1999-2000. All rights reserved.
  8. *
  9. * The program is provided "as is" without any warranty express or implied,
  10. * including the warranty of non-infringement and the implied warranties of
  11. * merchantibility and fitness for a particular purpose. IBM will not be
  12. * liable for any damages suffered by you or any third party claim against
  13. * you regarding the Program.
  14. *
  15. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  16. * This software is the proprietary information of Sun Microsystems, Inc.
  17. * Use is subject to license terms.
  18. *
  19. * Copyright 2004 Sun Microsystems, Inc. Tous droits reserves.
  20. * Ce logiciel est propriete de Sun Microsystems, Inc.
  21. * Distribue par des licences qui en restreignent l'utilisation.
  22. *
  23. */
  24. package javax.management.modelmbean;
  25. import java.io.IOException;
  26. import java.io.ObjectInputStream;
  27. import java.io.ObjectOutputStream;
  28. import java.io.ObjectStreamField;
  29. import java.io.Serializable;
  30. import java.security.AccessController;
  31. import java.security.PrivilegedAction;
  32. import javax.management.Descriptor;
  33. import javax.management.DescriptorAccess;
  34. import javax.management.MBeanAttributeInfo;
  35. import javax.management.MBeanConstructorInfo;
  36. import javax.management.MBeanException;
  37. import javax.management.MBeanInfo;
  38. import javax.management.MBeanNotificationInfo;
  39. import javax.management.MBeanOperationInfo;
  40. import javax.management.RuntimeOperationsException;
  41. import com.sun.jmx.mbeanserver.GetPropertyAction;
  42. import com.sun.jmx.trace.Trace;
  43. /**
  44. * This class represents the meta data for ModelMBeans. Descriptors have been added on the meta data objects.
  45. * <P>
  46. * Java resources wishing to be manageable instantiate the ModelMBean using the MBeanServer's
  47. * createMBean method. The resource then sets the ModelMBeanInfo and Descriptors for the ModelMBean
  48. * instance. The attributes and operations exposed via the ModelMBeanInfo for the ModelMBean are accessible
  49. * from MBeans, connectors/adaptors like other MBeans. Through the Descriptors, values and methods in
  50. * the managed application can be defined and mapped to attributes and operations of the ModelMBean.
  51. * This mapping can be defined during development in a file or dynamically and
  52. * programmatically at runtime.
  53. * <P>
  54. * Every ModelMBean which is instantiated in the MBeanServer becomes manageable:
  55. * its attributes and operations
  56. * become remotely accessible through the connectors/adaptors connected to that MBeanServer.
  57. * A Java object cannot be registered in the MBeanServer unless it is a JMX compliant MBean.
  58. * By instantiating a ModelMBean, resources are guaranteed that the MBean is valid.
  59. *
  60. * MBeanException and RuntimeOperationsException must be thrown on every public method. This allows
  61. * for wrapping exceptions from distributed communications (RMI, EJB, etc.)
  62. *
  63. * @since 1.5
  64. */
  65. public class ModelMBeanInfoSupport extends MBeanInfo
  66. implements ModelMBeanInfo, java.io.Serializable
  67. {
  68. // Serialization compatibility stuff:
  69. // Two serial forms are supported in this class. The selected form depends
  70. // on system property "jmx.serial.form":
  71. // - "1.0" for JMX 1.0
  72. // - any other value for JMX 1.1 and higher
  73. //
  74. // Serial version for old serial form
  75. private static final long oldSerialVersionUID = -3944083498453227709L;
  76. //
  77. // Serial version for new serial form
  78. private static final long newSerialVersionUID = -1935722590756516193L;
  79. //
  80. // Serializable fields in old serial form
  81. private static final ObjectStreamField[] oldSerialPersistentFields =
  82. {
  83. new ObjectStreamField("modelMBeanDescriptor", Descriptor.class),
  84. new ObjectStreamField("mmbAttributes", MBeanAttributeInfo[].class),
  85. new ObjectStreamField("mmbConstructors", MBeanConstructorInfo[].class),
  86. new ObjectStreamField("mmbNotifications", MBeanNotificationInfo[].class),
  87. new ObjectStreamField("mmbOperations", MBeanOperationInfo[].class),
  88. new ObjectStreamField("currClass", String.class)
  89. };
  90. //
  91. // Serializable fields in new serial form
  92. private static final ObjectStreamField[] newSerialPersistentFields =
  93. {
  94. new ObjectStreamField("modelMBeanDescriptor", Descriptor.class),
  95. new ObjectStreamField("modelMBeanAttributes", MBeanAttributeInfo[].class),
  96. new ObjectStreamField("modelMBeanConstructors", MBeanConstructorInfo[].class),
  97. new ObjectStreamField("modelMBeanNotifications", MBeanNotificationInfo[].class),
  98. new ObjectStreamField("modelMBeanOperations", MBeanOperationInfo[].class)
  99. };
  100. //
  101. // Actual serial version and serial form
  102. private static final long serialVersionUID;
  103. /**
  104. * @serialField modelMBeanDescriptor Descriptor The descriptor containing MBean wide policy
  105. * @serialField modelMBeanAttributes ModelMBeanAttributeInfo[] The array of {@link ModelMBeanAttributeInfo} objects which
  106. * have descriptors
  107. * @serialField modelMBeanConstructors MBeanConstructorInfo[] The array of {@link ModelMBeanConstructorInfo} objects which
  108. * have descriptors
  109. * @serialField modelMBeanNotifications MBeanNotificationInfo[] The array of {@link ModelMBeanNotificationInfo} objects which
  110. * have descriptors
  111. * @serialField modelMBeanOperations MBeanOperationInfo[] The array of {@link ModelMBeanOperationInfo} objects which
  112. * have descriptors
  113. */
  114. private static final ObjectStreamField[] serialPersistentFields;
  115. private static boolean compat = false;
  116. static {
  117. try {
  118. PrivilegedAction act = new GetPropertyAction("jmx.serial.form");
  119. String form = (String) AccessController.doPrivileged(act);
  120. compat = (form != null && form.equals("1.0"));
  121. } catch (Exception e) {
  122. // OK: No compat with 1.0
  123. }
  124. if (compat) {
  125. serialPersistentFields = oldSerialPersistentFields;
  126. serialVersionUID = oldSerialVersionUID;
  127. } else {
  128. serialPersistentFields = newSerialPersistentFields;
  129. serialVersionUID = newSerialVersionUID;
  130. }
  131. }
  132. //
  133. // END Serialization compatibility stuff
  134. /**
  135. * @serial The descriptor containing MBean wide policy
  136. */
  137. private Descriptor modelMBeanDescriptor = null;
  138. /* The following fields always have the same values as the
  139. fields inherited from MBeanInfo and are retained only for
  140. compatibility. By rewriting the serialization code we could
  141. get rid of them.
  142. These fields can't be final because they are assigned to by
  143. readObject(). */
  144. /**
  145. * @serial The array of {@link ModelMBeanAttributeInfo} objects which
  146. * have descriptors
  147. */
  148. private MBeanAttributeInfo[] modelMBeanAttributes;
  149. /**
  150. * @serial The array of {@link ModelMBeanConstructorInfo} objects which
  151. * have descriptors
  152. */
  153. private MBeanConstructorInfo[] modelMBeanConstructors;
  154. /**
  155. * @serial The array of {@link ModelMBeanNotificationInfo} objects which
  156. * have descriptors
  157. */
  158. private MBeanNotificationInfo[] modelMBeanNotifications;
  159. /**
  160. * @serial The array of {@link ModelMBeanOperationInfo} objects which
  161. * have descriptors
  162. */
  163. private MBeanOperationInfo[] modelMBeanOperations;
  164. private static final String ATTR = "attribute";
  165. private static final String OPER = "operation";
  166. private static final String NOTF = "notification";
  167. private static final String CONS = "constructor";
  168. private static final String MMB = "mbean";
  169. private static final String ALL = "all";
  170. private static final String currClass = "ModelMBeanInfoSupport";
  171. /**
  172. * Constructs a ModelMBeanInfoSupport which is a duplicate of the one
  173. * passed in.
  174. *
  175. * @param mbi the ModelMBeanInfo instance from which the ModelMBeanInfo
  176. * being created is initialized.
  177. */
  178. public ModelMBeanInfoSupport(ModelMBeanInfo mbi)
  179. {
  180. super(mbi.getClassName(),
  181. mbi.getDescription(),
  182. mbi.getAttributes(),
  183. mbi.getConstructors(),
  184. mbi.getOperations(),
  185. mbi.getNotifications());
  186. modelMBeanAttributes = mbi.getAttributes();
  187. modelMBeanConstructors = mbi.getConstructors();
  188. modelMBeanOperations = mbi.getOperations();
  189. modelMBeanNotifications = mbi.getNotifications();
  190. try
  191. {
  192. Descriptor mbeandescriptor = mbi.getMBeanDescriptor();
  193. if ((mbeandescriptor != null) && isValidDescriptor(mbeandescriptor))
  194. {
  195. if (tracing()) trace("ModelMBeanInfo(ModelMBeanInfo)","ModelMBeanDescriptor is valid, cloning Descriptor *" + mbeandescriptor.toString() + "*");
  196. modelMBeanDescriptor = (Descriptor) mbeandescriptor.clone();
  197. addDefaultFields();
  198. } else
  199. {
  200. if (tracing()) trace("ModelMBeanInfo(ModelMBeanInfo)",
  201. "ModelMBeanDescriptor in ModelMBeanInfo is null or invalid, setting to default value");
  202. modelMBeanDescriptor = createDefaultDescriptor();
  203. }
  204. } catch (MBeanException mbe)
  205. {
  206. modelMBeanDescriptor = createDefaultDescriptor();
  207. if (tracing()) trace("ModelMBeanInfo(ModelMBeanInfo)","Could not get modelMBeanDescriptor, setting to default value");
  208. }
  209. if (tracing())
  210. {
  211. trace("ModelMBeanInfo(ModelMBeanInfo)","Executed");
  212. }
  213. }
  214. /**
  215. * Creates a ModelMBeanInfoSupport with the provided information,
  216. * but the descriptor is a default.
  217. * The default descriptor is: name=mbeanName, descriptorType=mbean,
  218. * displayName=ClassName, persistPolicy=never, log=F, visibility=1
  219. *
  220. * @param className classname of the MBean
  221. * @param description human readable description of the
  222. * ModelMBean
  223. * @param attributes array of ModelMBeanAttributeInfo objects
  224. * which have descriptors
  225. * @param constructors array of ModelMBeanConstructorInfo
  226. * objects which have descriptors
  227. * @param operations array of ModelMBeanOperationInfo objects
  228. * which have descriptors
  229. * @param notifications array of ModelMBeanNotificationInfo
  230. * objects which have descriptors
  231. */
  232. public ModelMBeanInfoSupport(String className,
  233. String description,
  234. ModelMBeanAttributeInfo[] attributes,
  235. ModelMBeanConstructorInfo[] constructors,
  236. ModelMBeanOperationInfo[] operations,
  237. ModelMBeanNotificationInfo[] notifications) {
  238. this(className, description, attributes, constructors,
  239. operations, notifications, null);
  240. }
  241. /**
  242. * Creates a ModelMBeanInfoSupport with the provided information
  243. * and the descriptor given in parameter.
  244. *
  245. * @param className classname of the MBean
  246. * @param description human readable description of the
  247. * ModelMBean
  248. * @param attributes array of ModelMBeanAttributeInfo objects
  249. * which have descriptors
  250. * @param constructors array of ModelMBeanConstructorInfo
  251. * objects which have descriptor
  252. * @param operations array of ModelMBeanOperationInfo objects
  253. * which have descriptor
  254. * @param notifications array of ModelMBeanNotificationInfo
  255. * objects which have descriptor
  256. * @param mbeandescriptor descriptor to be used as the
  257. * MBeanDescriptor containing MBean wide policy. If the
  258. * descriptor is null, a default descriptor will be constructed.
  259. * The default descriptor is:
  260. * name=className, descriptorType=mbean, displayName=className,
  261. * persistPolicy=never, log=F, visibility=1. If the
  262. * descriptor does not contain all these fields, they will be
  263. * added with these default values.
  264. *
  265. * @exception RuntimeOperationsException Wraps an
  266. * IllegalArgumentException for invalid descriptor passed in
  267. * parameter. (see {@link #getMBeanDescriptor
  268. * getMBeanDescriptor} for the definition of a valid MBean
  269. * descriptor.)
  270. */
  271. public ModelMBeanInfoSupport(String className,
  272. String description,
  273. ModelMBeanAttributeInfo[] attributes,
  274. ModelMBeanConstructorInfo[] constructors,
  275. ModelMBeanOperationInfo[] operations,
  276. ModelMBeanNotificationInfo[] notifications,
  277. Descriptor mbeandescriptor) {
  278. super(className,
  279. description,
  280. (attributes != null) ? attributes : NO_ATTRIBUTES,
  281. (constructors != null) ? constructors : NO_CONSTRUCTORS,
  282. (operations != null) ? operations : NO_OPERATIONS,
  283. (notifications != null) ? notifications : NO_NOTIFICATIONS);
  284. /* The values saved here are possibly null, but we
  285. check this everywhere they are referenced. If at
  286. some stage we replace null with an empty array
  287. here, as we do in the superclass constructor
  288. parameters, then we must also do this in
  289. readObject(). */
  290. modelMBeanAttributes = attributes;
  291. modelMBeanConstructors = constructors;
  292. modelMBeanOperations = operations;
  293. modelMBeanNotifications = notifications;
  294. if (mbeandescriptor ==null) {
  295. if (tracing())
  296. trace("ModelMBeanInfo(String,String,ModelMBeanAttributeInfo[],ModelMBeanConstructorInfo[],ModelMBeanOperationInfo[],ModelMBeanNotificationInfo[],Descriptor)",
  297. "MBeanDescriptor is null, setting default descriptor");
  298. modelMBeanDescriptor = createDefaultDescriptor();
  299. } else {
  300. if (isValidDescriptor(mbeandescriptor)) {
  301. modelMBeanDescriptor = (Descriptor) mbeandescriptor.clone();
  302. addDefaultFields();
  303. } else {
  304. throw new RuntimeOperationsException(new IllegalArgumentException("Invalid descriptor passed in parameter"));
  305. }
  306. }
  307. if (tracing())
  308. {
  309. trace("ModelMBeanInfo(String,String,ModelMBeanAttributeInfo[],ModelMBeanConstructorInfo[],ModelMBeanOperationInfo[],ModelMBeanNotificationInfo[],Descriptor)",
  310. "Executed");
  311. }
  312. }
  313. private static final ModelMBeanAttributeInfo[] NO_ATTRIBUTES =
  314. new ModelMBeanAttributeInfo[0];
  315. private static final ModelMBeanConstructorInfo[] NO_CONSTRUCTORS =
  316. new ModelMBeanConstructorInfo[0];
  317. private static final ModelMBeanNotificationInfo[] NO_NOTIFICATIONS =
  318. new ModelMBeanNotificationInfo[0];
  319. private static final ModelMBeanOperationInfo[] NO_OPERATIONS =
  320. new ModelMBeanOperationInfo[0];
  321. // Java doc inherited from MOdelMBeanInfo interface
  322. public Object clone() {
  323. return(new ModelMBeanInfoSupport(this));
  324. }
  325. public Descriptor[] getDescriptors(String inDescriptorType)
  326. throws MBeanException, RuntimeOperationsException {
  327. if (tracing())
  328. {
  329. trace("ModelMBeanInfoSupport.getDescriptors()","Entry");
  330. }
  331. if ((inDescriptorType == null) || (inDescriptorType == ""))
  332. {
  333. inDescriptorType = "all";
  334. }
  335. // if no descriptors of that type, will return empty array
  336. Descriptor[] retList;
  337. if (inDescriptorType.equalsIgnoreCase(MMB))
  338. {
  339. retList = new Descriptor[] {modelMBeanDescriptor};
  340. } else if (inDescriptorType.equalsIgnoreCase(ATTR))
  341. {
  342. MBeanAttributeInfo[] attrList = modelMBeanAttributes;
  343. int numAttrs = 0;
  344. if (attrList != null) numAttrs = attrList.length;
  345. retList = new Descriptor[numAttrs];
  346. for (int i=0; i < numAttrs; i++)
  347. {
  348. retList[i] = (((ModelMBeanAttributeInfo) attrList[i]).getDescriptor());
  349. }
  350. } else if (inDescriptorType.equalsIgnoreCase(OPER))
  351. {
  352. MBeanOperationInfo[] operList = modelMBeanOperations;
  353. int numOpers = 0;
  354. if (operList != null) numOpers = operList.length;
  355. retList = new Descriptor[numOpers];
  356. for (int i=0; i < numOpers; i++)
  357. {
  358. retList[i] = (((ModelMBeanOperationInfo) operList[i]).getDescriptor());
  359. }
  360. } else if (inDescriptorType.equalsIgnoreCase(CONS))
  361. {
  362. MBeanConstructorInfo[] consList = modelMBeanConstructors;
  363. int numCons = 0;
  364. if (consList != null) numCons = consList.length;
  365. retList = new Descriptor[numCons];
  366. for (int i=0; i < numCons; i++)
  367. {
  368. retList[i] = (((ModelMBeanConstructorInfo) consList[i]).getDescriptor());
  369. }
  370. } else if (inDescriptorType.equalsIgnoreCase(NOTF))
  371. {
  372. MBeanNotificationInfo[] notifList = modelMBeanNotifications;
  373. int numNotifs = 0;
  374. if (notifList != null) numNotifs = notifList.length;
  375. retList = new Descriptor[numNotifs];
  376. for (int i=0; i < numNotifs; i++)
  377. {
  378. retList[i] = (((ModelMBeanNotificationInfo) notifList[i]).getDescriptor());
  379. }
  380. } else if (inDescriptorType.equalsIgnoreCase(ALL))
  381. {
  382. MBeanAttributeInfo[] attrList = modelMBeanAttributes;
  383. int numAttrs = 0;
  384. if (attrList != null) numAttrs = attrList.length;
  385. MBeanOperationInfo[] operList = modelMBeanOperations;
  386. int numOpers = 0;
  387. if (operList != null) numOpers = operList.length;
  388. MBeanConstructorInfo[] consList = modelMBeanConstructors;
  389. int numCons = 0;
  390. if (consList != null) numCons = consList.length;
  391. MBeanNotificationInfo[] notifList = modelMBeanNotifications;
  392. int numNotifs = 0;
  393. if (notifList != null) numNotifs = notifList.length;
  394. retList = new Descriptor[numAttrs + numCons + numOpers + numNotifs];
  395. int j=0;
  396. for (int i=0; i < numAttrs; i++)
  397. {
  398. retList[j] = (((ModelMBeanAttributeInfo) attrList[i]).getDescriptor());
  399. j++;
  400. }
  401. for (int i=0; i < numCons; i++)
  402. {
  403. retList[j] = (((ModelMBeanConstructorInfo)consList[i]).getDescriptor());
  404. j++;
  405. }
  406. for (int i=0; i < numOpers; i++)
  407. {
  408. retList[j] = (((ModelMBeanOperationInfo)operList[i]).getDescriptor());
  409. j++;
  410. }
  411. for (int i=0; i < numNotifs; i++)
  412. {
  413. retList[j] = (((ModelMBeanNotificationInfo)notifList[i]).getDescriptor());
  414. j++;
  415. }
  416. } else
  417. {
  418. throw new RuntimeOperationsException(new IllegalArgumentException("Descriptor Type is invalid"),
  419. ("Exception occurred trying to find the descriptors of the MBean"));
  420. }
  421. if (tracing())
  422. {
  423. trace("ModelMBeanInfoSupport.getDescriptors()","Exit");
  424. }
  425. return retList;
  426. }
  427. public void setDescriptors(Descriptor[] inDescriptors)
  428. throws MBeanException, RuntimeOperationsException {
  429. if (tracing())
  430. {
  431. trace("ModelMBeanInfoSupport.setDescriptors(Descriptor[])","Entry");
  432. }
  433. if (inDescriptors==null)
  434. { // throw RuntimeOperationsException - invalid descriptor
  435. throw new RuntimeOperationsException(new IllegalArgumentException("Descriptor list is invalid"),
  436. ("Exception occurred trying to set the descriptors of the MBeanInfo"));
  437. }
  438. if (inDescriptors.length == 0)
  439. { // empty list, no-op
  440. return;
  441. }
  442. for (int j=0; j < inDescriptors.length; j++)
  443. {
  444. setDescriptor(inDescriptors[j],null);
  445. }
  446. if (tracing())
  447. {
  448. trace("ModelMBeanInfoSupport.setDescriptors(Descriptor[])","Exit");
  449. }
  450. }
  451. /**
  452. * Returns a Descriptor requested by name.
  453. *
  454. * @param inDescriptorName The name of the descriptor.
  455. *
  456. * @return Descriptor containing a descriptor for the ModelMBean with the same name.
  457. * If no descriptor is found, null is returned.
  458. *
  459. * @exception MBeanException Wraps a distributed communication Exception.
  460. * @exception RuntimeOperationsException Wraps an IllegalArgumentException for null name.
  461. *
  462. * @see #setDescriptor
  463. */
  464. public Descriptor getDescriptor(String inDescriptorName)
  465. throws MBeanException, RuntimeOperationsException {
  466. if (tracing())
  467. {
  468. trace("ModelMBeanInfoSupport.getDescriptor(String)","Entry");
  469. }
  470. return(getDescriptor(inDescriptorName, null));
  471. }
  472. public Descriptor getDescriptor(String inDescriptorName,
  473. String inDescriptorType)
  474. throws MBeanException, RuntimeOperationsException {
  475. if (inDescriptorName==null) {
  476. // throw RuntimeOperationsException - invalid descriptor
  477. throw new RuntimeOperationsException(new IllegalArgumentException("Descriptor is invalid"),
  478. ("Exception occurred trying to set the descriptors of the MBeanInfo"));
  479. }
  480. if (MMB.equalsIgnoreCase(inDescriptorType)) {
  481. return (Descriptor) modelMBeanDescriptor.clone();
  482. }
  483. /* The logic here is a bit convoluted, because we are
  484. dealing with two possible cases, depending on whether
  485. inDescriptorType is null. If it's not null, then only
  486. one of the following ifs will run, and it will either
  487. return a descriptor or null. If inDescriptorType is
  488. null, then all of the following ifs will run until one
  489. of them finds a descriptor. */
  490. if (ATTR.equalsIgnoreCase(inDescriptorType) || inDescriptorType == null) {
  491. ModelMBeanAttributeInfo attr = getAttribute(inDescriptorName);
  492. if (attr != null)
  493. return attr.getDescriptor();
  494. if (inDescriptorType != null)
  495. return null;
  496. }
  497. if (OPER.equalsIgnoreCase(inDescriptorType) || inDescriptorType == null) {
  498. ModelMBeanOperationInfo oper = getOperation(inDescriptorName);
  499. if (oper != null)
  500. return oper.getDescriptor();
  501. if (inDescriptorType != null)
  502. return null;
  503. }
  504. if (CONS.equalsIgnoreCase(inDescriptorType) || inDescriptorType == null) {
  505. ModelMBeanConstructorInfo oper =
  506. getConstructor(inDescriptorName);
  507. if (oper != null)
  508. return oper.getDescriptor();
  509. if (inDescriptorType != null)
  510. return null;
  511. }
  512. if (NOTF.equalsIgnoreCase(inDescriptorType) || inDescriptorType == null) {
  513. ModelMBeanNotificationInfo notif =
  514. getNotification(inDescriptorName);
  515. if (notif != null)
  516. return notif.getDescriptor();
  517. if (inDescriptorType != null)
  518. return null;
  519. }
  520. if (inDescriptorType == null)
  521. return null;
  522. throw new RuntimeOperationsException(new IllegalArgumentException("Descriptor Type is invalid"),
  523. "Exception occurred trying to find the descriptors of the MBean");
  524. }
  525. public void setDescriptor(Descriptor inDescriptor,
  526. String inDescriptorType)
  527. throws MBeanException, RuntimeOperationsException {
  528. final String excMsg =
  529. "Exception occurred trying to set the descriptors of the MBean";
  530. if (tracing()) {
  531. trace("ModelMBeanInfoSupport.setDescriptor(Descriptor,String)",
  532. "Entry");
  533. }
  534. if (inDescriptor==null) {
  535. RuntimeException iae =
  536. new IllegalArgumentException("Null Descriptor");
  537. throw new RuntimeOperationsException(iae, excMsg);
  538. }
  539. if ((inDescriptorType == null) || (inDescriptorType == "")) {
  540. inDescriptorType =
  541. (String) inDescriptor.getFieldValue("descriptorType");
  542. if (inDescriptorType == null) {
  543. RuntimeException iae =
  544. new IllegalArgumentException("Descriptor type is invalid");
  545. throw new RuntimeOperationsException(iae, excMsg);
  546. }
  547. }
  548. String inDescriptorName =
  549. (String) inDescriptor.getFieldValue("name");
  550. if (inDescriptorName == null) {
  551. RuntimeException iae =
  552. new IllegalArgumentException("Descriptor name is invalid");
  553. throw new RuntimeOperationsException(iae, excMsg);
  554. }
  555. boolean found = false;
  556. if (inDescriptorType.equalsIgnoreCase(MMB)) {
  557. setMBeanDescriptor(inDescriptor);
  558. found = true;
  559. } else if (inDescriptorType.equalsIgnoreCase(ATTR)) {
  560. MBeanAttributeInfo[] attrList = modelMBeanAttributes;
  561. int numAttrs = 0;
  562. if (attrList != null) numAttrs = attrList.length;
  563. for (int i=0; i < numAttrs; i++) {
  564. if (inDescriptorName.equals(attrList[i].getName())) {
  565. found = true;
  566. ModelMBeanAttributeInfo mmbai =
  567. (ModelMBeanAttributeInfo) attrList[i];
  568. mmbai.setDescriptor(inDescriptor);
  569. if (tracing()) {
  570. trace("ModelMBeanInfoSupport.setDescriptor",
  571. "setting descriptor to " + inDescriptor);
  572. trace("ModelMBeanInfoSupport.setDescriptor",
  573. "local: AttributeInfo descriptor is " +
  574. mmbai.getDescriptor());
  575. trace("ModelMBeanInfoSupport.setDescriptor",
  576. "modelMBeanInfo: AttributeInfo descriptor is " +
  577. this.getDescriptor(inDescriptorName,
  578. "attribute"));
  579. }
  580. }
  581. }
  582. } else if (inDescriptorType.equalsIgnoreCase(OPER)) {
  583. MBeanOperationInfo[] operList = modelMBeanOperations;
  584. int numOpers = 0;
  585. if (operList != null) numOpers = operList.length;
  586. for (int i=0; i < numOpers; i++) {
  587. if (inDescriptorName.equals(operList[i].getName())) {
  588. found = true;
  589. ModelMBeanOperationInfo mmboi =
  590. (ModelMBeanOperationInfo) operList[i];
  591. mmboi.setDescriptor(inDescriptor);
  592. }
  593. }
  594. } else if (inDescriptorType.equalsIgnoreCase(CONS)) {
  595. MBeanConstructorInfo[] consList = modelMBeanConstructors;
  596. int numCons = 0;
  597. if (consList != null) numCons = consList.length;
  598. for (int i=0; i < numCons; i++) {
  599. if (inDescriptorName.equals(consList[i].getName())) {
  600. found = true;
  601. ModelMBeanConstructorInfo mmbci =
  602. (ModelMBeanConstructorInfo) consList[i];
  603. mmbci.setDescriptor(inDescriptor);
  604. }
  605. }
  606. } else if (inDescriptorType.equalsIgnoreCase(NOTF)) {
  607. MBeanNotificationInfo[] notifList = modelMBeanNotifications;
  608. int numNotifs = 0;
  609. if (notifList != null) numNotifs = notifList.length;
  610. for (int i=0; i < numNotifs; i++) {
  611. if (inDescriptorName.equals(notifList[i].getName())) {
  612. found = true;
  613. ModelMBeanNotificationInfo mmbni =
  614. (ModelMBeanNotificationInfo) notifList[i];
  615. mmbni.setDescriptor(inDescriptor);
  616. }
  617. }
  618. } else {
  619. RuntimeException iae =
  620. new IllegalArgumentException("Invalid descriptor type: " +
  621. inDescriptorType);
  622. throw new RuntimeOperationsException(iae, excMsg);
  623. }
  624. if (!found) {
  625. RuntimeException iae =
  626. new IllegalArgumentException("Descriptor name is invalid: " +
  627. "type=" + inDescriptorType +
  628. "; name=" + inDescriptorName);
  629. throw new RuntimeOperationsException(iae, excMsg);
  630. }
  631. if (tracing()) {
  632. trace("ModelMBeanInfoSupport.setDescriptor(Descriptor,String)",
  633. "Exit");
  634. }
  635. }
  636. public ModelMBeanAttributeInfo getAttribute(String inName)
  637. throws MBeanException, RuntimeOperationsException {
  638. ModelMBeanAttributeInfo retInfo = null;
  639. if (tracing())
  640. {
  641. trace("ModelMBeanInfoSupport.getAttributeInfo(String)","Entry");
  642. }
  643. if (inName == null)
  644. {
  645. throw new RuntimeOperationsException(new IllegalArgumentException("Attribute Name is null"),
  646. ("Exception occurred trying to get the ModelMBeanAttributeInfo of the MBean"));
  647. }
  648. MBeanAttributeInfo[] attrList = modelMBeanAttributes;
  649. int numAttrs = 0;
  650. if (attrList != null) numAttrs = attrList.length;
  651. for (int i=0; (i < numAttrs) && (retInfo == null); i++)
  652. {
  653. if (tracing())
  654. {
  655. trace("ModelMBeanInfoSupport.getAttribute","this.getAttributes() MBeanAttributeInfo Array " + i + ":" + ((ModelMBeanAttributeInfo)attrList[i]).getDescriptor().toString());
  656. trace("ModelMBeanInfoSupport.getAttribute","this.modelMBeanAttributes MBeanAttributeInfo Array " + i + ":" + ((ModelMBeanAttributeInfo)modelMBeanAttributes[i]).getDescriptor().toString());
  657. }
  658. if (inName.equals(attrList[i].getName()))
  659. {
  660. retInfo = ((ModelMBeanAttributeInfo)attrList[i].clone());
  661. }
  662. }
  663. if (tracing())
  664. {
  665. trace("ModelMBeanInfoSupport.getAttribute()","Exit");
  666. }
  667. return retInfo;
  668. }
  669. public ModelMBeanOperationInfo getOperation(String inName)
  670. throws MBeanException, RuntimeOperationsException {
  671. ModelMBeanOperationInfo retInfo = null;
  672. if (tracing())
  673. {
  674. trace("ModelMBeanInfoSupport.getOperation(String)","Entry");
  675. }
  676. if (inName == null)
  677. {
  678. throw new RuntimeOperationsException(new IllegalArgumentException("inName is null"),
  679. ("Exception occurred trying to get the ModelMBeanOperationInfo of the MBean"));
  680. }
  681. MBeanOperationInfo[] operList = modelMBeanOperations; //this.getOperations();
  682. int numOpers = 0;
  683. if (operList != null) numOpers = operList.length;
  684. for (int i=0; (i < numOpers) && (retInfo == null); i++)
  685. {
  686. if (inName.equals(operList[i].getName()))
  687. {
  688. retInfo = ((ModelMBeanOperationInfo) operList[i].clone());
  689. }
  690. }
  691. if (tracing())
  692. {
  693. trace("ModelMBeanInfoSupport.getOperation(String)","Exit");
  694. }
  695. return retInfo;
  696. }
  697. /**
  698. * Returns the ModelMBeanConstructorInfo requested by name.
  699. * If no ModelMBeanConstructorInfo exists for this name null is returned.
  700. *
  701. * @param inName the name of the constructor.
  702. *
  703. * @return the constructor info for the named constructor, or null
  704. * if there is none.
  705. *
  706. * @exception MBeanException Wraps a distributed communication Exception.
  707. * @exception RuntimeOperationsException Wraps an IllegalArgumentException for a null constructor name.
  708. */
  709. public ModelMBeanConstructorInfo getConstructor(String inName)
  710. throws MBeanException, RuntimeOperationsException {
  711. ModelMBeanConstructorInfo retInfo = null;
  712. if (tracing())
  713. {
  714. trace("ModelMBeanInfoSupport.getConstructor(String)","Entry");
  715. }
  716. if (inName == null)
  717. {
  718. throw new RuntimeOperationsException(new IllegalArgumentException("Constructor name is null"),
  719. ("Exception occurred trying to get the ModelMBeanConstructorInfo of the MBean"));
  720. }
  721. MBeanConstructorInfo[] consList = modelMBeanConstructors; //this.getConstructors();
  722. int numCons = 0;
  723. if (consList != null) numCons = consList.length;
  724. for (int i=0; (i < numCons) && (retInfo == null); i++)
  725. {
  726. if (inName.equals(consList[i].getName()))
  727. {
  728. retInfo = ((ModelMBeanConstructorInfo) consList[i].clone());
  729. }
  730. }
  731. if (tracing())
  732. {
  733. trace("ModelMBeanInfoSupport.getConstructor(String)","Exit");
  734. }
  735. return retInfo;
  736. }
  737. public ModelMBeanNotificationInfo getNotification(String inName)
  738. throws MBeanException, RuntimeOperationsException {
  739. ModelMBeanNotificationInfo retInfo = null;
  740. if (tracing())
  741. {
  742. trace("ModelMBeanInfoSupport.getNotification(String)","Entry");
  743. }
  744. if (inName == null)
  745. {
  746. throw new RuntimeOperationsException(new IllegalArgumentException("Notification name is null"),
  747. ("Exception occurred trying to get the ModelMBeanNotificationInfo of the MBean"));
  748. }
  749. MBeanNotificationInfo[] notifList = modelMBeanNotifications; //this.getNotifications();
  750. int numNotifs = 0;
  751. if (notifList != null) numNotifs = notifList.length;
  752. for (int i=0; (i < numNotifs) && (retInfo == null); i++)
  753. {
  754. if (inName.equals(notifList[i].getName()))
  755. {
  756. retInfo = ((ModelMBeanNotificationInfo) notifList[i].clone());
  757. }
  758. }
  759. if (tracing())
  760. {
  761. trace("ModelMBeanInfoSupport.getNotification(String)","Exit");
  762. }
  763. return retInfo;
  764. }
  765. public Descriptor getMBeanDescriptor()
  766. throws MBeanException, RuntimeOperationsException {
  767. if (tracing())
  768. {
  769. trace("ModelMBeanInfoSupport.getMBeanDescriptor()","Executed");
  770. }
  771. if (modelMBeanDescriptor == null)
  772. {
  773. return null;
  774. }
  775. if (tracing()) trace("ModelMBeanInfoSupport.getMBeanDesriptor()", "Returning " + modelMBeanDescriptor.toString());
  776. return((Descriptor) modelMBeanDescriptor.clone());
  777. }
  778. public void setMBeanDescriptor(Descriptor inMBeanDescriptor)
  779. throws MBeanException, RuntimeOperationsException {
  780. if (tracing())
  781. {
  782. trace("ModelMBeanInfoSupport.setMBeanDescriptor(Descriptor)","Executed");
  783. }
  784. if (inMBeanDescriptor == null)
  785. {
  786. if (tracing()) trace("ModelMBeanInfoSupport.setMBeanDescriptor(Descriptor)","MBean Descriptor is not valid");
  787. modelMBeanDescriptor = createDefaultDescriptor();
  788. } else
  789. {
  790. if (isValidDescriptor(inMBeanDescriptor)) {
  791. modelMBeanDescriptor = (Descriptor) inMBeanDescriptor.clone();
  792. addDefaultFields();
  793. } else {
  794. throw new RuntimeOperationsException(new IllegalArgumentException("Invalid descriptor passed in parameter"));
  795. }
  796. }
  797. }
  798. /* The default descriptor is:
  799. * name=mbeanName,descriptorType=mbean, displayName=this.getClassName(),
  800. * persistPolicy=never,log=F,visibility=1
  801. */
  802. private Descriptor createDefaultDescriptor()
  803. {
  804. Descriptor dftDesc = null;
  805. dftDesc = new DescriptorSupport(new String[] {("name=" + this.getClassName()),
  806. "descriptorType=mbean",
  807. ("displayName=" + this.getClassName()),
  808. "persistPolicy=never",
  809. "log=F",
  810. "visibility=1"});
  811. return dftDesc;
  812. }
  813. /*
  814. * Validates the ModelMBeanDescriptor
  815. * If the descriptor does not contain all these fields,
  816. * they will be added with these default values.
  817. * name=mbeanName,descriptorType=mbean, displayName=this.getClassName(),
  818. * persistPolicy=never,log=F,visibility=1
  819. *
  820. * Will return false if the MBeanDescriptor has a null name or descriptorType.
  821. */
  822. private boolean isValidDescriptor(Descriptor inDesc)
  823. {
  824. String badField = null;
  825. // if name != mbi.getClassName
  826. // if (descriptorType != mbean)
  827. // look for displayName, persistPolicy, logging, visibility and add in
  828. if (tracing())
  829. trace("isValidDescriptor",
  830. "Validating descriptor: " + inDesc.toString());
  831. if (inDesc == null)
  832. badField = "nullDescriptor";
  833. else if (!inDesc.isValid())
  834. // checks for empty descriptors, null,
  835. // checks for empty name and descriptorType and
  836. // valid values for fields.
  837. badField="InvalidDescriptor";
  838. else if ((((String)inDesc.getFieldValue("name")) == null))
  839. badField="name";
  840. else if (! ((String)inDesc.getFieldValue("descriptorType"))
  841. .equalsIgnoreCase(MMB))
  842. badField="descriptorType";
  843. else { // no bad fields
  844. if (tracing())
  845. trace("isValidDescriptor", "returning true");
  846. return true;
  847. }
  848. if (tracing())
  849. trace("isValidDescriptor",
  850. "returning false: invalid field is " + badField);
  851. return false;
  852. }
  853. private void addDefaultFields() {
  854. final Descriptor d = modelMBeanDescriptor;
  855. if ((d.getFieldValue("displayName")) == null)
  856. d.setField("displayName",this.getClassName());
  857. if ((d.getFieldValue("persistPolicy")) == null)
  858. d.setField("persistPolicy","never");
  859. if ((d.getFieldValue("log")) == null)
  860. d.setField("log","F");
  861. if ((d.getFieldValue("visibility")) == null)
  862. d.setField("visibility","1");
  863. }
  864. // SUN Trace and debug functions
  865. private boolean tracing()
  866. {
  867. return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MODELMBEAN);
  868. }
  869. private void trace(String inClass, String inMethod, String inText)
  870. {
  871. Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MODELMBEAN, inClass,
  872. inMethod, inText);
  873. }
  874. private void trace(String inMethod, String inText)
  875. {
  876. trace(currClass, inMethod, inText);
  877. }
  878. /**
  879. * Deserializes a {@link ModelMBeanInfoSupport} from an {@link ObjectInputStream}.
  880. */
  881. private void readObject(ObjectInputStream in)
  882. throws IOException, ClassNotFoundException {
  883. if (compat)
  884. {
  885. // Read an object serialized in the old serial form
  886. //
  887. ObjectInputStream.GetField fields = in.readFields();
  888. modelMBeanDescriptor = (Descriptor) fields.get("modelMBeanDescriptor", null);
  889. if (fields.defaulted("modelMBeanDescriptor"))
  890. {
  891. throw new NullPointerException("modelMBeanDescriptor");
  892. }
  893. modelMBeanAttributes = (MBeanAttributeInfo[]) fields.get("mmbAttributes", null);
  894. if (fields.defaulted("mmbAttributes"))
  895. {
  896. throw new NullPointerException("mmbAttributes");
  897. }
  898. modelMBeanConstructors = (MBeanConstructorInfo[]) fields.get("mmbConstructors", null);
  899. if (fields.defaulted("mmbConstructors"))
  900. {
  901. throw new NullPointerException("mmbConstructors");
  902. }
  903. modelMBeanNotifications = (MBeanNotificationInfo[]) fields.get("mmbNotifications", null);
  904. if (fields.defaulted("mmbNotifications"))
  905. {
  906. throw new NullPointerException("mmbNotifications");
  907. }
  908. modelMBeanOperations = (MBeanOperationInfo[]) fields.get("mmbOperations", null);
  909. if (fields.defaulted("mmbOperations"))
  910. {
  911. throw new NullPointerException("mmbOperations");
  912. }
  913. }
  914. else
  915. {
  916. // Read an object serialized in the new serial form
  917. //
  918. in.defaultReadObject();
  919. }
  920. }
  921. /**
  922. * Serializes a {@link ModelMBeanInfoSupport} to an {@link ObjectOutputStream}.
  923. */
  924. private void writeObject(ObjectOutputStream out)
  925. throws IOException {
  926. if (compat)
  927. {
  928. // Serializes this instance in the old serial form
  929. //
  930. ObjectOutputStream.PutField fields = out.putFields();
  931. fields.put("modelMBeanDescriptor", modelMBeanDescriptor);
  932. fields.put("mmbAttributes", modelMBeanAttributes);
  933. fields.put("mmbConstructors", modelMBeanConstructors);
  934. fields.put("mmbNotifications", modelMBeanNotifications);
  935. fields.put("mmbOperations", modelMBeanOperations);
  936. fields.put("currClass", currClass);
  937. out.writeFields();
  938. }
  939. else
  940. {
  941. // Serializes this instance in the new serial form
  942. //
  943. out.defaultWriteObject();
  944. }
  945. }
  946. }