- /*
- * @(#)StandardMBean.java 1.21 04/05/03
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package javax.management;
-
- import java.io.PrintWriter;
- import java.io.StringWriter;
- import java.lang.reflect.UndeclaredThrowableException;
-
- import com.sun.jmx.trace.Trace;
- import com.sun.jmx.mbeanserver.MetaData;
- import com.sun.jmx.mbeanserver.StandardMetaDataImpl;
-
- /**
- * <p>An MBean whose management interface is determined by reflection
- * on a Java interface.</p>
- *
- * <p>This class brings more flexibility to the notion of Management
- * Interface in the use of Standard MBeans. Straightforward use of
- * the patterns for Standard MBeans described in the JMX Specification
- * means that there is a fixed relationship between the implementation
- * class of an MBean and its management interface (i.e., if the
- * implementation class is Thing, the management interface must be
- * ThingMBean). This class makes it possible to keep the convenience
- * of specifying the management interface with a Java interface,
- * without requiring that there be any naming relationship between the
- * implementation and interface classes.</p>
- *
- * <p>By making a DynamicMBean out of an MBean, this class makes
- * it possible to select any interface implemented by the MBean as its
- * management interface, provided that it complies with JMX patterns
- * (i.e., attributes defined by getter/setter etc...).</p>
- *
- * <p> This class also provides hooks that make it possible to supply
- * custom descriptions and names for the {@link MBeanInfo} returned by
- * the DynamicMBean interface.</p>
- *
- * <p>Using this class, an MBean can be created with any
- * implementation class name <i>Impl</i> and with a management
- * interface defined (as for current Standard MBeans) by any interface
- * <i>Intf</i>, in one of two general ways:</p>
- *
- * <ul>
- *
- * <li>Using the public constructor
- * {@link #StandardMBean(java.lang.Object, java.lang.Class)
- * StandardMBean(impl,interface)}:
- * <pre>
- * MBeanServer mbs;
- * ...
- * Impl impl = new Impl(...);
- * StandardMBean mbean = new StandardMBean(impl, Intf.class);
- * mbs.registerMBean(mbean, objectName);
- * </pre></li>
- *
- * <li>Subclassing StandardMBean:
- * <pre>
- * public class Impl extends StandardMBean implements Intf {
- * public Impl() {
- * super(Intf.class);
- * }
- * // implement methods of Intf
- * }
- *
- * [...]
- *
- * MBeanServer mbs;
- * ....
- * Impl impl = new Impl();
- * mbs.registerMBean(impl, objectName);
- * </pre></li>
- *
- * </ul>
- *
- * <p>In either case, the class <i>Impl</i> must implement the
- * interface <i>Intf</i>.</p>
- *
- * <p>Standard MBeans based on the naming relationship between
- * implementation and interface classes are of course still
- * available.</p>
- *
- * @since 1.5
- * @since.unbundled JMX 1.2
- */
- public class StandardMBean implements DynamicMBean {
- /** The name of this class to be used for tracing */
- private final static String dbgTag = "StandardMBean";
-
- /**
- * Override StandardMetaDataImpl in order to redefine the caching
- * of MBean Information.
- **/
- private final class StandardMBeanMeta extends StandardMetaDataImpl {
- /** Constructor... **/
- public StandardMBeanMeta() {
- super(false);
- }
-
- /**
- * We need to override this method because some methods
- * from BaseMetaDataImpl rely on MetaData#getMBeanInfo().
- * <p>
- * The default caching implemented in StandardMetaDataImpl
- * will not work if two instances of class <var>c</var> can have
- * different management interfaces, which is made possible
- * by {@link StandardMBean}
- *
- * @return StandardMBean.this.getMBeanInfo();
- **/
- protected MBeanInfo getCachedMBeanInfo(Class beanClass) {
- if (beanClass == null) return null;
-
- // Need the synchronized block as long as implementation
- // and mbeanInterface are not final.
- //
- synchronized (StandardMBean.this) {
- // Consistency checking: beanClass must be equal
- // to StandardMBean.this.getImplementationClass().
- //
- final Class implementationClass =
- StandardMBean.this.getImplementationClass();
- if (implementationClass == null) return null;
- if (!beanClass.equals(implementationClass)) return null;
-
- // Should always come here (null cases excepted)...
- //
- return StandardMBean.this.getMBeanInfo();
- }
- }
-
- /**
- * We need to override this method because some methods
- * from StandardMetaDataImpl rely on it.
- * <p>
- * The default caching implemented in StandardMetaDataImpl
- * will not work if two instances of class <var>c</var> can have
- * different management interfaces, which is made possible
- * by {@link StandardMBean}
- *
- * @return StandardMBean.this.getMBeanInterface();
- **/
- protected Class getCachedMBeanInterface(Class beanClass) {
- // Need the synchronized block as long as implementation
- // and mbeanInterface are not final.
- //
- synchronized (StandardMBean.this) {
- // Consistency checking: beanClass must be equal
- // to StandardMBean.this.getImplementationClass().
- //
- final Class implementationClass =
- StandardMBean.this.getImplementationClass();
- if (implementationClass == null) return null;
- if (!beanClass.equals(implementationClass)) return null;
-
- // Should always come here (null cases excepted)...
- //
- return StandardMBean.this.getMBeanInterface();
- }
- }
-
- /**
- * Need to override this method because default caching implemented
- * in StandardMetaDataImpl will not work if two instances of class
- * <var>c</var> can have different <var>mbeanInterface</var>.
- * <p>
- * The default caching mechanism in StandardMetaDataImpl uses
- * class static {@link java.util.WeakHashMap WeakHashMaps} - and
- * is common to all instance of StandardMetaData - hence to
- * all MBeanServer.
- * <p>
- * As this default mechanism might not always work for
- * StandardMBean objects (may have several instances of class
- * <var>c</var> with different MBean interfaces), we disable
- * this default caching by defining an empty
- * <code>cacheMBeanInfo()</code> method.
- * <p>
- * Caching in our case is no longer performed by the MetaData
- * object, but by the StandardMBean object.
- **/
- protected void cacheMBeanInfo(Class c,Class mbeanInterface,
- MBeanInfo mbeanInfo) {
- }
- }
-
- /**
- * The management interface.
- **/
- private Class mbeanInterface;
-
- /**
- * The implementation.
- **/
- private Object implementation;
-
- /**
- * The MetaData object used for invoking reflection.
- **/
- private final StandardMetaDataImpl meta;
-
- /**
- * The cached MBeanInfo.
- **/
- private MBeanInfo cachedMBeanInfo;
-
- /**
- * Make a DynamicMBean out of <var>implementation</var>, using the
- * specified <var>mbeanInterface</var> class.
- * @param implementation The implementation of this MBean.
- * If <code>null</code>, and null implementation is allowed,
- * then the implementation is assumed to be <var>this</var>.
- * @param mbeanInterface The Management Interface exported by this
- * MBean's implementation. If <code>null</code>, then this
- * object will use standard JMX design pattern to determine
- * the management interface associated with the given
- * implementation.
- * @param nullImplementationAllowed <code>true</code> if a null
- * implementation is allowed. If null implementation is allowed,
- * and a null implementation is passed, then the implementation
- * is assumed to be <var>this</var>.
- * @exception IllegalArgumentException if the given
- * <var>implementation</var> is null, and null is not allowed.
- * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
- * does not follow JMX design patterns for Management Interfaces, or
- * if the given <var>implementation</var> does not implement the
- * specified interface.
- **/
- private StandardMBean(Object implementation, Class mbeanInterface,
- boolean nullImplementationAllowed)
- throws NotCompliantMBeanException {
- if (implementation == null) {
- if (nullImplementationAllowed) implementation = this;
- else throw new IllegalArgumentException("implementation is null");
- }
- this.meta = new StandardMBeanMeta();
- setImplementation(implementation,mbeanInterface);
- }
-
- /**
- * <p>Make a DynamicMBean out of the object
- * <var>implementation</var>, using the specified
- * <var>mbeanInterface</var> class.</p>
- *
- * @param implementation The implementation of this MBean.
- * @param mbeanInterface The Management Interface exported by this
- * MBean's implementation. If <code>null</code>, then this
- * object will use standard JMX design pattern to determine
- * the management interface associated with the given
- * implementation.
- *
- * @exception IllegalArgumentException if the given
- * <var>implementation</var> is null.
- * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
- * does not follow JMX design patterns for Management Interfaces, or
- * if the given <var>implementation</var> does not implement the
- * specified interface.
- **/
- public StandardMBean(Object implementation,Class mbeanInterface)
- throws NotCompliantMBeanException {
- this(implementation,mbeanInterface,false);
- }
-
- /**
- * <p>Make a DynamicMBean out of <var>this</var>, using the specified
- * <var>mbeanInterface</var> class.</p>
- *
- * <p>Call {@link #StandardMBean(java.lang.Object, java.lang.Class)
- * this(this,mbeanInterface)}.
- * This constructor is reserved to subclasses.</p>
- *
- * @param mbeanInterface The Management Interface exported by this
- * MBean.
- *
- * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
- * does not follow JMX design patterns for Management Interfaces, or
- * if <var>this</var> does not implement the specified interface.
- **/
- protected StandardMBean(Class mbeanInterface)
- throws NotCompliantMBeanException {
- this(null,mbeanInterface,true);
- }
-
- /**
- * <p>Replace the implementation object wrapped in this
- * object.</p>
- *
- * @param implementation The new implementation of this MBean.
- * The <code>implementation</code> object must implement the MBean
- * interface that was supplied when this
- * <code>StandardMBean</code> was constructed.
- *
- * @exception IllegalArgumentException if the given
- * <var>implementation</var> is null.
- *
- * @exception NotCompliantMBeanException if the given
- * <var>implementation</var> does not implement the MBean
- * interface that was supplied at construction.
- *
- * @see #getImplementation
- **/
- public synchronized void setImplementation(Object implementation)
- throws NotCompliantMBeanException {
- setImplementation(implementation, getMBeanInterface());
- }
-
- /**
- * Replace the implementation and management interface wrapped in
- * this object.
- * @param implementation The new implementation of this MBean.
- * @param mbeanInterface The Management Interface exported by this
- * MBean's implementation. If <code>null</code>, then this
- * object will use standard JMX design patterns to determine
- * the management interface associated with the given
- * implementation.
- * @exception IllegalArgumentException if the given
- * <var>implementation</var> is null.
- * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
- * does not follow JMX design patterns for Management Interfaces, or
- * if the given <var>implementation</var> does not implement the
- * specified interface.
- **/
- private synchronized void setImplementation(Object implementation,
- Class mbeanInterface)
- throws NotCompliantMBeanException {
- if (implementation == null)
- throw new IllegalArgumentException("implementation is null");
-
- // test compliance
- this.meta.testCompliance(implementation.getClass(),mbeanInterface);
-
- // flush the cache...
- cacheMBeanInfo(null);
- this.implementation = implementation;
- this.mbeanInterface = mbeanInterface;
- if (this.mbeanInterface == null)
- this.mbeanInterface =
- meta.getStandardMBeanInterface(implementation.getClass());
- }
-
- /**
- * Get the implementation of this MBean.
- * @return The implementation of this MBean.
- *
- * @see #setImplementation
- **/
- public synchronized Object getImplementation() {
- return implementation;
- }
-
- /**
- * Get the Management Interface of this MBean.
- * @return The management interface of this MBean.
- **/
- public final synchronized Class getMBeanInterface() {
- return mbeanInterface;
- }
-
- /**
- * Get the class of the implementation of this MBean.
- * @return The class of the implementation of this MBean.
- **/
- public synchronized Class getImplementationClass() {
- if (implementation == null) return null;
- return implementation.getClass();
- }
-
- // ------------------------------------------------------------------
- // From the DynamicMBean interface.
- // ------------------------------------------------------------------
- public Object getAttribute(String attribute)
- throws AttributeNotFoundException,
- MBeanException, ReflectionException {
- return meta.getAttribute(getImplementation(),attribute);
- }
-
- // ------------------------------------------------------------------
- // From the DynamicMBean interface.
- // ------------------------------------------------------------------
- public void setAttribute(Attribute attribute)
- throws AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException,
- ReflectionException {
- meta.setAttribute(getImplementation(),attribute);
- }
-
- // ------------------------------------------------------------------
- // From the DynamicMBean interface.
- // ------------------------------------------------------------------
- public AttributeList getAttributes(String[] attributes) {
- try {
- return meta.getAttributes(getImplementation(),attributes);
- } catch (ReflectionException x) {
- final RuntimeException r =
- new UndeclaredThrowableException(x,x.getMessage());
- throw new RuntimeOperationsException(r,x.getMessage());
- }
- }
-
- // ------------------------------------------------------------------
- // From the DynamicMBean interface.
- // ------------------------------------------------------------------
- public AttributeList setAttributes(AttributeList attributes) {
- try {
- return meta.setAttributes(getImplementation(),attributes);
- } catch (ReflectionException x) {
- final RuntimeException r =
- new UndeclaredThrowableException(x,x.getMessage());
- throw new RuntimeOperationsException(r,x.getMessage());
- }
- }
-
- // ------------------------------------------------------------------
- // From the DynamicMBean interface.
- // ------------------------------------------------------------------
- public Object invoke(String actionName, Object params[],
- String signature[])
- throws MBeanException, ReflectionException {
- return meta.invoke(getImplementation(),actionName,params,signature);
- }
-
- /**
- * Get the {@link MBeanInfo} for this MBean.
- * <p>
- * This method implements
- * {@link javax.management.DynamicMBean#getMBeanInfo()
- * DynamicMBean.getMBeanInfo()}.
- * <p>
- * This method first calls {@link #getCachedMBeanInfo()} in order to
- * retrieve the cached MBeanInfo for this MBean, if any. If the
- * MBeanInfo returned by {@link #getCachedMBeanInfo()} is not null,
- * then it is returned.<br>
- * Otherwise, this method builds a default MBeanInfo for this MBean,
- * using the Management Interface specified for this MBean.
- * <p>
- * While building the MBeanInfo, this method calls the customization
- * hooks that make it possible for subclasses to supply their custom
- * descriptions, parameter names, etc...<br>
- * Finally, it calls {@link #cacheMBeanInfo(javax.management.MBeanInfo)
- * cacheMBeanInfo()} in order to cache the new MBeanInfo.
- * @return The cached MBeanInfo for that MBean, if not null, or a
- * newly built MBeanInfo if none was cached.
- **/
- public MBeanInfo getMBeanInfo() {
- try {
- final MBeanInfo cached = getCachedMBeanInfo();
- if (cached != null) return (MBeanInfo)cached;
- } catch (RuntimeException x) {
- debug("getMBeanInfo","failed to get cached MBeanInfo: "+x);
- debugX("getMBeanInfo",x);
- }
-
- if (isTraceOn()) {
- trace("getMBeanInfo", "Building MBeanInfo for "+
- getImplementationClass().getName());
- }
-
- final MBeanInfo bi;
- final Object impl;
- try {
- synchronized (this) {
- impl = getImplementation();
- bi = buildStandardMBeanInfo();
- }
- } catch (NotCompliantMBeanException x) {
- final RuntimeException r =
- new UndeclaredThrowableException(x,x.getMessage());
- throw new RuntimeOperationsException(r,x.getMessage());
- }
-
- final String cname = getClassName(bi);
- final String text = getDescription(bi);
- final MBeanConstructorInfo[] ctors = getConstructors(bi,impl);
- final MBeanAttributeInfo[] attrs = getAttributes(bi);
- final MBeanOperationInfo[] ops = getOperations(bi);
- final MBeanNotificationInfo[] ntfs = getNotifications(bi);
- final MBeanInfo nmbi =
- new MBeanInfo(cname,text,attrs,ctors,ops,ntfs);
-
- try { cacheMBeanInfo(nmbi); } catch (RuntimeException x) {
- debug("cacheMBeanInfo","failed to cache MBeanInfo: "+x);
- debugX("cacheMBeanInfo",x);
- }
-
- return nmbi;
- }
-
- /**
- * Customization hook:
- * Get the className that will be used in the MBeanInfo returned by
- * this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom class name. The default implementation returns
- * {@link MBeanInfo#getClassName() info.getClassName()}.
- * @param info The default MBeanInfo derived by reflection.
- * @return the class name for the new MBeanInfo.
- **/
- protected String getClassName(MBeanInfo info) {
- if (info == null) return getImplementationClass().getName();
- return info.getClassName();
- }
-
- /**
- * Customization hook:
- * Get the description that will be used in the MBeanInfo returned by
- * this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom MBean description. The default implementation returns
- * {@link MBeanInfo#getDescription() info.getDescription()}.
- * @param info The default MBeanInfo derived by reflection.
- * @return the description for the new MBeanInfo.
- **/
- protected String getDescription(MBeanInfo info) {
- if (info == null) return null;
- return info.getDescription();
- }
-
- /**
- * <p>Customization hook:
- * Get the description that will be used in the MBeanFeatureInfo
- * returned by this MBean.</p>
- *
- * <p>Subclasses may redefine this method in order to supply
- * their custom description. The default implementation returns
- * {@link MBeanFeatureInfo#getDescription()
- * info.getDescription()}.</p>
- *
- * <p>This method is called by
- * {@link #getDescription(MBeanAttributeInfo)},
- * {@link #getDescription(MBeanOperationInfo)},
- * {@link #getDescription(MBeanConstructorInfo)}.</p>
- *
- * @param info The default MBeanFeatureInfo derived by reflection.
- * @return the description for the given MBeanFeatureInfo.
- **/
- protected String getDescription(MBeanFeatureInfo info) {
- if (info == null) return null;
- return info.getDescription();
- }
-
- /**
- * Customization hook:
- * Get the description that will be used in the MBeanAttributeInfo
- * returned by this MBean.
- *
- * <p>Subclasses may redefine this method in order to supply their
- * custom description. The default implementation returns {@link
- * #getDescription(MBeanFeatureInfo)
- * getDescription((MBeanFeatureInfo) info)}.
- * @param info The default MBeanAttributeInfo derived by reflection.
- * @return the description for the given MBeanAttributeInfo.
- **/
- protected String getDescription(MBeanAttributeInfo info) {
- return getDescription((MBeanFeatureInfo)info);
- }
-
- /**
- * Customization hook:
- * Get the description that will be used in the MBeanConstructorInfo
- * returned by this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom description.
- * The default implementation returns {@link
- * #getDescription(MBeanFeatureInfo)
- * getDescription((MBeanFeatureInfo) info)}.
- * @param info The default MBeanConstructorInfo derived by reflection.
- * @return the description for the given MBeanConstructorInfo.
- **/
- protected String getDescription(MBeanConstructorInfo info) {
- return getDescription((MBeanFeatureInfo)info);
- }
-
- /**
- * Customization hook:
- * Get the description that will be used for the <var>sequence</var>
- * MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom description. The default implementation returns
- * {@link MBeanParameterInfo#getDescription() param.getDescription()}.
- *
- * @param ctor The default MBeanConstructorInfo derived by reflection.
- * @param param The default MBeanParameterInfo derived by reflection.
- * @param sequence The sequence number of the parameter considered
- * ("0" for the first parameter, "1" for the second parameter,
- * etc...).
- * @return the description for the given MBeanParameterInfo.
- **/
- protected String getDescription(MBeanConstructorInfo ctor,
- MBeanParameterInfo param,
- int sequence) {
- if (param == null) return null;
- return param.getDescription();
- }
-
- /**
- * Customization hook:
- * Get the name that will be used for the <var>sequence</var>
- * MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom parameter name. The default implementation returns
- * {@link MBeanParameterInfo#getName() param.getName()}.
- *
- * @param ctor The default MBeanConstructorInfo derived by reflection.
- * @param param The default MBeanParameterInfo derived by reflection.
- * @param sequence The sequence number of the parameter considered
- * ("0" for the first parameter, "1" for the second parameter,
- * etc...).
- * @return the name for the given MBeanParameterInfo.
- **/
- protected String getParameterName(MBeanConstructorInfo ctor,
- MBeanParameterInfo param,
- int sequence) {
- if (param == null) return null;
- return param.getName();
- }
-
- /**
- * Customization hook:
- * Get the description that will be used in the MBeanOperationInfo
- * returned by this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom description. The default implementation returns
- * {@link #getDescription(MBeanFeatureInfo)
- * getDescription((MBeanFeatureInfo) info)}.
- * @param info The default MBeanOperationInfo derived by reflection.
- * @return the description for the given MBeanOperationInfo.
- **/
- protected String getDescription(MBeanOperationInfo info) {
- return getDescription((MBeanFeatureInfo)info);
- }
-
- /**
- * Customization hook:
- * Get the <var>impact</var> flag of the operation that will be used in
- * the MBeanOperationInfo returned by this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom impact flag. The default implementation returns
- * {@link MBeanOperationInfo#getImpact() info.getImpact()}.
- * @param info The default MBeanOperationInfo derived by reflection.
- * @return the impact flag for the given MBeanOperationInfo.
- **/
- protected int getImpact(MBeanOperationInfo info) {
- if (info == null) return MBeanOperationInfo.UNKNOWN;
- return info.getImpact();
- }
-
- /**
- * Customization hook:
- * Get the name that will be used for the <var>sequence</var>
- * MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom parameter name. The default implementation returns
- * {@link MBeanParameterInfo#getName() param.getName()}.
- *
- * @param op The default MBeanOperationInfo derived by reflection.
- * @param param The default MBeanParameterInfo derived by reflection.
- * @param sequence The sequence number of the parameter considered
- * ("0" for the first parameter, "1" for the second parameter,
- * etc...).
- * @return the name to use for the given MBeanParameterInfo.
- **/
- protected String getParameterName(MBeanOperationInfo op,
- MBeanParameterInfo param,
- int sequence) {
- if (param == null) return null;
- return param.getName();
- }
-
- /**
- * Customization hook:
- * Get the description that will be used for the <var>sequence</var>
- * MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom description. The default implementation returns
- * {@link MBeanParameterInfo#getDescription() param.getDescription()}.
- *
- * @param op The default MBeanOperationInfo derived by reflection.
- * @param param The default MBeanParameterInfo derived by reflection.
- * @param sequence The sequence number of the parameter considered
- * ("0" for the first parameter, "1" for the second parameter,
- * etc...).
- * @return the description for the given MBeanParameterInfo.
- **/
- protected String getDescription(MBeanOperationInfo op,
- MBeanParameterInfo param,
- int sequence) {
- if (param == null) return null;
- return param.getDescription();
- }
-
- /**
- * Customization hook:
- * Get the MBeanConstructorInfo[] that will be used in the MBeanInfo
- * returned by this MBean.
- * <br>
- * By default, this method returns <code>null</code> if the wrapped
- * implementation is not <var>this</var>. Indeed, if the wrapped
- * implementation is not this object itself, it will not be possible
- * to recreate a wrapped implementation by calling the implementation
- * constructors through <code>MBeanServer.createMBean(...)</code>.<br>
- * Otherwise, if the wrapped implementation is <var>this</var>,
- * <var>ctors</var> is returned.
- * <br>
- * Subclasses may redefine this method in order to modify this
- * behavior, if needed.
- * @param ctors The default MBeanConstructorInfo[] derived by reflection.
- * @param impl The wrapped implementation. If <code>null</code> is
- * passed, the wrapped implementation is ignored and
- * <var>ctors</var> is returned.
- * @return the MBeanConstructorInfo[] for the new MBeanInfo.
- **/
- protected MBeanConstructorInfo[]
- getConstructors(MBeanConstructorInfo[] ctors, Object impl) {
- if (ctors == null) return null;
- if (impl != null && impl != this) return null;
- return ctors;
- }
-
- /**
- * Customization hook:
- * Get the MBeanNotificationInfo[] that will be used in the MBeanInfo
- * returned by this MBean.
- * <br>
- * Subclasses may redefine this method in order to supply their
- * custom notifications.
- * @param info The default MBeanInfo derived by reflection.
- * @return the MBeanNotificationInfo[] for the new MBeanInfo.
- **/
- // Private because not needed - the StandardMBeanMetaDataImpl allready
- // calls getNotificationInfo() on the implementation....
- private MBeanNotificationInfo[]
- getNotifications(MBeanInfo info) {
- if (info == null) return null;
- return info.getNotifications();
- }
-
- /**
- * Customization hook:
- * Return the MBeanInfo cached for this object.
- *
- * <p>Subclasses may redefine this method in order to implement their
- * own caching policy. The default implementation stores one
- * {@link MBeanInfo} object per instance.
- *
- * @return The cached MBeanInfo, or null if no MBeanInfo is cached.
- *
- * @see #cacheMBeanInfo(MBeanInfo)
- **/
- protected synchronized MBeanInfo getCachedMBeanInfo() {
- return cachedMBeanInfo;
- }
-
- /**
- * Customization hook:
- * cache the MBeanInfo built for this object.
- *
- * <p>Subclasses may redefine this method in order to implement
- * their own caching policy. The default implementation stores
- * <code>info</code> in this instance. A subclass can define
- * other policies, such as not saving <code>info</code> (so it is
- * reconstructed every time {@link #getMBeanInfo()} is called) or
- * sharing a unique {@link MBeanInfo} object when several
- * <code>StandardMBean</code> instances have equal {@link
- * MBeanInfo} values.
- *
- * @param info the new <code>MBeanInfo</code> to cache. Any
- * previously cached value is discarded. This parameter may be
- * null, in which case there is no new cached value.
- **/
- protected synchronized void cacheMBeanInfo(MBeanInfo info) {
- cachedMBeanInfo = info;
- }
-
- // ------------------------------------------------------------------
- // Build the defaullt standard MBeanInfo.
- // ------------------------------------------------------------------
- private synchronized MBeanInfo buildStandardMBeanInfo()
- throws NotCompliantMBeanException {
- return meta.buildMBeanInfo(getImplementationClass(),
- getMBeanInterface());
- }
-
- // ------------------------------------------------------------------
- // Build the custom MBeanConstructorInfo[]
- // ------------------------------------------------------------------
- private MBeanConstructorInfo[]
- getConstructors(MBeanInfo info,Object impl) {
- final MBeanConstructorInfo[] ctors =
- getConstructors(info.getConstructors(),impl);
- final MBeanConstructorInfo[] nctors;
- if (ctors != null) {
- final int ctorlen = ctors.length;
- nctors = new MBeanConstructorInfo[ctorlen];
- for (int i=0; i<ctorlen; i++) {
- final MBeanConstructorInfo c = ctors[i];
- final MBeanParameterInfo[] params = c.getSignature();
- final MBeanParameterInfo[] nps;
- if (params != null) {
- final int plen = params.length;
- nps = new MBeanParameterInfo[plen];
- for (int ii=0;ii<plen;ii++) {
- MBeanParameterInfo p = params[ii];
- final String name = getParameterName(c,p,ii);
- final String text = getDescription(c,p,ii);
- nps[ii] = new MBeanParameterInfo(name,
- p.getType(),
- text);
- }
- } else {
- nps = null;
- }
- nctors[i] = new MBeanConstructorInfo(c.getName(),
- getDescription(c),
- nps);
- }
- } else {
- nctors = null;
- }
- return nctors;
- }
-
- // ------------------------------------------------------------------
- // Build the custom MBeanOperationInfo[]
- // ------------------------------------------------------------------
- private MBeanOperationInfo[] getOperations(MBeanInfo info) {
- final MBeanOperationInfo[] ops = info.getOperations();
- final MBeanOperationInfo[] nops;
- if (ops != null) {
- final int oplen = ops.length;
- nops = new MBeanOperationInfo[oplen];
- for (int i=0; i<oplen; i++) {
- final MBeanOperationInfo o = ops[i];
- final MBeanParameterInfo[] params = o.getSignature();
- final MBeanParameterInfo[] nps;
- if (params != null) {
- final int plen = params.length;
- nps = new MBeanParameterInfo[plen];
- for (int ii=0;ii<plen;ii++) {
- MBeanParameterInfo p = params[ii];
- final String name = getParameterName(o,p,ii);
- final String text = getDescription(o,p,ii);
- nps[ii] = new MBeanParameterInfo(name,
- p.getType(),
- text);
- }
- } else {
- nps = null;
- }
- nops[i] = new MBeanOperationInfo(o.getName(),
- getDescription(o),
- nps,
- o.getReturnType(),
- getImpact(o));
- }
- } else {
- nops = null;
- }
- return nops;
- }
-
- // ------------------------------------------------------------------
- // Build the custom MBeanAttributeInfo[]
- // ------------------------------------------------------------------
- private MBeanAttributeInfo[] getAttributes(MBeanInfo info) {
- final MBeanAttributeInfo[] atts = info.getAttributes();
- final MBeanAttributeInfo[] natts;
- if (atts != null) {
- final int attlen = atts.length;
- natts = new MBeanAttributeInfo[attlen];
- for (int i=0; i<attlen; i++) {
- final MBeanAttributeInfo a = atts[i];
- natts[i] = new MBeanAttributeInfo(a.getName(),
- a.getType(),
- getDescription(a),
- a.isReadable(),
- a.isWritable(),
- a.isIs());
- }
- } else {
- natts = null;
- }
- return natts;
- }
-
- // private stuff
-
- private static boolean isTraceOn() {
- return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MISC);
- }
-
- private static void trace(String clz, String func, String info) {
- Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MISC, clz, func, info);
- }
-
- private static void trace(String func, String info) {
- trace(dbgTag, func, info);
- }
-
- private static boolean isDebugOn() {
- return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MISC);
- }
-
- private static void debug(String clz, String func, String info) {
- Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MISC, clz, func, info);
- }
-
- private static void debug(String func, String info) {
- debug(dbgTag, func, info);
- }
-
- private static void debugX(String func,Throwable e) {
- if (isDebugOn()) {
- final StringWriter s = new StringWriter();
- e.printStackTrace(new PrintWriter(s));
- final String stack = s.toString();
-
- debug(dbgTag,func,"Exception caught in "+ func+"(): "+e);
- debug(dbgTag,func,stack);
-
- // java.lang.System.err.println("**** Exception caught in "+
- // func+"(): "+e);
- // java.lang.System.err.println(stack);
- }
- }
-
- }