001/* 002 * Copyright 2002-2014 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jmx.export.assembler; 018 019import java.lang.reflect.Method; 020import java.util.Arrays; 021import java.util.Enumeration; 022import java.util.HashMap; 023import java.util.HashSet; 024import java.util.Map; 025import java.util.Properties; 026import java.util.Set; 027 028import org.springframework.util.StringUtils; 029 030/** 031 * {@code AbstractReflectiveMBeanInfoAssembler} subclass that allows 032 * method names to be explicitly excluded as MBean operations and attributes. 033 * 034 * <p>Any method not explicitly excluded from the management interface will be exposed to 035 * JMX. JavaBean getters and setters will automatically be exposed as JMX attributes. 036 * 037 * <p>You can supply an array of method names via the {@code ignoredMethods} 038 * property. If you have multiple beans and you wish each bean to use a different 039 * set of method names, then you can map bean keys (that is the name used to pass 040 * the bean to the {@code MBeanExporter}) to a list of method names using the 041 * {@code ignoredMethodMappings} property. 042 * 043 * <p>If you specify values for both {@code ignoredMethodMappings} and 044 * {@code ignoredMethods}, Spring will attempt to find method names in the 045 * mappings first. If no method names for the bean are found, it will use the 046 * method names defined by {@code ignoredMethods}. 047 * 048 * @author Rob Harrop 049 * @author Seth Ladd 050 * @since 1.2.5 051 * @see #setIgnoredMethods 052 * @see #setIgnoredMethodMappings 053 * @see InterfaceBasedMBeanInfoAssembler 054 * @see SimpleReflectiveMBeanInfoAssembler 055 * @see MethodNameBasedMBeanInfoAssembler 056 * @see org.springframework.jmx.export.MBeanExporter 057 */ 058public class MethodExclusionMBeanInfoAssembler extends AbstractConfigurableMBeanInfoAssembler { 059 060 private Set<String> ignoredMethods; 061 062 private Map<String, Set<String>> ignoredMethodMappings; 063 064 065 /** 066 * Set the array of method names to be <b>ignored</b> when creating the management info. 067 * <p>These method names will be used for a bean if no entry corresponding to 068 * that bean is found in the {@code ignoredMethodsMappings} property. 069 * @see #setIgnoredMethodMappings(java.util.Properties) 070 */ 071 public void setIgnoredMethods(String... ignoredMethodNames) { 072 this.ignoredMethods = new HashSet<String>(Arrays.asList(ignoredMethodNames)); 073 } 074 075 /** 076 * Set the mappings of bean keys to a comma-separated list of method names. 077 * <p>These method names are <b>ignored</b> when creating the management interface. 078 * <p>The property key must match the bean key and the property value must match 079 * the list of method names. When searching for method names to ignore for a bean, 080 * Spring will check these mappings first. 081 */ 082 public void setIgnoredMethodMappings(Properties mappings) { 083 this.ignoredMethodMappings = new HashMap<String, Set<String>>(); 084 for (Enumeration<?> en = mappings.keys(); en.hasMoreElements();) { 085 String beanKey = (String) en.nextElement(); 086 String[] methodNames = StringUtils.commaDelimitedListToStringArray(mappings.getProperty(beanKey)); 087 this.ignoredMethodMappings.put(beanKey, new HashSet<String>(Arrays.asList(methodNames))); 088 } 089 } 090 091 092 @Override 093 protected boolean includeReadAttribute(Method method, String beanKey) { 094 return isNotIgnored(method, beanKey); 095 } 096 097 @Override 098 protected boolean includeWriteAttribute(Method method, String beanKey) { 099 return isNotIgnored(method, beanKey); 100 } 101 102 @Override 103 protected boolean includeOperation(Method method, String beanKey) { 104 return isNotIgnored(method, beanKey); 105 } 106 107 /** 108 * Determine whether the given method is supposed to be included, 109 * that is, not configured as to be ignored. 110 * @param method the operation method 111 * @param beanKey the key associated with the MBean in the beans map 112 * of the {@code MBeanExporter} 113 */ 114 protected boolean isNotIgnored(Method method, String beanKey) { 115 if (this.ignoredMethodMappings != null) { 116 Set<String> methodNames = this.ignoredMethodMappings.get(beanKey); 117 if (methodNames != null) { 118 return !methodNames.contains(method.getName()); 119 } 120 } 121 if (this.ignoredMethods != null) { 122 return !this.ignoredMethods.contains(method.getName()); 123 } 124 return true; 125 } 126 127}