/*
* Copyright (C) The MX4J Contributors.
* All rights reserved.
*
* This software is distributed under the terms of the MX4J License version 1.0.
* See the terms of the MX4J License in the documentation provided with this software.
*/
package test.javax.management;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mx4j.MX4JSystemKeys;
import mx4j.server.MBeanIntrospector;
import mx4j.server.MBeanMetaData;
import test.MX4JTestCase;
import test.javax.management.support.ComplianceSupport;
import javax.management.MBeanConstructorInfo;
/**
* @version $Revision: 1.10 $
*/
public class MBeanComplianceTest extends MX4JTestCase
{
private MBeanIntrospector introspector;
public MBeanComplianceTest(String s)
{
super(s);
}
protected void setUp() throws Exception
{
String property = MX4JSystemKeys.MX4J_STRICT_MBEAN_INTERFACE;
System.setProperty(property, "no");
introspector = new MBeanIntrospector();
}
protected void tearDown() throws Exception
{
introspector = null;
}
private MBeanMetaData createMBeanMetaData(Object mbean) throws Exception
{
MBeanMetaData metadata = MBeanMetaData.Factory.create();
metadata.setMBean(mbean);
metadata.setClassLoader(mbean.getClass().getClassLoader());
return metadata;
}
private boolean isCompliant(Object mbean) throws Exception
{
Object metadata = createMBeanMetaData(mbean);
Method method = introspector.getClass().getDeclaredMethod("testCompliance", new Class[]{MBeanMetaData.class});
method.setAccessible(true);
Boolean value = (Boolean)method.invoke(introspector, new Object[]{metadata});
return value.booleanValue();
}
private boolean isStandardCompliant(Object mbean) throws Exception
{
MBeanMetaData metadata = createMBeanMetaData(mbean);
Method method = introspector.getClass().getDeclaredMethod("testCompliance", new Class[]{MBeanMetaData.class});
method.setAccessible(true);
Boolean value = (Boolean)method.invoke(introspector, new Object[]{metadata});
return value.booleanValue() && metadata.isMBeanStandard() && !metadata.isMBeanDynamic() && metadata.getMBeanInterface() != null;
}
private boolean isDynamicCompliant(Object mbean) throws Exception
{
MBeanMetaData metadata = createMBeanMetaData(mbean);
Method method = introspector.getClass().getDeclaredMethod("testCompliance", new Class[]{MBeanMetaData.class});
method.setAccessible(true);
Boolean value = (Boolean)method.invoke(introspector, new Object[]{metadata});
return value.booleanValue() && !metadata.isMBeanStandard() && metadata.isMBeanDynamic();
}
private Class getStandardManagementInterface(Object mbean) throws Exception
{
MBeanMetaData metadata = createMBeanMetaData(mbean);
introspector.introspect(metadata);
return metadata.getMBeanInterface();
}
private Method[] getStandardManagementMethods(Object mbean) throws Exception
{
Class intf = getStandardManagementInterface(mbean);
return intf.getMethods();
}
public void testNotCompliantNoManagement() throws Exception
{
Object bad = new ComplianceSupport.NoManagement();
if (isCompliant(bad)) fail("MBean is not compliant");
}
public void testNotCompliantLexicalPatternNotRespected() throws Exception
{
Object bad = new ComplianceSupport.DoesntRespectLexicalPattern();
if (isCompliant(bad)) fail("MBean is not compliant");
}
public void testNotCompliantOverloadedAttributeSetSet() throws Exception
{
Object bad = new ComplianceSupport.OverloadedAttributeSetSet();
if (isCompliant(bad)) fail("MBean is not compliant");
}
public void testNotCompliantOverloadedAttributeGetGet() throws Exception
{
// This is guaranteed by the Java compiler: a class with 2 getters that return different types
// does not compile
}
public void testNotCompliantOverloadedAttribute3() throws Exception
{
Object bad = new ComplianceSupport.OverloadedAttributeGetSet();
if (isCompliant(bad)) fail("MBean is not compliant");
}
public void testNotCompliantOverloadedAttribute4() throws Exception
{
Object bad = new ComplianceSupport.OverloadedAttributeIsGet();
if (isCompliant(bad)) fail("MBean is not compliant");
}
public void testCompliantBasicStandard() throws Exception
{
Object good = new ComplianceSupport.BasicStandard();
if (!isStandardCompliant(good)) fail("MBean is compliant");
Method[] methods = ComplianceSupport.BasicStandardMBean.class.getMethods();
List list = Arrays.asList(methods);
Method[] management = getStandardManagementMethods(good);
List list2 = Arrays.asList(management);
assertTrue("Different management interface", list.containsAll(list2) && list2.containsAll(list));
}
public void testCompliantDerived() throws Exception
{
Object good = new ComplianceSupport.Derived();
if (!isStandardCompliant(good)) fail("MBean is compliant");
Method[] methods = ComplianceSupport.BasicStandardMBean.class.getMethods();
List list = Arrays.asList(methods);
Method[] management = getStandardManagementMethods(good);
List list2 = Arrays.asList(management);
assertTrue("Different management interface", list.containsAll(list2) && list2.containsAll(list));
}
public void testCompliantInherited() throws Exception
{
Object good = new ComplianceSupport.Inherited();
if (!isStandardCompliant(good)) fail("MBean is compliant");
Method[] methods = ComplianceSupport.InheritedMBean.class.getMethods();
List list = Arrays.asList(methods);
Method[] management = getStandardManagementMethods(good);
List list2 = Arrays.asList(management);
assertTrue("Different management interface", list.containsAll(list2) && list2.containsAll(list));
}
public void testCompliantNotInherited() throws Exception
{
Object good = new ComplianceSupport.NotInherited();
if (!isStandardCompliant(good)) fail("MBean is compliant");
Method[] methods = ComplianceSupport.BasicStandardMBean.class.getMethods();
List list = Arrays.asList(methods);
Method[] management = getStandardManagementMethods(good);
List list2 = Arrays.asList(management);
assertTrue("Different management interface", list.containsAll(list2) && list2.containsAll(list));
}
public void testCompliantMulti() throws Exception
{
Object good = new ComplianceSupport.Multi();
if (!isStandardCompliant(good)) fail("MBean is compliant");
Method[] methods = ComplianceSupport.BasicStandardMBean.class.getMethods();
List list = new ArrayList();
list.addAll(Arrays.asList(methods));
methods = ComplianceSupport.InheritedMBean.class.getMethods();
list.addAll(Arrays.asList(methods));
Method[] management = getStandardManagementMethods(good);
List list2 = Arrays.asList(management);
assertTrue("Different management interface", list.containsAll(list2) && list2.containsAll(list));
}
public void testCompliantPackagePrivate() throws Exception
{
String clsName = "test.javax.management.support.ComplianceSupport$PackagePrivate";
Class cls = getClass().getClassLoader().loadClass(clsName);
Constructor ctor = cls.getDeclaredConstructor(new Class[0]);
ctor.setAccessible(true);
Object good = ctor.newInstance(new Object[0]);
if (!isStandardCompliant(good)) fail("MBean is compliant");
}
public void testNotCompliantDynamicNoClassName() throws Exception
{
// In JMX 1.2 it is not possible to create an MBeanInfo with null class name
Object mbean = new ComplianceSupport.NoClassNameDynamicMBean();
if (isCompliant(mbean)) fail();
}
public void testCompliantBasicDynamic() throws Exception
{
Object mbean = new ComplianceSupport.BasicDynamic();
if (!isDynamicCompliant(mbean)) fail("MBean is compliant");
}
public void testCompliantStandardAndDynamic() throws Exception
{
// JMX 1.0, this is invalid. For JMX 1.1 this is a dynamic MBean
Object mbean = new ComplianceSupport.StandardAndDynamic();
if (!isDynamicCompliant(mbean)) fail("MBean is compliant");
Class intf = getStandardManagementInterface(mbean);
if (intf != null) fail("MBean is dynamic");
}
public void testCompliantStandardDynamic() throws Exception
{
// In JMX 1.0 this is an invalid MBean; in JMX 1.1 is a dynamic MBean
Object mbean = new ComplianceSupport.StandardDynamic();
if (!isDynamicCompliant(mbean)) fail("MBean is compliant");
Class intf = getStandardManagementInterface(mbean);
if (intf != null) fail("MBean is dynamic");
}
public void testDynamicFromStandard() throws Exception
{
// A standard mbean subclassed to be dynamic
Object mbean = new ComplianceSupport.DynamicFromStandard();
if (!isDynamicCompliant(mbean)) fail("MBean is compliant");
Class intf = getStandardManagementInterface(mbean);
if (intf != null) fail("MBean is dynamic");
}
public void testStandardFromDynamic() throws Exception
{
// A dynamic mbean subclassed to be standard, it remains a dynamic (as of JMX 1.1)
Object mbean = new ComplianceSupport.StandardFromDynamic();
if (!isDynamicCompliant(mbean)) fail("MBean is compliant");
Class intf = getStandardManagementInterface(mbean);
if (intf != null) fail("MBean is dynamic");
}
public void testStandardConstructorInfo() throws Exception
{
Object mbean = new ComplianceSupport.BasicStandard();
MBeanMetaData md = createMBeanMetaData(mbean);
introspector.introspect(md);
MBeanConstructorInfo[] constructors = md.getMBeanInfo().getConstructors();
assertEquals(1, constructors.length);
MBeanConstructorInfo info = constructors[0];
assertEquals(mbean.getClass().getName(), info.getName());
}
}