private static void populateMetricsAndOperations(List<Class<?>> classes, Element root, String parentName, boolean withNamePrefix) throws Exception {
Set<String> uniqueOperations = new HashSet<String>();
Document doc = root.getOwnerDocument();
Element parent = doc.createElement(parentName);
for (Class<?> clazz : classes) {
MBean mbean = clazz.getAnnotation(MBean.class);
String prefix = withNamePrefix ? mbean.objectName() + '.' : "";
CtClass ctClass = classPool.get(clazz.getName());
CtMethod[] ctMethods = ctClass.getMethods();
for (CtMethod ctMethod : ctMethods) {
ManagedAttribute managedAttr = (ManagedAttribute) ctMethod.getAnnotation(ManagedAttribute.class);
ManagedOperation managedOp = (ManagedOperation) ctMethod.getAnnotation(ManagedOperation.class);
if (managedAttr != null) {
String property = prefix + getPropertyFromBeanConvention(ctMethod);
String attrDisplayName = managedAttr.displayName();
if (attrDisplayName.length() == 0) {
throw new RuntimeException("Missing displayName on: " + property);
}
String displayName = withNamePrefix ? "[" + mbean.objectName() + "] " + attrDisplayName : attrDisplayName;
validateDisplayName(displayName);
Element metric = doc.createElement("metric");
metric.setAttribute("property", property);
metric.setAttribute("displayName", displayName);
metric.setAttribute("displayType", managedAttr.displayType().toString());
metric.setAttribute("dataType", managedAttr.dataType().toString());
metric.setAttribute("units", managedAttr.units().toString());
metric.setAttribute("description", managedAttr.description());
parent.appendChild(metric);
}
if (managedOp != null) {
String name;
if (!managedOp.name().isEmpty()) {
name = prefix + managedOp.name();
} else {
name = prefix + ctMethod.getName();
}
Object[][] paramAnnotations = ctMethod.getParameterAnnotations();
Element parameters = doc.createElement("parameters");
for (Object[] paramAnnotationsInEach : paramAnnotations) {
boolean annotatedParameter = false;
for (Object annot : paramAnnotationsInEach) {
if (annot instanceof Parameter) {
Parameter param = (Parameter) annot;
Element prop = doc.createElementNS(URN_XMLNS_RHQ_CONFIGURATION, "simple-property");
name += "|" + param.name();
prop.setAttribute("name", param.name());
prop.setAttribute("description", param.description());
// default type from RHQ is String but sometimes we need (numbers) integer or long
if (!param.type().equals("")) prop.setAttribute("type", param.type());
parameters.appendChild(prop);
annotatedParameter = true;
}
}
if (!annotatedParameter) {
throw new RuntimeException("Duplicate operation name: " + name);
}
}
if (uniqueOperations.contains(name)) {
throw new RuntimeException("Duplicate operation name: " + name);
}
uniqueOperations.add(name);
String opDisplayName = managedOp.displayName();
if (opDisplayName.length() == 0) {
throw new RuntimeException("Missing displayName on: " + name);
}
String displayName = withNamePrefix ? "[" + mbean.objectName() + "] " + opDisplayName : opDisplayName;
validateDisplayName(displayName);
Element operation = doc.createElement("operation");
operation.setAttribute("name", name);
operation.setAttribute("displayName", displayName);
if (managedAttr != null) {
operation.setAttribute("description", managedAttr.description());
} else {
operation.setAttribute("description", managedOp.description());
}
if(parameters.hasChildNodes()) {
operation.appendChild(parameters);
}
CtClass returnType = ctMethod.getReturnType();
if (!returnType.equals(CtClass.voidType) && !returnType.equals(Void.TYPE)) {
Element results = doc.createElement("results");
Element prop = doc.createElementNS(URN_XMLNS_RHQ_CONFIGURATION, "simple-property");
prop.setAttribute("name", "operationResult");
results.appendChild(prop);
operation.appendChild(results);
}
parent.appendChild(operation);
}
}
CtField[] ctFields = ctClass.getDeclaredFields();
for (CtField ctField : ctFields) {
ManagedAttribute managedAttr = (ManagedAttribute) ctField.getAnnotation(ManagedAttribute.class);
if (managedAttr != null) {
String property = prefix + getPropertyFromBeanConvention(ctField);
Element metric = doc.createElement("metric");
metric.setAttribute("property", property);
String displayName = withNamePrefix ? "[" + mbean.objectName() + "] " + managedAttr.displayName() : managedAttr.displayName();
validateDisplayName(displayName);
metric.setAttribute("property", property);
metric.setAttribute("displayName", displayName);
metric.setAttribute("displayType", managedAttr.displayType().toString());
metric.setAttribute("dataType", managedAttr.dataType().toString());