1. /*
  2. * $Header: /home/cvspublic/jakarta-commons/modeler/src/java/org/apache/commons/modeler/ManagedBean.java,v 1.9 2003/07/20 07:35:13 ggregory Exp $
  3. * $Revision: 1.9 $
  4. * $Date: 2003/07/20 07:35:13 $
  5. *
  6. * ====================================================================
  7. *
  8. * The Apache Software License, Version 1.1
  9. *
  10. * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
  11. * reserved.
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions
  15. * are met:
  16. *
  17. * 1. Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. *
  20. * 2. Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in
  22. * the documentation and/or other materials provided with the
  23. * distribution.
  24. *
  25. * 3. The end-user documentation included with the redistribution, if
  26. * any, must include the following acknowlegement:
  27. * "This product includes software developed by the
  28. * Apache Software Foundation (http://www.apache.org/)."
  29. * Alternately, this acknowlegement may appear in the software itself,
  30. * if and wherever such third-party acknowlegements normally appear.
  31. *
  32. * 4. The names "The Jakarta Project", "Commons", and "Apache Software
  33. * Foundation" must not be used to endorse or promote products derived
  34. * from this software without prior written permission. For written
  35. * permission, please contact apache@apache.org.
  36. *
  37. * 5. Products derived from this software may not be called "Apache"
  38. * nor may "Apache" appear in their names without prior written
  39. * permission of the Apache Group.
  40. *
  41. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  42. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  43. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  45. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  46. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  47. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  48. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  49. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  50. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  51. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  52. * SUCH DAMAGE.
  53. * ====================================================================
  54. *
  55. * This software consists of voluntary contributions made by many
  56. * individuals on behalf of the Apache Software Foundation. For more
  57. * information on the Apache Software Foundation, please see
  58. * <http://www.apache.org/>.
  59. *
  60. * [Additional notices, if required by prior licensing conditions]
  61. *
  62. */
  63. package org.apache.commons.modeler;
  64. import java.util.ArrayList;
  65. import java.util.Iterator;
  66. import java.util.List;
  67. import javax.management.Descriptor;
  68. import javax.management.InstanceNotFoundException;
  69. import javax.management.MBeanException;
  70. import javax.management.RuntimeOperationsException;
  71. import javax.management.modelmbean.InvalidTargetObjectTypeException;
  72. import javax.management.modelmbean.ModelMBean;
  73. import javax.management.modelmbean.ModelMBeanAttributeInfo;
  74. import javax.management.modelmbean.ModelMBeanConstructorInfo;
  75. import javax.management.modelmbean.ModelMBeanInfo;
  76. import javax.management.modelmbean.ModelMBeanInfoSupport;
  77. import javax.management.modelmbean.ModelMBeanNotificationInfo;
  78. import javax.management.modelmbean.ModelMBeanOperationInfo;
  79. /**
  80. * <p>Internal configuration information for a managed bean (MBean)
  81. * descriptor.</p>
  82. *
  83. * @author Craig R. McClanahan
  84. * @version $Revision: 1.9 $ $Date: 2003/07/20 07:35:13 $
  85. */
  86. public class ManagedBean implements java.io.Serializable
  87. {
  88. // ----------------------------------------------------- Instance Variables
  89. /**
  90. * The <code>ModelMBeanInfo</code> object that corresponds
  91. * to this <code>ManagedBean</code> instance.
  92. */
  93. transient ModelMBeanInfo info = null;
  94. protected AttributeInfo attributes[] = new AttributeInfo[0];
  95. protected String className =
  96. "org.apache.commons.modeler.BaseModelMBean";
  97. protected ConstructorInfo constructors[] = new ConstructorInfo[0];
  98. protected String description = null;
  99. protected String domain = null;
  100. protected String group = null;
  101. protected String name = null;
  102. protected List fields = new ArrayList();
  103. protected NotificationInfo notifications[] = new NotificationInfo[0];
  104. protected OperationInfo operations[] = new OperationInfo[0];
  105. protected String type = null;
  106. /** Constructor. Will add default attributes.
  107. *
  108. */
  109. public ManagedBean() {
  110. AttributeInfo ai=new AttributeInfo();
  111. ai.setName("modelerType");
  112. ai.setDescription("Type of the modeled resource. Can be set only once");
  113. ai.setType("java.lang.String");
  114. addAttribute(ai);
  115. }
  116. // ------------------------------------------------------------- Properties
  117. /**
  118. * The collection of attributes for this MBean.
  119. */
  120. public AttributeInfo[] getAttributes() {
  121. return (this.attributes);
  122. }
  123. /**
  124. * The fully qualified name of the Java class of the MBean
  125. * described by this descriptor. If not specified, the standard JMX
  126. * class (<code>javax.management.modelmbean.RequiredModeLMBean</code>)
  127. * will be utilized.
  128. */
  129. public String getClassName() {
  130. return (this.className);
  131. }
  132. public void setClassName(String className) {
  133. this.className = className;
  134. this.info = null;
  135. }
  136. /**
  137. * The collection of constructors for this MBean.
  138. */
  139. public ConstructorInfo[] getConstructors() {
  140. return (this.constructors);
  141. }
  142. /**
  143. * The human-readable description of this MBean.
  144. */
  145. public String getDescription() {
  146. return (this.description);
  147. }
  148. public void setDescription(String description) {
  149. this.description = description;
  150. this.info = null;
  151. }
  152. /**
  153. * The (optional) <code>ObjectName</code> domain in which this MBean
  154. * should be registered in the MBeanServer.
  155. */
  156. public String getDomain() {
  157. return (this.domain);
  158. }
  159. public void setDomain(String domain) {
  160. this.domain = domain;
  161. }
  162. /**
  163. * <p>Return a <code>List</code> of the {@link FieldInfo} objects for
  164. * the name/value pairs that should be
  165. * added to the Descriptor created from this metadata.</p>
  166. */
  167. public List getFields() {
  168. return (this.fields);
  169. }
  170. /**
  171. * The (optional) group to which this MBean belongs.
  172. */
  173. public String getGroup() {
  174. return (this.group);
  175. }
  176. public void setGroup(String group) {
  177. this.group = group;
  178. }
  179. /**
  180. * The name of this managed bean, which must be unique among all
  181. * MBeans managed by a particular MBeans server.
  182. */
  183. public String getName() {
  184. return (this.name);
  185. }
  186. public void setName(String name) {
  187. this.name = name;
  188. this.info = null;
  189. }
  190. /**
  191. * The collection of notifications for this MBean.
  192. */
  193. public NotificationInfo[] getNotifications() {
  194. return (this.notifications);
  195. }
  196. /**
  197. * The collection of operations for this MBean.
  198. */
  199. public OperationInfo[] getOperations() {
  200. return (this.operations);
  201. }
  202. /**
  203. * The fully qualified name of the Java class of the resource
  204. * implementation class described by the managed bean described
  205. * by this descriptor.
  206. */
  207. public String getType() {
  208. return (this.type);
  209. }
  210. public void setType(String type) {
  211. this.type = type;
  212. this.info = null;
  213. }
  214. // --------------------------------------------------------- Public Methods
  215. /**
  216. * Add a new attribute to the set of attributes for this MBean.
  217. *
  218. * @param attribute The new attribute descriptor
  219. */
  220. public void addAttribute(AttributeInfo attribute) {
  221. synchronized (attributes) {
  222. AttributeInfo results[] =
  223. new AttributeInfo[attributes.length + 1];
  224. System.arraycopy(attributes, 0, results, 0, attributes.length);
  225. results[attributes.length] = attribute;
  226. attributes = results;
  227. this.info = null;
  228. }
  229. }
  230. /**
  231. * Add a new constructor to the set of constructors for this MBean.
  232. *
  233. * @param constructor The new constructor descriptor
  234. */
  235. public void addConstructor(ConstructorInfo constructor) {
  236. synchronized (constructors) {
  237. ConstructorInfo results[] =
  238. new ConstructorInfo[constructors.length + 1];
  239. System.arraycopy(constructors, 0, results, 0, constructors.length);
  240. results[constructors.length] = constructor;
  241. constructors = results;
  242. this.info = null;
  243. }
  244. }
  245. /**
  246. * <p>Add a new field to the fields associated with the
  247. * Descriptor that will be created from this metadata.</p>
  248. *
  249. * @param field The field to be added
  250. */
  251. public void addField(FieldInfo field) {
  252. fields.add(field);
  253. }
  254. /**
  255. * Add a new notification to the set of notifications for this MBean.
  256. *
  257. * @param notification The new notification descriptor
  258. */
  259. public void addNotification(NotificationInfo notification) {
  260. synchronized (notifications) {
  261. NotificationInfo results[] =
  262. new NotificationInfo[notifications.length + 1];
  263. System.arraycopy(notifications, 0, results, 0,
  264. notifications.length);
  265. results[notifications.length] = notification;
  266. notifications = results;
  267. this.info = null;
  268. }
  269. }
  270. /**
  271. * Add a new operation to the set of operations for this MBean.
  272. *
  273. * @param operation The new operation descriptor
  274. */
  275. public void addOperation(OperationInfo operation) {
  276. synchronized (operations) {
  277. OperationInfo results[] =
  278. new OperationInfo[operations.length + 1];
  279. System.arraycopy(operations, 0, results, 0, operations.length);
  280. results[operations.length] = operation;
  281. operations = results;
  282. this.info = null;
  283. }
  284. }
  285. /**
  286. * Create and return a <code>ModelMBean</code> that has been
  287. * preconfigured with the <code>ModelMBeanInfo</code> information
  288. * for this managed bean, but is not associated with any particular
  289. * managed resource. The returned <code>ModelMBean</code> will
  290. * <strong>NOT</strong> have been registered with our
  291. * <code>MBeanServer</code>.
  292. *
  293. * @exception InstanceNotFoundException if the managed resource
  294. * object cannot be found
  295. * @exception InvalidTargetObjectTypeException if our MBean cannot
  296. * handle object references (should never happen)
  297. * @exception MBeanException if a problem occurs instantiating the
  298. * <code>ModelMBean</code> instance
  299. * @exception RuntimeOperationsException if a JMX runtime error occurs
  300. */
  301. public ModelMBean createMBean()
  302. throws InstanceNotFoundException,
  303. InvalidTargetObjectTypeException,
  304. MBeanException, RuntimeOperationsException {
  305. return (createMBean(null));
  306. }
  307. /**
  308. * Create and return a <code>ModelMBean</code> that has been
  309. * preconfigured with the <code>ModelMBeanInfo</code> information
  310. * for this managed bean, and is associated with the specified
  311. * managed object instance. The returned <code>ModelMBean</code>
  312. * will <strong>NOT</strong> have been registered with our
  313. * <code>MBeanServer</code>.
  314. *
  315. * @param instance Instanced of the managed object, or <code>null</code>
  316. * for no associated instance
  317. *
  318. * @exception InstanceNotFoundException if the managed resource
  319. * object cannot be found
  320. * @exception InvalidTargetObjectTypeException if our MBean cannot
  321. * handle object references (should never happen)
  322. * @exception MBeanException if a problem occurs instantiating the
  323. * <code>ModelMBean</code> instance
  324. * @exception RuntimeOperationsException if a JMX runtime error occurs
  325. */
  326. public ModelMBean createMBean(Object instance)
  327. throws InstanceNotFoundException,
  328. InvalidTargetObjectTypeException,
  329. MBeanException, RuntimeOperationsException {
  330. // Load the ModelMBean implementation class
  331. Class clazz = null;
  332. Exception ex = null;
  333. try {
  334. clazz = Class.forName(getClassName());
  335. } catch (Exception e) {
  336. }
  337. if( clazz==null ) {
  338. try {
  339. ClassLoader cl= Thread.currentThread().getContextClassLoader();
  340. if ( cl != null)
  341. clazz= cl.loadClass(getClassName());
  342. } catch (Exception e) {
  343. ex=e;
  344. }
  345. }
  346. if( clazz==null) {
  347. throw new MBeanException
  348. (ex, "Cannot load ModelMBean class " + getClassName());
  349. }
  350. // Create a new ModelMBean instance
  351. ModelMBean mbean = null;
  352. try {
  353. mbean = (ModelMBean) clazz.newInstance();
  354. mbean.setModelMBeanInfo(createMBeanInfo());
  355. } catch (MBeanException e) {
  356. throw e;
  357. } catch (RuntimeOperationsException e) {
  358. throw e;
  359. } catch (Exception e) {
  360. throw new MBeanException
  361. (e, "Cannot instantiate ModelMBean of class " +
  362. getClassName());
  363. }
  364. // Set the managed resource (if any)
  365. try {
  366. if (instance != null)
  367. mbean.setManagedResource(instance, "objectReference");
  368. } catch (InstanceNotFoundException e) {
  369. throw e;
  370. } catch (InvalidTargetObjectTypeException e) {
  371. throw e;
  372. }
  373. return (mbean);
  374. }
  375. /**
  376. * Create and return a <code>ModelMBeanInfo</code> object that
  377. * describes this entire managed bean.
  378. */
  379. public ModelMBeanInfo createMBeanInfo() {
  380. // Return our cached information (if any)
  381. if (info != null)
  382. return (info);
  383. // Create subordinate information descriptors as required
  384. AttributeInfo attrs[] = getAttributes();
  385. ModelMBeanAttributeInfo attributes[] =
  386. new ModelMBeanAttributeInfo[attrs.length];
  387. for (int i = 0; i < attrs.length; i++)
  388. attributes[i] = attrs[i].createAttributeInfo();
  389. ConstructorInfo consts[] = getConstructors();
  390. ModelMBeanConstructorInfo constructors[] =
  391. new ModelMBeanConstructorInfo[consts.length];
  392. for (int i = 0; i < consts.length; i++)
  393. constructors[i] = consts[i].createConstructorInfo();
  394. NotificationInfo notifs[] = getNotifications();
  395. ModelMBeanNotificationInfo notifications[] =
  396. new ModelMBeanNotificationInfo[notifs.length];
  397. for (int i = 0; i < notifs.length; i++)
  398. notifications[i] = notifs[i].createNotificationInfo();
  399. OperationInfo opers[] = getOperations();
  400. ModelMBeanOperationInfo operations[] =
  401. new ModelMBeanOperationInfo[opers.length];
  402. for (int i = 0; i < opers.length; i++)
  403. operations[i] = opers[i].createOperationInfo();
  404. /*
  405. // Add operations for attribute getters and setters as needed
  406. ArrayList list = new ArrayList();
  407. for (int i = 0; i < operations.length; i++)
  408. list.add(operations[i]);
  409. for (int i = 0; i < attributes.length; i++) {
  410. Descriptor descriptor = attributes[i].getDescriptor();
  411. String getMethod = (String) descriptor.getFieldValue("getMethod");
  412. if (getMethod != null) {
  413. OperationInfo oper =
  414. new OperationInfo(getMethod, true,
  415. attributes[i].getType());
  416. list.add(oper.createOperationInfo());
  417. }
  418. String setMethod = (String) descriptor.getFieldValue("setMethod");
  419. if (setMethod != null) {
  420. OperationInfo oper =
  421. new OperationInfo(setMethod, false,
  422. attributes[i].getType());
  423. list.add(oper.createOperationInfo());
  424. }
  425. }
  426. if (list.size() > operations.length)
  427. operations =
  428. (ModelMBeanOperationInfo[]) list.toArray(operations);
  429. */
  430. // Construct and return a new ModelMBeanInfo object
  431. info = new ModelMBeanInfoSupport
  432. (getClassName(), getDescription(),
  433. attributes, constructors, operations, notifications);
  434. try {
  435. Descriptor descriptor = info.getMBeanDescriptor();
  436. Iterator fields = getFields().iterator();
  437. while (fields.hasNext()) {
  438. FieldInfo field = (FieldInfo) fields.next();
  439. descriptor.setField(field.getName(), field.getValue());
  440. }
  441. info.setMBeanDescriptor(descriptor);
  442. } catch (MBeanException e) {
  443. ;
  444. }
  445. return (info);
  446. }
  447. /**
  448. * Return a string representation of this managed bean.
  449. */
  450. public String toString() {
  451. StringBuffer sb = new StringBuffer("ManagedBean[");
  452. sb.append("name=");
  453. sb.append(name);
  454. sb.append(", className=");
  455. sb.append(className);
  456. sb.append(", description=");
  457. sb.append(description);
  458. if (group != null) {
  459. sb.append(", group=");
  460. sb.append(group);
  461. }
  462. sb.append(", type=");
  463. sb.append(type);
  464. sb.append("]");
  465. return (sb.toString());
  466. }
  467. }