/*
* 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.activemq.artemis.core.management.impl;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.apache.activemq.artemis.api.core.management.Attribute;
import org.apache.activemq.artemis.api.core.management.Operation;
import org.apache.activemq.artemis.api.core.management.Parameter;
public class MBeanInfoHelper {
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
// Public --------------------------------------------------------
public static MBeanOperationInfo[] getMBeanOperationsInfo(final Class mbeanInterface) {
List<MBeanOperationInfo> operations = new ArrayList<>();
for (Method method : mbeanInterface.getMethods()) {
if (!MBeanInfoHelper.isGetterMethod(method) && !MBeanInfoHelper.isSetterMethod(method) &&
!MBeanInfoHelper.isIsBooleanMethod(method)) {
operations.add(MBeanInfoHelper.getOperationInfo(method));
}
}
return operations.toArray(new MBeanOperationInfo[operations.size()]);
}
public static MBeanAttributeInfo[] getMBeanAttributesInfo(final Class mbeanInterface) {
List<MBeanAttributeInfo> tempAttributes = new ArrayList<>();
List<MBeanAttributeInfo> finalAttributes = new ArrayList<>();
List<String> alreadyAdded = new ArrayList<>();
for (Method method : mbeanInterface.getMethods()) {
if (MBeanInfoHelper.isGetterMethod(method) || MBeanInfoHelper.isSetterMethod(method) ||
MBeanInfoHelper.isIsBooleanMethod(method)) {
tempAttributes.add(MBeanInfoHelper.getAttributeInfo(method));
}
}
// since getters and setters will each have an MBeanAttributeInfo we need to de-duplicate
for (MBeanAttributeInfo info1 : tempAttributes) {
MBeanAttributeInfo infoToCopy = info1;
for (MBeanAttributeInfo info2 : tempAttributes) {
if (info1.getName().equals(info2.getName()) && !info1.equals(info2)) {
infoToCopy = new MBeanAttributeInfo(info1.getName(), info1.getType().equals("void") ? info2.getType() : info1.getType(), info1.getDescription(), (info1.isReadable() || info2.isReadable()), (info1.isWritable() || info2.isWritable()), (info1.isIs() || info2.isIs()));
}
}
if (!alreadyAdded.contains(infoToCopy.getName())) {
finalAttributes.add(infoToCopy);
alreadyAdded.add(infoToCopy.getName());
}
}
return finalAttributes.toArray(new MBeanAttributeInfo[finalAttributes.size()]);
}
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
private static boolean isGetterMethod(final Method method) {
if (!method.getName().equals("get") && method.getName().startsWith("get") &&
method.getParameterTypes().length == 0 &&
!method.getReturnType().equals(void.class)) {
return true;
}
return false;
}
private static boolean isSetterMethod(final Method method) {
if (!method.getName().equals("set") && method.getName().startsWith("set") &&
method.getParameterTypes().length == 1 &&
method.getReturnType().equals(void.class)) {
return true;
} else {
return false;
}
}
private static boolean isIsBooleanMethod(final Method method) {
if (!method.getName().equals("is") && method.getName().startsWith("is") &&
method.getParameterTypes().length == 0 &&
method.getReturnType().equals(boolean.class)) {
return true;
} else {
return false;
}
}
private static MBeanOperationInfo getOperationInfo(final Method operation) {
MBeanOperationInfo info = null;
Class<?> returnType = operation.getReturnType();
MBeanParameterInfo[] paramsInfo = MBeanInfoHelper.getParametersInfo(operation.getParameterAnnotations(), operation.getParameterTypes());
String description = operation.getName();
int impact = MBeanOperationInfo.UNKNOWN;
if (operation.getAnnotation(Operation.class) != null) {
description = operation.getAnnotation(Operation.class).desc();
impact = operation.getAnnotation(Operation.class).impact();
}
info = new MBeanOperationInfo(operation.getName(), description, paramsInfo, returnType.getName(), impact);
return info;
}
private static MBeanAttributeInfo getAttributeInfo(final Method operation) {
String description = "N/A";
if (operation.getAnnotation(Attribute.class) != null) {
description = operation.getAnnotation(Attribute.class).desc();
}
MBeanAttributeInfo info = new MBeanAttributeInfo(getAttributeName(operation), operation.getReturnType().getName(), description, (isGetterMethod(operation) || isIsBooleanMethod(operation)), isSetterMethod(operation), isIsBooleanMethod(operation));
return info;
}
private static String getAttributeName(Method operation) {
String name = operation.getName();
if (isGetterMethod(operation) || isSetterMethod(operation))
name = operation.getName().substring(3);
else if (isIsBooleanMethod(operation))
name = operation.getName().substring(2);
return name;
}
private static MBeanParameterInfo[] getParametersInfo(final Annotation[][] params, final Class<?>[] paramTypes) {
MBeanParameterInfo[] paramsInfo = new MBeanParameterInfo[params.length];
for (int i = 0; i < params.length; i++) {
MBeanParameterInfo paramInfo = null;
String type = paramTypes[i].getName();
for (Annotation anno : params[i]) {
if (Parameter.class.isInstance(anno)) {
String name = Parameter.class.cast(anno).name();
String description = Parameter.class.cast(anno).desc();
paramInfo = new MBeanParameterInfo(name, type, description);
}
}
if (paramInfo == null) {
paramInfo = new MBeanParameterInfo("p " + (i + 1), type, "parameter " + (i + 1));
}
paramsInfo[i] = paramInfo;
}
return paramsInfo;
}
// Inner classes -------------------------------------------------
}