From 4dde7c4c160a5512dc474a230e3093e8d32354c9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 23 Jan 2013 13:40:22 +0100 Subject: [PATCH] MBeanInfoAssembler impls expose actual method parameter names if possible Issue: SPR-9985 --- .../AbstractReflectiveMBeanInfoAssembler.java | 46 ++++++++++++++++--- .../assembler/MetadataMBeanInfoAssembler.java | 9 ++-- ...ethodNameBasedMBeanInfoAssemblerTests.java | 11 ++++- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractReflectiveMBeanInfoAssembler.java b/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractReflectiveMBeanInfoAssembler.java index d38e5be948..f953d9465c 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractReflectiveMBeanInfoAssembler.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractReflectiveMBeanInfoAssembler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,8 @@ import javax.management.modelmbean.ModelMBeanOperationInfo; import org.springframework.aop.framework.AopProxyUtils; import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeanUtils; +import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.ParameterNameDiscoverer; import org.springframework.jmx.support.JmxUtils; /** @@ -49,6 +51,7 @@ import org.springframework.jmx.support.JmxUtils; * * @author Rob Harrop * @author Juergen Hoeller + * @author David Boden * @since 1.2 * @see #includeOperation * @see #includeReadAttribute @@ -177,6 +180,8 @@ public abstract class AbstractReflectiveMBeanInfoAssembler extends AbstractMBean private boolean exposeClassDescriptor = false; + private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); + /** * Set the default for the JMX field "currencyTimeLimit". @@ -254,6 +259,23 @@ public abstract class AbstractReflectiveMBeanInfoAssembler extends AbstractMBean return this.exposeClassDescriptor; } + /** + * Set the ParameterNameDiscoverer to use for resolving method parameter + * names if needed (e.g. for parameter names of MBean operation methods). + *

The default is {@link LocalVariableTableParameterNameDiscoverer}. + */ + public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) { + this.parameterNameDiscoverer = parameterNameDiscoverer; + } + + /** + * Return the ParameterNameDiscoverer to use for resolving method parameter + * names if needed (may be {@code null} in order to skip parameter detection). + */ + protected ParameterNameDiscoverer getParameterNameDiscoverer() { + return this.parameterNameDiscoverer; + } + /** * Iterate through all properties on the MBean class and gives subclasses @@ -381,7 +403,8 @@ public abstract class AbstractReflectiveMBeanInfoAssembler extends AbstractMBean * Creates an instance of {@code ModelMBeanOperationInfo} for the * given method. Populates the parameter info for the operation. * @param method the {@code Method} to create a {@code ModelMBeanOperationInfo} for - * @param name the name for the operation info + * @param name the logical name for the operation (method name or property name); + * not used by the default implementation but possibly by subclasses * @param beanKey the key associated with the MBean in the beans map * of the {@code MBeanExporter} * @return the {@code ModelMBeanOperationInfo} @@ -392,7 +415,7 @@ public abstract class AbstractReflectiveMBeanInfoAssembler extends AbstractMBean return new ModelMBeanOperationInfo(getOperationDescription(method, beanKey), method); } else { - return new ModelMBeanOperationInfo(name, + return new ModelMBeanOperationInfo(method.getName(), getOperationDescription(method, beanKey), getOperationParameters(method, beanKey), method.getReturnType().getName(), @@ -476,16 +499,27 @@ public abstract class AbstractReflectiveMBeanInfoAssembler extends AbstractMBean /** * Create parameter info for the given method. - *

The default implementation returns an empty arry of {@code MBeanParameterInfo}. + *

The default implementation returns an empty array of {@code MBeanParameterInfo}. * @param method the {@code Method} to get the parameter information for * @param beanKey the key associated with the MBean in the beans map * of the {@code MBeanExporter} * @return the {@code MBeanParameterInfo} array */ protected MBeanParameterInfo[] getOperationParameters(Method method, String beanKey) { - return new MBeanParameterInfo[0]; - } + ParameterNameDiscoverer paramNameDiscoverer = getParameterNameDiscoverer(); + String[] paramNames = (paramNameDiscoverer != null ? paramNameDiscoverer.getParameterNames(method) : null); + if (paramNames == null) { + return new MBeanParameterInfo[0]; + } + MBeanParameterInfo[] info = new MBeanParameterInfo[paramNames.length]; + Class[] typeParameters = method.getParameterTypes(); + for(int i = 0; i < info.length; i++) { + info[i] = new MBeanParameterInfo(paramNames[i], typeParameters[i].getName(), paramNames[i]); + } + + return info; + } /** * Allows subclasses to add extra fields to the {@code Descriptor} for an MBean. diff --git a/spring-context/src/main/java/org/springframework/jmx/export/assembler/MetadataMBeanInfoAssembler.java b/spring-context/src/main/java/org/springframework/jmx/export/assembler/MetadataMBeanInfoAssembler.java index 320a64790e..b75e956dab 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/assembler/MetadataMBeanInfoAssembler.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/assembler/MetadataMBeanInfoAssembler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,7 @@ import org.springframework.jmx.export.metadata.ManagedOperationParameter; import org.springframework.jmx.export.metadata.ManagedResource; import org.springframework.jmx.support.MetricType; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -255,19 +256,17 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem @Override protected MBeanParameterInfo[] getOperationParameters(Method method, String beanKey) { ManagedOperationParameter[] params = this.attributeSource.getManagedOperationParameters(method); - if (params == null || params.length == 0) { - return new MBeanParameterInfo[0]; + if (ObjectUtils.isEmpty(params)) { + return super.getOperationParameters(method, beanKey); } MBeanParameterInfo[] parameterInfo = new MBeanParameterInfo[params.length]; Class[] methodParameters = method.getParameterTypes(); - for (int i = 0; i < params.length; i++) { ManagedOperationParameter param = params[i]; parameterInfo[i] = new MBeanParameterInfo(param.getName(), methodParameters[i].getName(), param.getDescription()); } - return parameterInfo; } diff --git a/spring-context/src/test/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssemblerTests.java b/spring-context/src/test/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssemblerTests.java index 2b0bbaeefc..72da54f6f3 100644 --- a/spring-context/src/test/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssemblerTests.java +++ b/spring-context/src/test/java/org/springframework/jmx/export/assembler/MethodNameBasedMBeanInfoAssemblerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed 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 @@ -16,11 +16,13 @@ package org.springframework.jmx.export.assembler; +import javax.management.MBeanOperationInfo; import javax.management.modelmbean.ModelMBeanAttributeInfo; import javax.management.modelmbean.ModelMBeanInfo; /** * @author Rob Harrop + * @author David Boden */ public class MethodNameBasedMBeanInfoAssemblerTests extends AbstractJmxAssemblerTests { @@ -56,6 +58,13 @@ public class MethodNameBasedMBeanInfoAssemblerTests extends AbstractJmxAssembler assertFalse(attr.isWritable()); } + public void testSetNameParameterIsNamed() throws Exception { + ModelMBeanInfo info = getMBeanInfoFromAssembler(); + + MBeanOperationInfo operationSetAge = info.getOperation("setName"); + assertEquals("name", operationSetAge.getSignature()[0].getName()); + } + @Override protected String getApplicationContextPath() { return "org/springframework/jmx/export/assembler/methodNameAssembler.xml";