KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > jmx > agent > Introspector


1 /**
2  * The JMX 4 Distributed Open Processing (JMX4ODP)
3  *
4  * Copyright (C) 2003 by Lucas McGregor <lmcgregor@users.sourceforge.net>
5  * All Rights Reserved.
6  *
7  * This software is released under the terms of the following
8  * licenses:
9  *
10  * - The BSD License (see LICENSE.BSD).
11  *
12  * While not mandated by the BSD license, any patches you make to the
13  * JMX 4 Distributed Open Processing source code may be contributed back into the
14  * JMX 4 Distributed Open Processing project at your discretion. Contributions will
15  * benefit the Open Source community. Submissions may be made at:
16  *
17  * http://jmx4odp.sourceforge.net
18  *
19  * As per the BSD liscence, credit must be given to Lucas McGregor
20  * and the synerr dot org project.
21  **/

22 package org.objectweb.fractal.jmx.agent;
23
24 import javax.management.Descriptor JavaDoc;
25 import javax.management.JMException JavaDoc;
26 import javax.management.modelmbean.RequiredModelMBean JavaDoc;
27 import javax.management.modelmbean.DescriptorSupport JavaDoc;
28 import javax.management.modelmbean.ModelMBeanInfo JavaDoc;
29 import javax.management.modelmbean.ModelMBeanInfoSupport JavaDoc;
30 import javax.management.modelmbean.ModelMBeanAttributeInfo JavaDoc;
31 import javax.management.modelmbean.ModelMBeanOperationInfo JavaDoc;
32 import javax.management.modelmbean.ModelMBeanConstructorInfo JavaDoc;
33 import javax.management.modelmbean.ModelMBeanNotificationInfo JavaDoc;
34 import javax.management.modelmbean.InvalidTargetObjectTypeException JavaDoc;
35
36 import java.util.Vector JavaDoc;
37 import java.lang.reflect.Method JavaDoc;
38
39 /**
40  * Uses introspection to build ModelMBeans.
41  * @author Lucas McGregor, slightly modified for Fractal JMX
42  */

43 public class Introspector {
44     private final static boolean VERBOSE = true;
45     private final static boolean VERBOSE_DEBUG = false;
46
47     private Introspector() {}
48
49     /**
50      * Uses introspection to create an MBean that can manage methods and attributes of an object.
51      *
52      * @return a RequiredModelMBean that can manage the object.
53      *
54      * @param obj the object to introspect.
55      *
56      * @throws JMException if a problem occurs during introspection.
57      */

58     public static RequiredModelMBean JavaDoc createMBean(Object JavaDoc obj)
59         throws JMException JavaDoc {
60             try{
61                 return createMBean(obj, obj.getClass());
62             }
63             catch(InvalidTargetObjectTypeException JavaDoc e){
64                 throw new IllegalStateException JavaDoc(e.toString());
65             }
66         }
67
68     /**
69      * Uses introspection to create an MBean that can manage some methods and attributes of an object.
70      * These methods and attributes are specified in a class assignable to the object class.
71      *
72      * @return a RequiredModelMBean that can manage the object.
73      *
74      * @param obj the object to introspect.
75      * @param assign a class assignable to the object class.
76      *
77      * @throws InvalidTargetObjectTypeException if assign is not assignable to the object class.
78      * @throws JMException if a problem occurs during introspection.
79      */

80     public static RequiredModelMBean JavaDoc createMBean(Object JavaDoc obj, Class JavaDoc assign)
81         throws JMException JavaDoc, InvalidTargetObjectTypeException JavaDoc {
82         Class JavaDoc objClass = obj.getClass();
83         if (!assign.isAssignableFrom(objClass))
84             throw new InvalidTargetObjectTypeException JavaDoc(assign + " not a superclass or superinterface of " + objClass);
85         Method JavaDoc[] methods = assign.getMethods();
86         Vector JavaDoc attributes = new Vector JavaDoc();
87         Vector JavaDoc operators = new Vector JavaDoc();
88
89         // GET THE LIST OF METHODS IN THE OBJECT
90
for (int i = 0; i < methods.length; i++) {
91             // IF THE METHOD STARTS WITH "is," "get," or "set" THEN TRY TO ADD AN ATTRIBUTE TO THE MODELMBEAN
92
if ((methods[i].getName().startsWith("get"))
93                 || (methods[i].getName().startsWith("set"))
94                 || (methods[i].getName().startsWith("is"))) {
95                 try {
96                     ModelMBeanAttributeInfo JavaDoc mmai = doAttribute(methods, i);
97                     if (mmai != null)
98                         attributes.add(mmai);
99                 } catch (Exception JavaDoc e) {
100                     if (VERBOSE)
101                         e.printStackTrace();
102                 }
103             }
104
105             // ADD THE METHOD AS AN OPERATION TO THE MODEL MBEAN
106
try {
107                 ModelMBeanOperationInfo JavaDoc mmoi = doOperation(methods, i);
108                 if (mmoi != null)
109                     operators.add(mmoi);
110             } catch (Exception JavaDoc e) {
111                 if (VERBOSE)
112                     e.printStackTrace();
113             }
114         }
115
116         // ATTRIBUTES
117
ModelMBeanAttributeInfo JavaDoc[] attributeArray = new ModelMBeanAttributeInfo JavaDoc[attributes.size()];
118         for (int i_ = 0; i_ < attributeArray.length; i_++) {
119             attributeArray[i_] = (ModelMBeanAttributeInfo JavaDoc) attributes.get(i_);
120         }
121
122         // METHODS
123
ModelMBeanOperationInfo JavaDoc[] operatorArray = new ModelMBeanOperationInfo JavaDoc[operators.size()];
124         for (int i_ = 0; i_ < operatorArray.length; i_++) {
125             operatorArray[i_] = (ModelMBeanOperationInfo JavaDoc) operators.get(i_);
126         }
127
128         // Descriptor
129
Descriptor JavaDoc desc = new DescriptorSupport JavaDoc();
130         desc.setField("name", objClass.getName());
131         desc.setField("descriptorType", "MBean");
132
133         // CREATE MODELMBEAN
134
ModelMBeanInfo JavaDoc mminfo =
135             new ModelMBeanInfoSupport JavaDoc(
136                 objClass.getName(),
137                 objClass.getName(),
138                 attributeArray,
139                 new ModelMBeanConstructorInfo JavaDoc[0],
140                 operatorArray,
141                 new ModelMBeanNotificationInfo JavaDoc[0],
142                 desc);
143         RequiredModelMBean JavaDoc model = new RequiredModelMBean JavaDoc(mminfo);
144         model.setManagedResource(obj, "ObjectReference");
145         return model;
146     }
147
148     /**
149      * Build the ModelMBeanOperationInfo for the method. Take the array
150      * of the objects methods and the index of the method to work on.
151    *
152    * @param methods the array of the objects methods to work on.
153    * @param i the index of the method to work on.
154    * @return the ModelMBeanOperationInfo for the method.
155    * @throws JMException if something goes wrong.
156      */

157     private static ModelMBeanOperationInfo JavaDoc doOperation(Method JavaDoc methods[], int i) throws JMException JavaDoc {
158         if (VERBOSE_DEBUG)
159             System.out.println("ObjectIntrospector: processing operation: " + methods[i].getName());
160
161         Descriptor JavaDoc desc = new DescriptorSupport JavaDoc();
162         desc.setField("name", methods[i].getName());
163         desc.setField("descriptorType", "operation");
164         // MAKE SURE THAT THE AGENT DOESN'T READ FROM CACHE (0 does not work with JMX RI)
165
desc.setField("currencyTimeLimit", "1");
166
167         // IF THE METHOD STARTS WITH "get" or "is" TREAT IT AS A GETTER.
168
// IF IT STARTS WITH A "set" TREAT IT AS A SETTER.
169
if ((methods[i].getName().startsWith("get") || methods[i].getName().startsWith("is"))
170             && (methods[i].getParameterTypes().length == 0))
171             desc.setField("role", "getter");
172         else if (methods[i].getName().startsWith("set") && methods[i].getParameterTypes().length == 1)
173             desc.setField("role", "setter");
174         else
175             desc.setField("role", "operation");
176
177         ModelMBeanOperationInfo JavaDoc mmoi = new ModelMBeanOperationInfo JavaDoc(methods[i].getName(), methods[i], desc);
178         return mmoi;
179     }
180
181     /**
182      * Build the ModelMBeanAttributeInfo for the method. Take the array
183      * of the objects methods and the index of the method to work on. It
184      * needs the entire array of methods to determine matching sets of
185      * setters and getters.
186    *
187    * @param methods the array of the objects methods to work on.
188    * @param i the index of the method to work on.
189    * @return the ModelMBeanOperationInfo for the method.
190    * @throws JMException if something goes wrong.
191      */

192     private static ModelMBeanAttributeInfo JavaDoc doAttribute(Method JavaDoc methods[], int i) throws JMException JavaDoc {
193         if (VERBOSE_DEBUG)
194             System.out.println("ObjectIntrospector: processing attribute: " + methods[i].getName());
195
196         String JavaDoc name = null;
197         Method JavaDoc getter = null;
198         Method JavaDoc setter = null;
199         String JavaDoc type = null;
200
201         // THIS METHOD IS A GETTER
202
if ((methods[i].getName().startsWith("get")) && (methods[i].getParameterTypes().length == 0)) {
203             String JavaDoc setName = "s" + methods[i].getName().substring(1);
204             name = methods[i].getName().substring(3);
205             getter = methods[i];
206             type = methods[i].getReturnType().getName();
207             // CHECK TO SEE IF THERE IS THE EQUVALENT WRITE OBJECT
208
for (int i_ = 0; i_ < methods.length; i_++) {
209                 if (methods[i_].getName().equals(setName)) {
210                     setter = methods[i_];
211                     break;
212                 }
213             }
214
215         } // THIS OBJECT IS A SETTER
216
else if ((methods[i].getName().startsWith("set")) && (methods[i].getParameterTypes().length == 1)) {
217             String JavaDoc getName = "g" + methods[i].getName().substring(1);
218             name = methods[i].getName().substring(3);
219             // CHECK TO SEE IF THERE IS THE EQUVALENT READ OBJECT
220
// IF SO, THEN THE GET EQUIVALENT WOULD HAVE RETURNED
221
// A ModelMBeanAttributeInfo, SO RETURN A NULL
222
// SO THIS ATTRIBUTE DOESN'T SHOW UP TWICE
223
for (int i_ = 0; i_ < methods.length; i_++) {
224                 if (methods[i_].getName().equals(getName)) {
225                     return null;
226                 }
227             }
228             setter = methods[i];
229             type = methods[i].getParameterTypes()[0].getName();
230
231         } // THIS OBJECT IS A GETTER WITH NO SETTER
232
else if ((methods[i].getName().startsWith("is")) && (methods[i].getParameterTypes() == null)) {
233             name = methods[i].getName().substring(2);
234             getter = methods[i];
235             type = boolean.class.getName();
236         } // NOT A COMPLIENT get, set, OR is ATTRIBUTE
237
else {
238             return null;
239         }
240
241         Descriptor JavaDoc desc = new DescriptorSupport JavaDoc();
242         desc.setField("name", name); // THE NAME THAT THE ATTRIBUTE WILL HAVE
243
desc.setField("descriptorType", "attribute"); // THIS IS MANDATORY FOR ANY ATTRIBUTES DESCRIPTION
244
desc.setField("displayName", name);
245         // MAKE SURE THAT THE AGENT DOESN'T READ FROM CACHE (0 does not work with JMX RI)
246
desc.setField("currencyTimeLimit", "1");
247
248         if (getter != null)
249             desc.setField("getMethod", getter.getName());
250         if (setter != null)
251             desc.setField("setMethod", setter.getName());
252
253         ModelMBeanAttributeInfo JavaDoc mmai =
254             new ModelMBeanAttributeInfo JavaDoc(name, type, name, (getter != null), (setter != null), false, desc);
255
256         return mmai;
257     }
258 }
259
Popular Tags