KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > jmx > export > assembler > InterfaceBasedMBeanInfoAssembler


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.jmx.export.assembler;
18
19 import java.lang.reflect.Method JavaDoc;
20 import java.lang.reflect.Modifier JavaDoc;
21 import java.util.Arrays JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.Properties JavaDoc;
26
27 import org.springframework.beans.factory.BeanClassLoaderAware;
28 import org.springframework.beans.factory.InitializingBean;
29 import org.springframework.util.ClassUtils;
30 import org.springframework.util.StringUtils;
31
32 /**
33  * Subclass of <code>AbstractReflectiveMBeanInfoAssembler</code> that allows for
34  * the management interface of a bean to be defined using arbitrary interfaces.
35  * Any methods or properties that are defined in those interfaces are exposed
36  * as MBean operations and attributes.
37  *
38  * <p>By default, this class votes on the inclusion of each operation or attribute
39  * based on the interfaces implemented by the bean class. However, you can supply an
40  * array of interfaces via the <code>managedInterfaces</code> property that will be
41  * used instead. If you have multiple beans and you wish each bean to use a different
42  * set of interfaces, then you can map bean keys (that is the name used to pass the
43  * bean to the <code>MBeanExporter</code>) to a list of interface names using the
44  * <code>interfaceMappings</code> property.
45  *
46  * <p>If you specify values for both <code>interfaceMappings</code> and
47  * <code>managedInterfaces</code>, Spring will attempt to find interfaces in the
48  * mappings first. If no interfaces for the bean are found, it will use the
49  * interfaces defined by <code>managedInterfaces</code>.
50  *
51  * @author Rob Harrop
52  * @author Juergen Hoeller
53  * @since 1.2
54  * @see #setManagedInterfaces
55  * @see #setInterfaceMappings
56  * @see MethodNameBasedMBeanInfoAssembler
57  * @see SimpleReflectiveMBeanInfoAssembler
58  * @see org.springframework.jmx.export.MBeanExporter
59  */

60 public class InterfaceBasedMBeanInfoAssembler extends AbstractConfigurableMBeanInfoAssembler
61         implements BeanClassLoaderAware, InitializingBean {
62
63     /**
64      * Stores the array of interfaces to use for creating the management interface.
65      */

66     private Class JavaDoc[] managedInterfaces;
67
68     /**
69      * Stores the mappings of bean keys to an array of <code>Class</code>es.
70      */

71     private Properties JavaDoc interfaceMappings;
72
73     private ClassLoader JavaDoc beanClassLoader = ClassUtils.getDefaultClassLoader();
74
75     /**
76      * Stores the mappings of bean keys to an array of <code>Class</code>es.
77      */

78     private Map JavaDoc resolvedInterfaceMappings;
79
80
81     /**
82      * Set the array of interfaces to use for creating the management info.
83      * These interfaces will be used for a bean if no entry corresponding to
84      * that bean is found in the <code>interfaceMappings</code> property.
85      * @param managedInterfaces an array of classes indicating the interfaces to use.
86      * Each entry <strong>MUST</strong> be an interface.
87      * @see #setInterfaceMappings
88      */

89     public void setManagedInterfaces(Class JavaDoc[] managedInterfaces) {
90         if (managedInterfaces != null) {
91             for (int x = 0; x < managedInterfaces.length; x++) {
92                 if (!managedInterfaces[x].isInterface()) {
93                     throw new IllegalArgumentException JavaDoc(
94                             "Management interface [" + managedInterfaces[x].getName() + "] is no interface");
95                 }
96             }
97         }
98         this.managedInterfaces = managedInterfaces;
99     }
100
101     /**
102      * Set the mappings of bean keys to a comma-separated list of interface names.
103      * The property key should match the bean key and the property value should match
104      * the list of interface names. When searching for interfaces for a bean, Spring
105      * will check these mappings first.
106      * @param mappings the mappins of bean keys to interface names
107      */

108     public void setInterfaceMappings(Properties JavaDoc mappings) {
109         this.interfaceMappings = mappings;
110     }
111
112     public void setBeanClassLoader(ClassLoader JavaDoc beanClassLoader) {
113         this.beanClassLoader = beanClassLoader;
114     }
115
116
117     public void afterPropertiesSet() {
118         if (this.interfaceMappings != null) {
119             this.resolvedInterfaceMappings = resolveInterfaceMappings(this.interfaceMappings);
120         }
121     }
122
123     /**
124      * Resolve the given interface mappings, turning class names into Class objects.
125      * @param mappings the specified interface mappings
126      * @return the resolved interface mappings (with Class objects as values)
127      */

128     private Map JavaDoc resolveInterfaceMappings(Properties JavaDoc mappings) {
129         Map JavaDoc resolvedMappings = new HashMap JavaDoc(mappings.size());
130         for (Enumeration JavaDoc en = mappings.propertyNames(); en.hasMoreElements();) {
131             String JavaDoc beanKey = (String JavaDoc) en.nextElement();
132             String JavaDoc[] classNames = StringUtils.commaDelimitedListToStringArray(mappings.getProperty(beanKey));
133             Class JavaDoc[] classes = resolveClassNames(classNames, beanKey);
134             resolvedMappings.put(beanKey, classes);
135         }
136         return resolvedMappings;
137     }
138
139     /**
140      * Resolve the given class names into Class objects.
141      * @param classNames the class names to resolve
142      * @param beanKey the bean key that the class names are associated with
143      * @return the resolved Class
144      */

145     private Class JavaDoc[] resolveClassNames(String JavaDoc[] classNames, String JavaDoc beanKey) {
146         Class JavaDoc[] classes = new Class JavaDoc[classNames.length];
147         for (int x = 0; x < classes.length; x++) {
148             Class JavaDoc cls = ClassUtils.resolveClassName(classNames[x].trim(), this.beanClassLoader);
149             if (!cls.isInterface()) {
150                 throw new IllegalArgumentException JavaDoc(
151                         "Class [" + classNames[x] + "] mapped to bean key [" + beanKey + "] is no interface");
152             }
153             classes[x] = cls;
154         }
155         return classes;
156     }
157
158
159     /**
160      * Check to see if the <code>Method</code> is declared in
161      * one of the configured interfaces and that it is public.
162      * @param method the accessor <code>Method</code>.
163      * @param beanKey the key associated with the MBean in the
164      * <code>beans</code> <code>Map</code>.
165      * @return <code>true</code> if the <code>Method</code> is declared in one of the
166      * configured interfaces, otherwise <code>false</code>.
167      */

168     protected boolean includeReadAttribute(Method JavaDoc method, String JavaDoc beanKey) {
169         return isPublicInInterface(method, beanKey);
170     }
171
172     /**
173      * Check to see if the <code>Method</code> is declared in
174      * one of the configured interfaces and that it is public.
175      * @param method the mutator <code>Method</code>.
176      * @param beanKey the key associated with the MBean in the
177      * <code>beans</code> <code>Map</code>.
178      * @return <code>true</code> if the <code>Method</code> is declared in one of the
179      * configured interfaces, otherwise <code>false</code>.
180      */

181     protected boolean includeWriteAttribute(Method JavaDoc method, String JavaDoc beanKey) {
182         return isPublicInInterface(method, beanKey);
183     }
184
185     /**
186      * Check to see if the <code>Method</code> is declared in
187      * one of the configured interfaces and that it is public.
188      * @param method the operation <code>Method</code>.
189      * @param beanKey the key associated with the MBean in the
190      * <code>beans</code> <code>Map</code>.
191      * @return <code>true</code> if the <code>Method</code> is declared in one of the
192      * configured interfaces, otherwise <code>false</code>.
193      */

194     protected boolean includeOperation(Method JavaDoc method, String JavaDoc beanKey) {
195         return isPublicInInterface(method, beanKey);
196     }
197
198     /**
199      * Check to see if the <code>Method</code> is both public and declared in
200      * one of the configured interfaces.
201      * @param method the <code>Method</code> to check.
202      * @param beanKey the key associated with the MBean in the beans map
203      * @return <code>true</code> if the <code>Method</code> is declared in one of the
204      * configured interfaces and is public, otherwise <code>false</code>.
205      */

206     private boolean isPublicInInterface(Method JavaDoc method, String JavaDoc beanKey) {
207         return ((method.getModifiers() & Modifier.PUBLIC) > 0) && isDeclaredInInterface(method, beanKey);
208     }
209
210     /**
211      * Checks to see if the given method is declared in a managed
212      * interface for the given bean.
213      */

214     private boolean isDeclaredInInterface(Method JavaDoc method, String JavaDoc beanKey) {
215         Class JavaDoc[] ifaces = null;
216
217         if (this.resolvedInterfaceMappings != null) {
218             ifaces = (Class JavaDoc[]) this.resolvedInterfaceMappings.get(beanKey);
219         }
220
221         if (ifaces == null) {
222             ifaces = this.managedInterfaces;
223             if (ifaces == null) {
224                 ifaces = ClassUtils.getAllInterfacesForClass(method.getDeclaringClass());
225             }
226         }
227
228         if (ifaces != null) {
229             for (int i = 0; i < ifaces.length; i++) {
230                 Method JavaDoc[] methods = ifaces[i].getMethods();
231                 for (int j = 0; j < methods.length; j++) {
232                     Method JavaDoc ifaceMethod = methods[j];
233                     if (ifaceMethod.getName().equals(method.getName()) &&
234                             Arrays.equals(ifaceMethod.getParameterTypes(), method.getParameterTypes())) {
235                         return true;
236                     }
237                 }
238             }
239         }
240
241         return false;
242     }
243
244 }
245
Popular Tags