001: /*****************************************************************************
002: * Copyright (C) NanoContainer Organization. All rights reserved. *
003: * ------------------------------------------------------------------------- *
004: * The software in this package is published under the terms of the BSD *
005: * style license a copy of which has been included with this distribution in *
006: * the LICENSE.txt file. *
007: * *
008: * Original code by Michael Ward *
009: *****************************************************************************/package org.picocontainer.gems.jmx;
010:
011: import javax.management.DynamicMBean;
012: import javax.management.InstanceNotFoundException;
013: import javax.management.MBeanException;
014: import javax.management.MBeanInfo;
015: import javax.management.NotCompliantMBeanException;
016: import javax.management.RuntimeOperationsException;
017: import javax.management.StandardMBean;
018: import javax.management.modelmbean.InvalidTargetObjectTypeException;
019: import javax.management.modelmbean.ModelMBean;
020: import javax.management.modelmbean.ModelMBeanInfo;
021: import javax.management.modelmbean.RequiredModelMBean;
022:
023: /**
024: * A factory for DynamicMBeans, that creates MBean instances using the classes {@link StandardMBean} and
025: * {@link ModelMBean} provided by the JMX specification. The implementation offers special support for StandardMBeans
026: * following the naming convention for their management interface using the class name of the component with an appended
027: * <em>MBean</em>.
028: * @author Michael Ward
029: * @author Jörg Schaible
030: * @version $Revision: 3905 $
031: */
032: public class StandardMBeanFactory implements DynamicMBeanFactory {
033:
034: /**
035: * Create a StandardMBean for the component.
036: * @param componentInstance {@inheritDoc}
037: * @param management The management interface. If <code>null</code> the implementation will use the interface
038: * complying with the naming convention for management interfaces.
039: * @param mBeanInfo The {@link MBeanInfo} to use. If <code>null</code> the {@link StandardMBean} will use an
040: * automatically generated one.
041: * @return Returns a {@link StandardMBean}. If the <strong>mBeanInfo</strong> was not null, it is an instance of a
042: * {@link StandardNanoMBean}.
043: * @see org.picocontainer.gems.jmx.DynamicMBeanFactory#create(java.lang.Object, java.lang.Class,
044: * javax.management.MBeanInfo)
045: */
046: public DynamicMBean create(final Object componentInstance,
047: final Class management, final MBeanInfo mBeanInfo) {
048: try {
049: if (mBeanInfo == null) {
050: final Class managementInterface = getManagementInterface(
051: componentInstance.getClass(), management, null);
052: return new StandardMBean(componentInstance,
053: managementInterface);
054: } else if (mBeanInfo instanceof ModelMBeanInfo) {
055: final ModelMBean mBean = new RequiredModelMBean(
056: (ModelMBeanInfo) mBeanInfo);
057: try {
058: mBean.setManagedResource(componentInstance,
059: "ObjectReference");
060: } catch (final InvalidTargetObjectTypeException e) {
061: // N/A: "ObjectReference" is a valid reference type
062: } catch (final InstanceNotFoundException e) {
063: // N/A: the instance was a valid object
064: }
065: return mBean;
066: } else {
067: final Class managementInterface = getManagementInterface(
068: componentInstance.getClass(), management,
069: mBeanInfo);
070: return new StandardNanoMBean(componentInstance,
071: managementInterface, mBeanInfo);
072: }
073: } catch (final ClassNotFoundException e) {
074: throw new JMXRegistrationException(
075: "Cannot load management interface for StandardMBean",
076: e);
077: } catch (final NotCompliantMBeanException e) {
078: throw new JMXRegistrationException(
079: "Cannot create StandardMBean", e);
080: } catch (final RuntimeOperationsException e) {
081: throw new JMXRegistrationException(
082: "Cannot create ModelMBean", e);
083: } catch (final MBeanException e) {
084: throw new JMXRegistrationException(
085: "Cannot create ModelMBean", e);
086: }
087: }
088:
089: private Class getManagementInterface(final Class type,
090: final Class management, final MBeanInfo mBeanInfo)
091: throws ClassNotFoundException {
092: final Class managementInterface;
093: if (management == null) {
094: managementInterface = getDefaultManagementInterface(type,
095: mBeanInfo);
096: } else {
097: managementInterface = management;
098: }
099: return managementInterface;
100: }
101:
102: /**
103: * Determin the management interface for the given type. The class name of the given type is used as class name of
104: * the mBean unless the caller has provided a {@link MBeanInfo}, the class name of the MBean is retrieved a
105: * MBeanInfo that defines this name. Following the naming conventions is the name of the management interface the
106: * same as the class name of the MBean with an appended <em>MBean</em>. The {@link ClassLoader} of the type is
107: * used to load the interface type.
108: * @param type The class of the MBean.
109: * @param mBeanInfo The {@link MBeanInfo} for the MBean. May be <code>null</code>.
110: * @return Returns the default management interface.
111: * @throws ClassNotFoundException If the management interface cannot be found.
112: */
113: public Class getDefaultManagementInterface(final Class type,
114: final MBeanInfo mBeanInfo) throws ClassNotFoundException {
115: final ClassLoader classLoader = type.getClassLoader() != null ? type
116: .getClassLoader()
117: : Thread.currentThread().getContextClassLoader();
118: return classLoader.loadClass((mBeanInfo == null ? type
119: .getName() : mBeanInfo.getClassName())
120: + "MBean");
121: }
122: }
|