Open Source Repository

Home /spring/spring-context-3.0.5 | Repository Home



org/springframework/jmx/export/assembler/AbstractMBeanInfoAssembler.java
/*
 * Copyright 2002-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.jmx.export.assembler;

import javax.management.Descriptor;
import javax.management.JMException;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanConstructorInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanNotificationInfo;
import javax.management.modelmbean.ModelMBeanOperationInfo;

import org.springframework.aop.support.AopUtils;
import org.springframework.jmx.support.JmxUtils;

/**
 * Abstract implementation of the <code>MBeanInfoAssembler</code> interface
 * that encapsulates the creation of a <code>ModelMBeanInfo</code> instance
 * but delegates the creation of metadata to subclasses.
 *
 <p>This class offers two flavors of Class extraction from a managed bean
 * instance: {@link #getTargetClass}, extracting the target class behind
 * any kind of AOP proxy, and {@link #getClassToExpose}, returning the
 * class or interface that will be searched for annotations and exposed
 * to the JMX runtime.
 *
 @author Rob Harrop
 @author Juergen Hoeller
 @since 1.2
 */
public abstract class AbstractMBeanInfoAssembler implements MBeanInfoAssembler {

  /**
   * Create an instance of the <code>ModelMBeanInfoSupport</code> class supplied with all
   * JMX implementations and populates the metadata through calls to the subclass.
   @param managedBean the bean that will be exposed (might be an AOP proxy)
   @param beanKey the key associated with the managed bean
   @return the populated ModelMBeanInfo instance
   @throws JMException in case of errors
   @see #getDescription(Object, String)
   @see #getAttributeInfo(Object, String)
   @see #getConstructorInfo(Object, String)
   @see #getOperationInfo(Object, String)
   @see #getNotificationInfo(Object, String)
   @see #populateMBeanDescriptor(javax.management.Descriptor, Object, String)
   */
  public ModelMBeanInfo getMBeanInfo(Object managedBean, String beanKeythrows JMException {
    checkManagedBean(managedBean);
    ModelMBeanInfo info = new ModelMBeanInfoSupport(
        getClassName(managedBean, beanKey), getDescription(managedBean, beanKey),
        getAttributeInfo(managedBean, beanKey), getConstructorInfo(managedBean, beanKey),
        getOperationInfo(managedBean, beanKey), getNotificationInfo(managedBean, beanKey));
    Descriptor desc = info.getMBeanDescriptor();
    populateMBeanDescriptor(desc, managedBean, beanKey);
    info.setMBeanDescriptor(desc);
    return info;
  }

  /**
   * Check the given bean instance, throwing an IllegalArgumentException
   * if it is not eligible for exposure with this assembler.
   <p>Default implementation is empty, accepting every bean instance.
   @param managedBean the bean that will be exposed (might be an AOP proxy)
   @throws IllegalArgumentException the bean is not valid for exposure
   */
  protected void checkManagedBean(Object managedBeanthrows IllegalArgumentException {
  }

  /**
   * Return the actual bean class of the given bean instance.
   * This is the class exposed to description-style JMX properties.
   <p>Default implementation returns the target class for an AOP proxy,
   * and the plain bean class else.
   @param managedBean the bean instance (might be an AOP proxy)
   @return the bean class to expose
   @see org.springframework.aop.framework.AopProxyUtils#getTargetClass
   */
  protected Class getTargetClass(Object managedBean) {
    return AopUtils.getTargetClass(managedBean);
  }

  /**
   * Return the class or interface to expose for the given bean.
   * This is the class that will be searched for attributes and operations
   * (for example, checked for annotations).
   @param managedBean the bean instance (might be an AOP proxy)
   @return the bean class to expose
   @see JmxUtils#getClassToExpose(Object) 
   */
  protected Class<?> getClassToExpose(Object managedBean) {
    return JmxUtils.getClassToExpose(managedBean);
  }

  /**
   * Return the class or interface to expose for the given bean class.
   * This is the class that will be searched for attributes and operations
   @param beanClass the bean class (might be an AOP proxy class)
   @return the bean class to expose
   @see JmxUtils#getClassToExpose(Class)
   */
  protected Class<?> getClassToExpose(Class<?> beanClass) {
    return JmxUtils.getClassToExpose(beanClass);
  }

  /**
   * Get the class name of the MBean resource.
   <p>Default implementation returns a simple description for the MBean
   * based on the class name.
   @param managedBean the bean instance (might be an AOP proxy)
   @param beanKey the key associated with the MBean in the beans map
   * of the <code>MBeanExporter</code>
   @return the MBean description
   @throws JMException in case of errors
   */
  protected String getClassName(Object managedBean, String beanKeythrows JMException {
    return getTargetClass(managedBean).getName();
  }

  /**
   * Get the description of the MBean resource.
   <p>Default implementation returns a simple description for the MBean
   * based on the class name.
   @param managedBean the bean instance (might be an AOP proxy)
   @param beanKey the key associated with the MBean in the beans map
   * of the <code>MBeanExporter</code>
   @throws JMException in case of errors
   */
  protected String getDescription(Object managedBean, String beanKeythrows JMException {
    String targetClassName = getTargetClass(managedBean).getName();
    if (AopUtils.isAopProxy(managedBean)) {
      return "Proxy for " + targetClassName;
    }
    return targetClassName;
  }

  /**
   * Called after the <code>ModelMBeanInfo</code> instance has been constructed but
   * before it is passed to the <code>MBeanExporter</code>.
   <p>Subclasses can implement this method to add additional descriptors to the
   * MBean metadata. Default implementation is empty.
   @param descriptor the <code>Descriptor</code> for the MBean resource.
   @param managedBean the bean instance (might be an AOP proxy)
   @param beanKey the key associated with the MBean in the beans map
   * of the <code>MBeanExporter</code>
   @throws JMException in case of errors
   */
  protected void populateMBeanDescriptor(Descriptor descriptor, Object managedBean, String beanKey)
      throws JMException {
  }

  /**
   * Get the constructor metadata for the MBean resource. Subclasses should implement
   * this method to return the appropriate metadata for all constructors that should
   * be exposed in the management interface for the managed resource.
   <p>Default implementation returns an empty array of <code>ModelMBeanConstructorInfo</code>.
   @param managedBean the bean instance (might be an AOP proxy)
   @param beanKey the key associated with the MBean in the beans map
   * of the <code>MBeanExporter</code>
   @return the constructor metadata
   @throws JMException in case of errors
   */
  protected ModelMBeanConstructorInfo[] getConstructorInfo(Object managedBean, String beanKey)
      throws JMException {
    return new ModelMBeanConstructorInfo[0];
  }

  /**
   * Get the notification metadata for the MBean resource. Subclasses should implement
   * this method to return the appropriate metadata for all notifications that should
   * be exposed in the management interface for the managed resource.
   <p>Default implementation returns an empty array of <code>ModelMBeanNotificationInfo</code>.
   @param managedBean the bean instance (might be an AOP proxy)
   @param beanKey the key associated with the MBean in the beans map
   * of the <code>MBeanExporter</code>
   @return the notification metadata
   @throws JMException in case of errors
   */
  protected ModelMBeanNotificationInfo[] getNotificationInfo(Object managedBean, String beanKey)
      throws JMException {
    return new ModelMBeanNotificationInfo[0];
  }


  /**
   * Get the attribute metadata for the MBean resource. Subclasses should implement
   * this method to return the appropriate metadata for all the attributes that should
   * be exposed in the management interface for the managed resource.
   @param managedBean the bean instance (might be an AOP proxy)
   @param beanKey the key associated with the MBean in the beans map
   * of the <code>MBeanExporter</code>
   @return the attribute metadata
   @throws JMException in case of errors
   */
  protected abstract ModelMBeanAttributeInfo[] getAttributeInfo(Object managedBean, String beanKey)
      throws JMException;

  /**
   * Get the operation metadata for the MBean resource. Subclasses should implement
   * this method to return the appropriate metadata for all operations that should
   * be exposed in the management interface for the managed resource.
   @param managedBean the bean instance (might be an AOP proxy)
   @param beanKey the key associated with the MBean in the beans map
   * of the <code>MBeanExporter</code>
   @return the operation metadata
   @throws JMException in case of errors
   */
  protected abstract ModelMBeanOperationInfo[] getOperationInfo(Object managedBean, String beanKey)
      throws JMException;

}