MBeanInfoCombiner.java
package com.ziesemer.utils.jmx.server;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.openmbean.CompositeData;
/**
* <p>This class is meant to be called by the customization hooks in
* {@link javax.management.StandardMBean}, useful for filling in missing descriptions,
* parameter names, and impacts from another populated {@link MBeanInfo},
* such as one built by {@link MBeanInfoBuilder} that reads annotations.</p>
* <p>If an instance of this class is stored in a subclass of {@link javax.management.StandardMBean},
* steps should be taken to allow it and its included {@link MBeanInfo} to
* be garbage collected.
* One way to accomplish this is by setting the stored reference to null after calling
* <code>super</code> in either {@link javax.management.StandardMBean#getMBeanInfo()} or
* {@link javax.management.StandardMBean#cacheMBeanInfo(MBeanInfo)}.</p>
* <p>Following the current limitations of {@link MBeanInfoBuilder}, methods supporting
* {@link javax.management.MBeanConstructorInfo}s are not currently provided,
* as no current need was seen to support constructors remotely.
* For example, JConsole doesn't appear to support constructing object instances at all,
* with or without parameters.
* If you have a need otherwise, please first verify that this is still the current release,
* then open an issue on the issue tracker.</p>
* <p>This approach should maintain compatibility with Java 1.5/5.0, 1.6 / 6, and beyond.
* This includes:</p>
* <ul>
* <li>Not extending {@link javax.management.StandardMBean}, which would result in
* hiding the constructor added in 1.6 / 6 that supports MXBeans.</li>
* <li>Allowing {@link javax.management.Descriptor}s to be used in all the
* {@link javax.management.MBeanFeatureInfo} classes, which aren't usable until
* Java 1.6 / 6 when these classes also implement
* <code>javax.management.DescriptorRead</code>.</li>
* <li>Proper and full support of MXBeans, a limitation of this library's {@link SimpleMBean}.</li>
* </ul>
* @author Mark A. Ziesemer
* <a href="http://www.ziesemer.com."><www.ziesemer.com></a>
*/
public class MBeanInfoCombiner{
protected final MBeanInfo mBeanInfo;
public MBeanInfoCombiner(final MBeanInfo mBeanInfo){
this.mBeanInfo = mBeanInfo;
}
public MBeanInfo getMBeanInfo(){
return mBeanInfo;
}
/**
* <p>Designed to be called from
* {@link javax.management.StandardMBean#getDescription(MBeanInfo)}.</p>
*/
public String getDescription(final MBeanInfo mbi){
return mBeanInfo.getDescription();
}
/**
* <p>Designed to be called from
* {@link javax.management.StandardMBean#getDescription(MBeanAttributeInfo)}.</p>
*/
public String getDescription(final MBeanAttributeInfo mbai){
for(final MBeanAttributeInfo customInfo : mBeanInfo.getAttributes()){
if(customInfo.getName().equals(mbai.getName())){
return customInfo.getDescription();
}
}
return mbai.getDescription();
}
/**
* <p>Designed to be called from
* {@link javax.management.StandardMBean#getDescription(MBeanOperationInfo)}.</p>
*/
public String getDescription(final MBeanOperationInfo mboi){
final MBeanOperationInfo customInfo = findMatching(mboi);
if(customInfo != null){
return customInfo.getDescription();
}
return mboi.getDescription();
}
/**
* <p>Designed to be called from
* {@link javax.management.StandardMBean#getImpact(MBeanOperationInfo)}.</p>
*/
public int getImpact(final MBeanOperationInfo mboi){
final MBeanOperationInfo customInfo = findMatching(mboi);
if(customInfo != null){
return customInfo.getImpact();
}
return mboi.getImpact();
}
/**
* <p>Designed to be called from
* {@link javax.management.StandardMBean#getParameterName(MBeanOperationInfo, MBeanParameterInfo, int)}.</p>
*/
public String getParameterName(final MBeanOperationInfo mboi,
final MBeanParameterInfo mbpi, final int sequence){
final MBeanOperationInfo customInfo = findMatching(mboi);
if(customInfo != null){
return customInfo.getSignature()[sequence].getName();
}
return mbpi.getName();
}
/**
* <p>Designed to be called from
* {@link javax.management.StandardMBean#getDescription(MBeanOperationInfo, MBeanParameterInfo, int)}.</p>
*/
public String getDescription(final MBeanOperationInfo mboi,
final MBeanParameterInfo mbpi, final int sequence){
final MBeanOperationInfo customInfo = findMatching(mboi);
if(customInfo != null){
return customInfo.getSignature()[sequence].getDescription();
}
return mbpi.getDescription();
}
protected MBeanOperationInfo findMatching(final MBeanOperationInfo mboi){
for(final MBeanOperationInfo customInfo : mBeanInfo.getOperations()){
if(customInfo.getName().equals(mboi.getName())
&& (customInfo.getReturnType().equals(mboi.getReturnType())
|| CompositeData.class.getName().equals(mboi.getReturnType()))){
final MBeanParameterInfo[] customParams = customInfo.getSignature();
final MBeanParameterInfo[] params = mboi.getSignature();
// Can't simply call .equals, as it takes the names and descriptions into account.
if(customParams.length == params.length){
boolean matches = true;
for(int i=0; i < customParams.length && matches; i++){
matches = customParams[i].getType().equals(params[i].getType());
}
if(matches){
return customInfo;
}
}
}
}
return null;
}
}