KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > util > modeler > modules > MbeansDescriptorsIntrospectionSource


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

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

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

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

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

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

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

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

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