KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > modeler > modules > MbeansDescriptorsIntrospectionSource


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
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.apache.commons.modeler.modules;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.commons.modeler.AttributeInfo;
22 import org.apache.commons.modeler.ManagedBean;
23 import org.apache.commons.modeler.OperationInfo;
24 import org.apache.commons.modeler.ParameterInfo;
25 import org.apache.commons.modeler.Registry;
26 import org.apache.commons.modeler.ConstructorInfo;
27
28 import javax.management.ObjectName JavaDoc;
29
30 import java.lang.reflect.Method JavaDoc;
31 import java.lang.reflect.Modifier JavaDoc;
32 import java.lang.reflect.Constructor JavaDoc;
33 import java.math.BigDecimal JavaDoc;
34 import java.math.BigInteger JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.Enumeration JavaDoc;
37 import java.util.Hashtable JavaDoc;
38 import java.util.List JavaDoc;
39
40 public class MbeansDescriptorsIntrospectionSource extends ModelerSource
41 {
42     private static Log log = LogFactory.getLog(MbeansDescriptorsIntrospectionSource.class);
43
44     Registry registry;
45     String JavaDoc location;
46     String JavaDoc type;
47     Object JavaDoc source;
48     List JavaDoc mbeans=new ArrayList JavaDoc();
49
50     public void setRegistry(Registry reg) {
51         this.registry=reg;
52     }
53
54     public void setLocation( String JavaDoc loc ) {
55         this.location=loc;
56     }
57
58     /** Used if a single component is loaded
59      *
60      * @param type
61      */

62     public void setType( String JavaDoc type ) {
63        this.type=type;
64     }
65
66     public void setSource( Object JavaDoc source ) {
67         this.source=source;
68     }
69
70     public List JavaDoc loadDescriptors( Registry registry, String JavaDoc location,
71                                  String JavaDoc type, Object JavaDoc source)
72             throws Exception JavaDoc
73     {
74         setRegistry(registry);
75         setLocation(location);
76         setType(type);
77         setSource(source);
78         execute();
79         return mbeans;
80     }
81
82     public void execute() throws Exception JavaDoc {
83         if( registry==null ) registry=Registry.getRegistry();
84         try {
85             ManagedBean managed=createManagedBean(registry, null, (Class JavaDoc)source, type);
86             if( managed==null ) return;
87             managed.setName( type );
88
89             mbeans.add(managed);
90
91         } catch( Exception JavaDoc ex ) {
92             log.error( "Error reading descriptors ", ex);
93         }
94     }
95
96
97
98     // ------------ Implementation for non-declared introspection classes
99

100     static Hashtable JavaDoc specialMethods=new Hashtable JavaDoc();
101     static {
102         specialMethods.put( "preDeregister", "");
103         specialMethods.put( "postDeregister", "");
104     }
105
106     private static String JavaDoc strArray[]=new String JavaDoc[0];
107     private static ObjectName JavaDoc objNameArray[]=new ObjectName JavaDoc[0];
108     // createMBean == registerClass + registerMBean
109

110     private static Class JavaDoc[] supportedTypes = new Class JavaDoc[] {
111         Boolean JavaDoc.class,
112         Boolean.TYPE,
113         Byte JavaDoc.class,
114         Byte.TYPE,
115         Character JavaDoc.class,
116         Character.TYPE,
117         Short JavaDoc.class,
118         Short.TYPE,
119         Integer JavaDoc.class,
120         Integer.TYPE,
121         Long JavaDoc.class,
122         Long.TYPE,
123         Float JavaDoc.class,
124         Float.TYPE,
125         Double JavaDoc.class,
126         Double.TYPE,
127         String JavaDoc.class,
128         strArray.getClass(),
129         BigDecimal JavaDoc.class,
130         BigInteger JavaDoc.class,
131         ObjectName JavaDoc.class,
132         objNameArray.getClass(),
133         java.io.File JavaDoc.class,
134     };
135     
136     /**
137      * Check if this class is one of the supported types.
138      * If the class is supported, returns true. Otherwise,
139      * returns false.
140      * @param ret The class to check
141      * @return boolean True if class is supported
142      */

143     private boolean supportedType(Class JavaDoc ret) {
144         for (int i = 0; i < supportedTypes.length; i++) {
145             if (ret == supportedTypes[i]) {
146                 return true;
147             }
148         }
149         if (isBeanCompatible(ret)) {
150             return true;
151         }
152         return false;
153     }
154
155     /**
156      * Check if this class conforms to JavaBeans specifications.
157      * If the class is conformant, returns true.
158      *
159      * @param javaType The class to check
160      * @return boolean True if the class is compatible.
161      */

162     protected boolean isBeanCompatible(Class JavaDoc javaType) {
163         // Must be a non-primitive and non array
164
if (javaType.isArray() || javaType.isPrimitive()) {
165             return false;
166         }
167
168         // Anything in the java or javax package that
169
// does not have a defined mapping is excluded.
170
if (javaType.getName().startsWith("java.") ||
171             javaType.getName().startsWith("javax.")) {
172             return false;
173         }
174
175         try {
176             javaType.getConstructor(new Class JavaDoc[]{});
177         } catch (java.lang.NoSuchMethodException JavaDoc e) {
178             return false;
179         }
180
181         // Make sure superclass is compatible
182
Class JavaDoc superClass = javaType.getSuperclass();
183         if (superClass != null &&
184             superClass != java.lang.Object JavaDoc.class &&
185             superClass != java.lang.Exception JavaDoc.class &&
186             superClass != java.lang.Throwable JavaDoc.class) {
187             if (!isBeanCompatible(superClass)) {
188                 return false;
189             }
190         }
191         return true;
192     }
193     
194     /**
195      * Process the methods and extract 'attributes', methods, etc
196      *
197      * @param realClass The class to process
198      * @param methods The methods to process
199      * @param attMap The attribute map (complete)
200      * @param getAttMap The readable attributess map
201      * @param setAttMap The settable attributes map
202      * @param invokeAttMap The invokable attributes map
203      */

204     private void initMethods(Class JavaDoc realClass,
205                              Method JavaDoc methods[],
206                              Hashtable JavaDoc attMap, Hashtable JavaDoc getAttMap,
207                              Hashtable JavaDoc setAttMap, Hashtable JavaDoc invokeAttMap)
208     {
209         for (int j = 0; j < methods.length; ++j) {
210             String JavaDoc name=methods[j].getName();
211
212             if( Modifier.isStatic(methods[j].getModifiers()))
213                 continue;
214             if( ! Modifier.isPublic( methods[j].getModifiers() ) ) {
215                 if( log.isDebugEnabled())
216                     log.debug("Not public " + methods[j] );
217                 continue;
218             }
219             if( methods[j].getDeclaringClass() == Object JavaDoc.class )
220                 continue;
221             Class JavaDoc params[]=methods[j].getParameterTypes();
222
223             if( name.startsWith( "get" ) && params.length==0) {
224                 Class JavaDoc ret=methods[j].getReturnType();
225                 if( ! supportedType( ret ) ) {
226                     if( log.isDebugEnabled() )
227                         log.debug("Unsupported type " + methods[j]);
228                     continue;
229                 }
230                 name=unCapitalize( name.substring(3));
231
232                 getAttMap.put( name, methods[j] );
233                 // just a marker, we don't use the value
234
attMap.put( name, methods[j] );
235             } else if( name.startsWith( "is" ) && params.length==0) {
236                 Class JavaDoc ret=methods[j].getReturnType();
237                 if( Boolean.TYPE != ret ) {
238                     if( log.isDebugEnabled() )
239                         log.debug("Unsupported type " + methods[j] + " " + ret );
240                     continue;
241                 }
242                 name=unCapitalize( name.substring(2));
243
244                 getAttMap.put( name, methods[j] );
245                 // just a marker, we don't use the value
246
attMap.put( name, methods[j] );
247
248             } else if( name.startsWith( "set" ) && params.length==1) {
249                 if( ! supportedType( params[0] ) ) {
250                     if( log.isDebugEnabled() )
251                         log.debug("Unsupported type " + methods[j] + " " + params[0]);
252                     continue;
253                 }
254                 name=unCapitalize( name.substring(3));
255                 setAttMap.put( name, methods[j] );
256                 attMap.put( name, methods[j] );
257             } else {
258                 if( params.length == 0 ) {
259                     if( specialMethods.get( methods[j].getName() ) != null )
260                         continue;
261                     invokeAttMap.put( name, methods[j]);
262                 } else {
263                     boolean supported=true;
264                     for( int i=0; i<params.length; i++ ) {
265                         if( ! supportedType( params[i])) {
266                             supported=false;
267                             break;
268                         }
269                     }
270                     if( supported )
271                         invokeAttMap.put( name, methods[j]);
272                 }
273             }
274         }
275     }
276
277     /**
278      * XXX Find if the 'className' is the name of the MBean or
279      * the real class ( I suppose first )
280      * XXX Read (optional) descriptions from a .properties, generated
281      * from source
282      * XXX Deal with constructors
283      *
284      * @param registry The Bean registry (not used)
285      * @param domain The bean domain (not used)
286      * @param realClass The class to analyze
287      * @param type The bean type
288      * @return ManagedBean The create MBean
289      */

290     public ManagedBean createManagedBean(Registry registry, String JavaDoc domain,
291                                          Class JavaDoc realClass, String JavaDoc type)
292     {
293         ManagedBean mbean= new ManagedBean();
294
295         Method JavaDoc methods[]=null;
296
297         Hashtable JavaDoc attMap=new Hashtable JavaDoc();
298         // key: attribute val: getter method
299
Hashtable JavaDoc getAttMap=new Hashtable JavaDoc();
300         // key: attribute val: setter method
301
Hashtable JavaDoc setAttMap=new Hashtable JavaDoc();
302         // key: operation val: invoke method
303
Hashtable JavaDoc invokeAttMap=new Hashtable JavaDoc();
304
305         methods = realClass.getMethods();
306
307         initMethods(realClass, methods, attMap, getAttMap, setAttMap, invokeAttMap );
308
309         try {
310
311             Enumeration JavaDoc en=attMap.keys();
312             while( en.hasMoreElements() ) {
313                 String JavaDoc name=(String JavaDoc)en.nextElement();
314                 AttributeInfo ai=new AttributeInfo();
315                 ai.setName( name );
316                 Method JavaDoc gm=(Method JavaDoc)getAttMap.get(name);
317                 if( gm!=null ) {
318                     //ai.setGetMethodObj( gm );
319
ai.setGetMethod( gm.getName());
320                     Class JavaDoc t=gm.getReturnType();
321                     if( t!=null )
322                         ai.setType( t.getName() );
323                 }
324                 Method JavaDoc sm=(Method JavaDoc)setAttMap.get(name);
325                 if( sm!=null ) {
326                     //ai.setSetMethodObj(sm);
327
Class JavaDoc t=sm.getParameterTypes()[0];
328                     if( t!=null )
329                         ai.setType( t.getName());
330                     ai.setSetMethod( sm.getName());
331                 }
332                 ai.setDescription("Introspected attribute " + name);
333                 if( log.isDebugEnabled()) log.debug("Introspected attribute " +
334                         name + " " + gm + " " + sm);
335                 if( gm==null )
336                     ai.setReadable(false);
337                 if( sm==null )
338                     ai.setWriteable(false);
339                 if( sm!=null || gm!=null )
340                     mbean.addAttribute(ai);
341             }
342
343             en=invokeAttMap.keys();
344             while( en.hasMoreElements() ) {
345                 String JavaDoc name=(String JavaDoc)en.nextElement();
346                 Method JavaDoc m=(Method JavaDoc)invokeAttMap.get(name);
347                 if( m!=null && name != null ) {
348                     OperationInfo op=new OperationInfo();
349                     op.setName(name);
350                     op.setReturnType(m.getReturnType().getName());
351                     op.setDescription("Introspected operation " + name);
352                     Class JavaDoc parms[]=m.getParameterTypes();
353                     for(int i=0; i<parms.length; i++ ) {
354                         ParameterInfo pi=new ParameterInfo();
355                         pi.setType(parms[i].getName());
356                         pi.setName( "param" + i);
357                         pi.setDescription("Introspected parameter param" + i);
358                         op.addParameter(pi);
359                     }
360                     mbean.addOperation(op);
361                 } else {
362                     log.error("Null arg " + name + " " + m );
363                 }
364             }
365
366             Constructor JavaDoc[] constructors = realClass.getConstructors();
367             for(int i=0;i<constructors.length;i++) {
368                 ConstructorInfo info = new ConstructorInfo();
369                 String JavaDoc className = realClass.getName();
370                 int nIndex = -1;
371                 if((nIndex = className.lastIndexOf('.'))!=-1) {
372                     className = className.substring(nIndex+1);
373                 }
374                 info.setName(className);
375                 info.setDescription(constructors[i].getName());
376                 Class JavaDoc classes[] = constructors[i].getParameterTypes();
377                 for(int j=0;j<classes.length;j++) {
378                     ParameterInfo pi = new ParameterInfo();
379                     pi.setType(classes[j].getName());
380                     pi.setName("param" + j);
381                     pi.setDescription("Introspected parameter param" + j);
382                     info.addParameter(pi);
383                 }
384                 mbean.addConstructor(info);
385             }
386             
387             if( log.isDebugEnabled())
388                 log.debug("Setting name: " + type );
389             mbean.setName( type );
390
391             return mbean;
392         } catch( Exception JavaDoc ex ) {
393             ex.printStackTrace();
394             return null;
395         }
396     }
397
398
399     // -------------------- Utils --------------------
400
/**
401      * Converts the first character of the given
402      * String into lower-case.
403      *
404      * @param name The string to convert
405      * @return String
406      */

407     private static String JavaDoc unCapitalize(String JavaDoc name) {
408         if (name == null || name.length() == 0) {
409             return name;
410         }
411         char chars[] = name.toCharArray();
412         chars[0] = Character.toLowerCase(chars[0]);
413         return new String JavaDoc(chars);
414     }
415
416 }
417
418 // End of class: MbeanDescriptorsIntrospectionSource
419
Popular Tags