/* This is the core of the test. Given the MXBean interface c, we makeanMXBeanobjectthatimplementsthatinterfaceby constructingadynamicproxy.Iftheinterfacedefinesan attributeFoo(withgetFooandsetFoomethods),thenitmust alsocontainafield(constant)Fooofthesametype,anda field(constant)FooTypethatisanOpenType.ThefieldFoois areferencevalueforthiscase.Wecheckthattheattribute doesindeedhavethegivenOpenType.Thedynamically-created MXBeanwillreturnthereferencevaluefromthegetFoo() method,andwecheckthatthatvaluesurvivesthemappingto openvaluesandbackwhentheattributeisaccessedthroughan MXBeanproxy.TheMXBeanwillalsocheckinitssetFoomethod thatthevaluebeingsetisequaltothereferencevalue,which teststhatthemappingandunmappingalsoworksintheother direction.TheinterfaceshoulddefineanoperationopFoowith twoparametersandareturnvalueallofthesametypeasthe attribute.TheMXBeanwillcheckthatthetwoparametersare equaltothereferencevalue,andwillreturnthatvalue.The testchecksthatcallingtheoperationthroughanMXBeanproxy returnsthereferencevalue,againaftermappingtoandback fromopenvalues.
NamedMXBeans namedMXBeans = new NamedMXBeans(mbsc);
InvocationHandler ih =
nullTest ? new MXBeanNullImplInvocationHandler(c, namedMXBeans) : new MXBeanImplInvocationHandler(c, namedMXBeans);
T impl = c.cast(Proxy.newProxyInstance(c.getClassLoader(), newClass[] {c},
ih));
ObjectName on = new ObjectName("test:type=" + c.getName());
mbs.registerMBean(impl, on);
System.out.println("Register any MXBeans...");
Field[] fields = c.getFields(); for (Field field : fields) {
String n = field.getName(); if (n.endsWith("ObjectName")) {
String objectNameString = (String) field.get(null);
String base = n.substring(0, n.length() - 10);
Field f = c.getField(base);
Object mxbean = f.get(null);
ObjectName objectName =
ObjectName.getInstance(objectNameString);
mbs.registerMBean(mxbean, objectName);
namedMXBeans.put(objectName, mxbean);
}
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final String mname = method.getName(); finalint what = getType(method); final String name = getName(method); final Field refField = intf.getField(name); final Object refValue = getRefValue(refField);
@Override
Object getRefValue(Field refField) throws Exception { Class<?> type = refField.getType(); if (type.isPrimitive()) returnsuper.getRefValue(refField); else returnnull;
}
}
privatestaticfinal String[] prefixes = { "get", "set", "op",
}; privatestaticfinalint GET = 0, SET = 1, OP = 2;
privatestatic String getName(Method m) { return getName(m.getName());
}
privatestatic String getName(String n) { for (int i = 0; i < prefixes.length; i++) { if (n.startsWith(prefixes[i])) return n.substring(prefixes[i].length());
} thrownew Error();
}
privatestaticint getType(Method m) { return getType(m.getName());
}
privatestaticint getType(String n) { for (int i = 0; i < prefixes.length; i++) { if (n.startsWith(prefixes[i])) return i;
} thrownew Error();
}
staticboolean equal(Object o1, Object o2, NamedMXBeans namedMXBeans) { if (o1 == o2) returntrue; if (o1 == null || o2 == null) returnfalse; if (o1.getClass().isArray()) { if (!o2.getClass().isArray()) returnfalse; return deepEqual(o1, o2, namedMXBeans);
} if (o1 instanceof Map) { if (!(o2 instanceof Map)) returnfalse; return equalMap((Map) o1, (Map) o2, namedMXBeans);
} if (o1 instanceof CompositeData && o2 instanceof CompositeData) { return compositeDataEqual((CompositeData) o1, (CompositeData) o2,
namedMXBeans);
} if (Proxy.isProxyClass(o1.getClass())) { if (Proxy.isProxyClass(o2.getClass())) return proxyEqual(o1, o2, namedMXBeans);
InvocationHandler ih = Proxy.getInvocationHandler(o1); // if (ih instanceof MXBeanInvocationHandler) { // return proxyEqualsObject((MXBeanInvocationHandler) ih, // o2, namedMXBeans); if (ih instanceof MBeanServerInvocationHandler) { returntrue;
} elseif (ih instanceof CompositeDataInvocationHandler) { return o2.equals(o1); // We assume the other object has a reasonable equals method
}
} elseif (Proxy.isProxyClass(o2.getClass())) return equal(o2, o1, namedMXBeans); return o1.equals(o2);
}
// We'd use Arrays.deepEquals except we want the test to work on 1.4 // Note this code assumes no selfreferential arrays // (as does Arrays.deepEquals) privatestaticboolean deepEqual(Object a1, Object a2,
NamedMXBeans namedMXBeans) { int len = Array.getLength(a1); if (len != Array.getLength(a2)) returnfalse; for (int i = 0; i < len; i++) {
Object e1 = Array.get(a1, i);
Object e2 = Array.get(a2, i); if (!equal(e1, e2, namedMXBeans)) returnfalse;
} returntrue;
}
privatestaticboolean equalMap(Map<?,?> m1, Map<?,?> m2,
NamedMXBeans namedMXBeans) { if (m1.size() != m2.size()) returnfalse; if ((m1 instanceof SortedMap) != (m2 instanceof SortedMap)) returnfalse; for (Object k1 : m1.keySet()) { if (!m2.containsKey(k1)) returnfalse; if (!equal(m1.get(k1), m2.get(k1), namedMXBeans)) returnfalse;
} returntrue;
}
// This is needed to work around a bug (5095277) // in CompositeDataSupport.equals privatestaticboolean compositeDataEqual(CompositeData cd1,
CompositeData cd2,
NamedMXBeans namedMXBeans) { if (cd1 == cd2) returntrue; if (!cd1.getCompositeType().equals(cd2.getCompositeType())) returnfalse;
Collection v1 = cd1.values();
Collection v2 = cd2.values(); if (v1.size() != v2.size()) returnfalse; // should not happen for (Iterator i1 = v1.iterator(), i2 = v2.iterator();
i1.hasNext(); ) { if (!equal(i1.next(), i2.next(), namedMXBeans)) returnfalse;
} returntrue;
}
// private static boolean proxyEqualsObject(MXBeanInvocationHandler ih, // Object o, // NamedMXBeans namedMXBeans) { // if (namedMXBeans.getMBeanServerConnection() != // ih.getMBeanServerConnection()) // return false; // // ObjectName on = ih.getObjectName(); // Object named = namedMXBeans.get(on); // if (named == null) // return false; // return (o == named && ih.getMXBeanInterface().isInstance(named)); // }
/* I wanted to call this method toString(Object), but oddly enough thismeantthatIcouldn'tcallitfromtheinnerclass MXBeanImplInvocationHandler,becausetheinheritedObject.toString()
prevented that. */ static String string(Object o) { if (o == null) return"null"; if (o instanceof String) return'"' + (String) o + '"'; if (o instanceof Collection) return deepToString((Collection) o); if (o.getClass().isArray()) return deepToString(o); return o.toString();
}
privatestatic String deepToString(Object o) {
StringBuffer buf = new StringBuffer();
buf.append("["); int len = Array.getLength(o); for (int i = 0; i < len; i++) { if (i > 0)
buf.append(", ");
Object e = Array.get(o, i);
buf.append(string(e));
}
buf.append("]"); return buf.toString();
}
privatestatic String deepToString(Collection c) { return deepToString(c.toArray());
}
privatestaticvoid compareTabularType(TabularType t1, TabularType t2) { if (t1.equals(t2)) {
System.out.println("same tabular type"); return;
} if (t1.getClassName().equals(t2.getClassName()))
System.out.println("same class name"); if (t1.getDescription().equals(t2.getDescription()))
System.out.println("same description"); else {
System.out.println("t1 description: " + t1.getDescription());
System.out.println("t2 description: " + t2.getDescription());
} if (t1.getIndexNames().equals(t2.getIndexNames()))
System.out.println("same index names"); if (t1.getRowType().equals(t2.getRowType()))
System.out.println("same row type");
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.