001: /*
002: * Copyright 2002-2007 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: * http://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:
017: package org.springframework.jmx.export.assembler;
018:
019: import javax.management.Descriptor;
020: import javax.management.JMException;
021: import javax.management.modelmbean.ModelMBeanAttributeInfo;
022: import javax.management.modelmbean.ModelMBeanConstructorInfo;
023: import javax.management.modelmbean.ModelMBeanInfo;
024: import javax.management.modelmbean.ModelMBeanInfoSupport;
025: import javax.management.modelmbean.ModelMBeanNotificationInfo;
026: import javax.management.modelmbean.ModelMBeanOperationInfo;
027:
028: import org.springframework.aop.support.AopUtils;
029: import org.springframework.jmx.support.JmxUtils;
030:
031: /**
032: * Abstract implementation of the <code>MBeanInfoAssembler</code> interface
033: * that encapsulates the creation of a <code>ModelMBeanInfo</code> instance
034: * but delegates the creation of metadata to subclasses.
035: *
036: * <p>This class offers two flavors of Class extraction from a managed bean
037: * instance: {@link #getTargetClass}, extracting the target class behind
038: * any kind of AOP proxy, and {@link #getClassToExpose}, returning the
039: * class or interface that will be searched for annotations and exposed
040: * to the JMX runtime.
041: *
042: * @author Rob Harrop
043: * @author Juergen Hoeller
044: * @since 1.2
045: */
046: public abstract class AbstractMBeanInfoAssembler implements
047: MBeanInfoAssembler {
048:
049: /**
050: * Create an instance of the <code>ModelMBeanInfoSupport</code> class supplied with all
051: * JMX implementations and populates the metadata through calls to the subclass.
052: * @param managedBean the bean that will be exposed (might be an AOP proxy)
053: * @param beanKey the key associated with the managed bean
054: * @return the populated ModelMBeanInfo instance
055: * @throws JMException in case of errors
056: * @see #getDescription(Object, String)
057: * @see #getAttributeInfo(Object, String)
058: * @see #getConstructorInfo(Object, String)
059: * @see #getOperationInfo(Object, String)
060: * @see #getNotificationInfo(Object, String)
061: * @see #populateMBeanDescriptor(javax.management.Descriptor, Object, String)
062: */
063: public ModelMBeanInfo getMBeanInfo(Object managedBean,
064: String beanKey) throws JMException {
065: checkManagedBean(managedBean);
066: ModelMBeanInfo info = new ModelMBeanInfoSupport(getClassName(
067: managedBean, beanKey), getDescription(managedBean,
068: beanKey), getAttributeInfo(managedBean, beanKey),
069: getConstructorInfo(managedBean, beanKey),
070: getOperationInfo(managedBean, beanKey),
071: getNotificationInfo(managedBean, beanKey));
072: Descriptor desc = info.getMBeanDescriptor();
073: populateMBeanDescriptor(desc, managedBean, beanKey);
074: info.setMBeanDescriptor(desc);
075: return info;
076: }
077:
078: /**
079: * Check the given bean instance, throwing an IllegalArgumentException
080: * if it is not eligible for exposure with this assembler.
081: * <p>Default implementation is empty, accepting every bean instance.
082: * @param managedBean the bean that will be exposed (might be an AOP proxy)
083: * @throws IllegalArgumentException the bean is not valid for exposure
084: */
085: protected void checkManagedBean(Object managedBean)
086: throws IllegalArgumentException {
087: }
088:
089: /**
090: * Return the actual bean class of the given bean instance.
091: * This is the class exposed to description-style JMX properties.
092: * <p>Default implementation returns the target class for an AOP proxy,
093: * and the plain bean class else.
094: * @param managedBean the bean instance (might be an AOP proxy)
095: * @return the bean class to expose
096: * @see org.springframework.aop.framework.AopProxyUtils#getTargetClass
097: */
098: protected Class getTargetClass(Object managedBean) {
099: return AopUtils.getTargetClass(managedBean);
100: }
101:
102: /**
103: * Return the class or interface to expose for the given bean.
104: * This is the class that will be searched for attributes and operations
105: * (for example, checked for annotations).
106: * @param managedBean the bean instance (might be an AOP proxy)
107: * @return the bean class to expose
108: * @see JmxUtils#getClassToExpose(Object)
109: */
110: protected Class getClassToExpose(Object managedBean) {
111: return JmxUtils.getClassToExpose(managedBean);
112: }
113:
114: /**
115: * Return the class or interface to expose for the given bean class.
116: * This is the class that will be searched for attributes and operations
117: * @param beanClass the bean class (might be an AOP proxy class)
118: * @return the bean class to expose
119: * @see JmxUtils#getClassToExpose(Class)
120: */
121: protected Class getClassToExpose(Class beanClass) {
122: return JmxUtils.getClassToExpose(beanClass);
123: }
124:
125: /**
126: * Get the class name of the MBean resource.
127: * <p>Default implementation returns a simple description for the MBean
128: * based on the class name.
129: * @param managedBean the bean instance (might be an AOP proxy)
130: * @param beanKey the key associated with the MBean in the beans map
131: * of the <code>MBeanExporter</code>
132: * @return the MBean description
133: * @throws JMException in case of errors
134: */
135: protected String getClassName(Object managedBean, String beanKey)
136: throws JMException {
137: return getTargetClass(managedBean).getName();
138: }
139:
140: /**
141: * Get the description of the MBean resource.
142: * <p>Default implementation returns a simple description for the MBean
143: * based on the class name.
144: * @param managedBean the bean instance (might be an AOP proxy)
145: * @param beanKey the key associated with the MBean in the beans map
146: * of the <code>MBeanExporter</code>
147: * @throws JMException in case of errors
148: */
149: protected String getDescription(Object managedBean, String beanKey)
150: throws JMException {
151: String targetClassName = getTargetClass(managedBean).getName();
152: if (AopUtils.isAopProxy(managedBean)) {
153: return "Proxy for " + targetClassName;
154: }
155: return targetClassName;
156: }
157:
158: /**
159: * Called after the <code>ModelMBeanInfo</code> instance has been constructed but
160: * before it is passed to the <code>MBeanExporter</code>.
161: * <p>Subclasses can implement this method to add additional descriptors to the
162: * MBean metadata. Default implementation is empty.
163: * @param descriptor the <code>Descriptor</code> for the MBean resource.
164: * @param managedBean the bean instance (might be an AOP proxy)
165: * @param beanKey the key associated with the MBean in the beans map
166: * of the <code>MBeanExporter</code>
167: * @throws JMException in case of errors
168: */
169: protected void populateMBeanDescriptor(Descriptor descriptor,
170: Object managedBean, String beanKey) throws JMException {
171: }
172:
173: /**
174: * Get the constructor metadata for the MBean resource. Subclasses should implement
175: * this method to return the appropriate metadata for all constructors that should
176: * be exposed in the management interface for the managed resource.
177: * <p>Default implementation returns an empty array of <code>ModelMBeanConstructorInfo</code>.
178: * @param managedBean the bean instance (might be an AOP proxy)
179: * @param beanKey the key associated with the MBean in the beans map
180: * of the <code>MBeanExporter</code>
181: * @return the constructor metadata
182: * @throws JMException in case of errors
183: */
184: protected ModelMBeanConstructorInfo[] getConstructorInfo(
185: Object managedBean, String beanKey) throws JMException {
186: return new ModelMBeanConstructorInfo[0];
187: }
188:
189: /**
190: * Get the notification metadata for the MBean resource. Subclasses should implement
191: * this method to return the appropriate metadata for all notifications that should
192: * be exposed in the management interface for the managed resource.
193: * <p>Default implementation returns an empty array of <code>ModelMBeanNotificationInfo</code>.
194: * @param managedBean the bean instance (might be an AOP proxy)
195: * @param beanKey the key associated with the MBean in the beans map
196: * of the <code>MBeanExporter</code>
197: * @return the notification metadata
198: * @throws JMException in case of errors
199: */
200: protected ModelMBeanNotificationInfo[] getNotificationInfo(
201: Object managedBean, String beanKey) throws JMException {
202: return new ModelMBeanNotificationInfo[0];
203: }
204:
205: /**
206: * Get the attribute metadata for the MBean resource. Subclasses should implement
207: * this method to return the appropriate metadata for all the attributes that should
208: * be exposed in the management interface for the managed resource.
209: * @param managedBean the bean instance (might be an AOP proxy)
210: * @param beanKey the key associated with the MBean in the beans map
211: * of the <code>MBeanExporter</code>
212: * @return the attribute metadata
213: * @throws JMException in case of errors
214: */
215: protected abstract ModelMBeanAttributeInfo[] getAttributeInfo(
216: Object managedBean, String beanKey) throws JMException;
217:
218: /**
219: * Get the operation metadata for the MBean resource. Subclasses should implement
220: * this method to return the appropriate metadata for all operations that should
221: * be exposed in the management interface for the managed resource.
222: * @param managedBean the bean instance (might be an AOP proxy)
223: * @param beanKey the key associated with the MBean in the beans map
224: * of the <code>MBeanExporter</code>
225: * @return the operation metadata
226: * @throws JMException in case of errors
227: */
228: protected abstract ModelMBeanOperationInfo[] getOperationInfo(
229: Object managedBean, String beanKey) throws JMException;
230:
231: }
|