/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.cxf.management.jmx.export.runtime;
import java.lang.reflect.Method;
import javax.management.Descriptor;
import javax.management.modelmbean.ModelMBeanInfo;
import org.apache.cxf.management.annotation.ManagedAttribute;
import org.apache.cxf.management.annotation.ManagedNotification;
import org.apache.cxf.management.annotation.ManagedNotifications;
import org.apache.cxf.management.annotation.ManagedOperation;
import org.apache.cxf.management.annotation.ManagedOperationParameter;
import org.apache.cxf.management.annotation.ManagedOperationParameters;
import org.apache.cxf.management.annotation.ManagedResource;
public class ModelMBeanAssembler {
private ModelMBeanInfoSupporter supporter = new ModelMBeanInfoSupporter();
public ManagedResource getManagedResource(Class<?> clazz) {
return clazz.getAnnotation(ManagedResource.class);
}
public ManagedAttribute getManagedAttribute(Method method) {
return method.getAnnotation(ManagedAttribute.class);
}
public ManagedOperation getManagedOperation(Method method) {
return method.getAnnotation(ManagedOperation.class);
}
public ManagedOperationParameter[] getManagedOperationParameters(Method method) {
ManagedOperationParameters params = method.getAnnotation(ManagedOperationParameters.class);
ManagedOperationParameter[] result = null;
if (params == null) {
result = new ManagedOperationParameter[0];
} else {
result = params.value();
}
return result;
}
public ManagedNotification[] getManagedNotifications(Class<?> clazz) {
ManagedNotifications notificationsAnn =
clazz.getAnnotation(ManagedNotifications.class);
ManagedNotification[] result = null;
if (null == notificationsAnn) {
return new ManagedNotification[0];
}
result = notificationsAnn.value();
return result;
}
public String getAttributeName(String methodName) {
if (methodName.indexOf("set") == 0) {
return methodName.substring(3);
}
if (methodName.indexOf("get") == 0) {
return methodName.substring(3);
}
if (methodName.indexOf("is") == 0) {
return methodName.substring(2);
}
return null;
}
public static boolean checkMethod(Method[] methods, String methodName) {
boolean result = false;
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().compareTo(methodName) == 0) {
result = true;
break;
}
}
return result;
}
public static String getAttributeType(Method[] methods, String attributeName) {
String result = null;
String searchMethod = "get" + attributeName;
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().compareTo(searchMethod) == 0) {
result = methods[i].getReturnType().getName();
break;
}
}
// check it is "is " attribute
if (null == result) {
searchMethod = "is" + attributeName;
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().compareTo(searchMethod) == 0) {
result = methods[i].getReturnType().getName();
break;
}
}
}
return result;
}
static class ManagedAttributeInfo {
String fname;
String ftype;
String description;
boolean read;
boolean write;
boolean is;
};
//get the attribut information for the method
public ManagedAttributeInfo getAttributInfo(Method[] methods,
String attributName,
String attributType,
ManagedAttribute managedAttribute) {
ManagedAttributeInfo mai = new ManagedAttributeInfo();
mai.fname = attributName;
mai.ftype = attributType;
mai.description = managedAttribute.description();
mai.is = checkMethod(methods, "is" + attributName);
mai.write = checkMethod(methods, "set" + attributName);
if (mai.is) {
mai.read = true;
} else {
mai.read = checkMethod(methods, "get" + attributName);
}
return mai;
}
Method findMethodByName(Method methods[], String methodName) {
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().compareTo(methodName) == 0) {
return methods[i];
} else {
continue;
}
}
return null;
}
void addAttributeOperation(Method method) {
Descriptor operationDescriptor =
supporter.buildAttributeOperationDescriptor(method.getName());
Class<?>[] types = method.getParameterTypes();
String[] paramTypes = new String[types.length];
String[] paramNames = new String[types.length];
String[] paramDescs = new String[types.length];
for (int j = 0; j < types.length; j++) {
paramTypes[j] = types[j].getName();
paramDescs[j] = "";
paramNames[j] = types[j].getName();
}
supporter.addModelMBeanMethod(method.getName(),
paramTypes,
paramNames,
paramDescs,
"",
method.getReturnType().getName(),
operationDescriptor);
}
public ModelMBeanInfo getModelMbeanInfo(Class<?> clazz) {
supporter.clear();
ManagedResource mr = getManagedResource(clazz);
if (mr == null) {
// the class is not need to expose to jmx
return null;
}
// Clazz get all the method which should be managemed
Descriptor mbeanDescriptor = supporter.buildMBeanDescriptor(mr);
// add the notification
ManagedNotification[] mns = getManagedNotifications(clazz);
for (int k = 0; k < mns.length; k++) {
supporter.addModelMBeanNotification(mns[k].notificationTypes(),
mns[k].name(),
mns[k].description(), null);
}
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
ManagedAttribute ma = getManagedAttribute(methods[i]);
//add Attribute to the ModelMBean
if (ma != null) {
String attributeName = getAttributeName(methods[i].getName());
if (!supporter.checkAttribute(attributeName)) {
String attributeType = getAttributeType(methods, attributeName);
ManagedAttributeInfo mai = getAttributInfo(methods,
attributeName,
attributeType,
ma);
Descriptor attributeDescriptor =
supporter.buildAttributeDescriptor(ma,
attributeName,
mai.is, mai.read, mai.write);
// should setup the description
supporter.addModelMBeanAttribute(mai.fname,
mai.ftype,
mai.read,
mai.write,
mai.is,
mai.description,
attributeDescriptor);
Method method;
// add the attribute methode to operation
if (mai.read) {
if (mai.is) {
method = findMethodByName(methods, "is" + attributeName);
} else {
method = findMethodByName(methods, "get" + attributeName);
}
addAttributeOperation(method);
}
if (mai.write) {
method = findMethodByName(methods, "set" + attributeName);
addAttributeOperation(method);
}
}
} else {
// add Operation to the ModelMBean
ManagedOperation mo = getManagedOperation(methods[i]);
if (mo != null) {
Class<?>[] types = methods[i].getParameterTypes();
ManagedOperationParameter[] mop = getManagedOperationParameters(methods[i]);
String[] paramTypes = new String[types.length];
String[] paramNames = new String[types.length];
String[] paramDescs = new String[types.length];
for (int j = 0; j < types.length; j++) {
paramTypes[j] = types[j].getName();
if (j < mop.length) {
paramDescs[j] = mop[j].description();
paramNames[j] = mop[j].name();
} else {
paramDescs[j] = "";
paramNames[j] = types[j].getName();
}
}
Descriptor operationDescriptor =
supporter.buildOperationDescriptor(mo, methods[i].getName());
supporter.addModelMBeanMethod(methods[i].getName(),
paramTypes,
paramNames,
paramDescs,
mo.description(),
methods[i].getReturnType().getName(),
operationDescriptor);
}
}
}
return supporter.buildModelMBeanInfo(mbeanDescriptor);
}
}