KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > util > mx > DynamicMBeanProxy


1
2
3 /*
4  * The contents of this file are subject to the terms
5  * of the Common Development and Distribution License
6  * (the "License"). You may not use this file except
7  * in compliance with the License.
8  *
9  * You can obtain a copy of the license at
10  * glassfish/bootstrap/legal/CDDLv1.0.txt or
11  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
12  * See the License for the specific language governing
13  * permissions and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL
16  * HEADER in each file and include the License file at
17  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
18  * add the following below this CDDL HEADER, with the
19  * fields enclosed by brackets "[]" replaced with your
20  * own identifying information: Portions Copyright [yyyy]
21  * [name of copyright owner]
22  *
23  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24  *
25  * Portions Copyright Apache Software Foundation.
26  */

27
28 package org.apache.tomcat.util.mx;
29
30 import java.io.*;
31 import java.net.*;
32 import java.lang.reflect.*;
33 import java.util.*;
34 import javax.management.*;
35
36 /**
37  * DynamicMBean implementation using introspection to manage any
38  * component that follows the bean/ant/Interceptor/Valve/Jk2 patterns.
39  *
40  * The class will wrap any component conforming to those patterns.
41  *
42  * @deprecated The same functionality ( and more ) is now available in
43  * commons-modeler
44  * @author Costin Manolache
45  */

46 public class DynamicMBeanProxy implements DynamicMBean {
47     Object JavaDoc real;
48     String JavaDoc name;
49     
50     Method methods[]=null;
51
52     Hashtable attMap=new Hashtable();
53
54     // key: attribute val: getter method
55
Hashtable getAttMap=new Hashtable();
56
57     // key: attribute val: setter method
58
Hashtable setAttMap=new Hashtable();
59
60     // key: operation val: invoke method
61
Hashtable invokeAttMap=new Hashtable();
62
63     static MBeanServer mserver=null;
64
65     static Hashtable instances=new Hashtable();
66     
67     /** Create a Dynamic proxy, using introspection to manage a
68      * real tomcat component.
69      */

70     public DynamicMBeanProxy() {
71         
72     }
73
74     public void setName(String JavaDoc name ) {
75         this.name=name;
76     }
77
78     public String JavaDoc getName() {
79         if( name!=null ) return name;
80
81         if( real==null ) return null;
82
83         name=generateName(real.getClass());
84         return name;
85     }
86
87     /** If a name was not provided, generate a name based on the
88      * class name and a sequence number.
89      */

90     public static String JavaDoc generateName(Class JavaDoc realClass) {
91         String JavaDoc name=realClass.getName();
92         name=name.substring( name.lastIndexOf( ".") + 1 );
93         Integer JavaDoc iInt=(Integer JavaDoc)instances.get(name );
94         int seq=0;
95         if( iInt!= null ) {
96             seq=iInt.intValue();
97             seq++;
98             instances.put( name, new Integer JavaDoc( seq ));
99         } else {
100             instances.put( name, new Integer JavaDoc( 0 ));
101         }
102         return "name=" + name + ",seq=" + seq;
103     }
104
105     public static String JavaDoc createMBean( Object JavaDoc proxy, String JavaDoc domain, String JavaDoc name ) {
106         try {
107             DynamicMBeanProxy mbean=new DynamicMBeanProxy();
108             mbean.setReal( proxy );
109             if( name!=null ) {
110                 mbean.setName( name );
111             } else {
112                 mbean.setName( generateName( proxy.getClass() ));
113             }
114
115             return mbean.registerMBean( domain );
116         } catch( Throwable JavaDoc t ) {
117             log.error( "Error creating mbean ", t );
118             return null;
119         }
120     }
121     
122     public String JavaDoc registerMBean( String JavaDoc domain ) {
123         try {
124             // XXX use aliases, suffix only, proxy.getName(), etc
125
String JavaDoc fullName=domain + ": " + getName();
126             ObjectName oname=new ObjectName( fullName );
127
128             if( getMBeanServer().isRegistered( oname )) {
129                 log.info("Unregistering " + oname );
130                 getMBeanServer().unregisterMBean( oname );
131             }
132             getMBeanServer().registerMBean( this, oname );
133             return fullName;
134         } catch( Throwable JavaDoc t ) {
135             log.error( "Error creating mbean ", t );
136             return null;
137         }
138     }
139
140     public static void unregisterMBean( Object JavaDoc o, String JavaDoc name ) {
141         try {
142             ObjectName oname=new ObjectName( name );
143
144             getMBeanServer().unregisterMBean( oname );
145         } catch( Throwable JavaDoc t ) {
146             log.error( "Error unregistering mbean ", t );
147         }
148     }
149
150     public static MBeanServer getMBeanServer() {
151         if( mserver==null ) {
152             if( MBeanServerFactory.findMBeanServer(null).size() > 0 ) {
153                 mserver=(MBeanServer)MBeanServerFactory.findMBeanServer(null).get(0);
154             } else {
155                 mserver=MBeanServerFactory.createMBeanServer();
156             }
157         }
158         
159         return mserver;
160     }
161
162     private boolean supportedType( Class JavaDoc ret ) {
163         return ret == String JavaDoc.class ||
164             ret == Integer JavaDoc.class ||
165             ret == Integer.TYPE ||
166             ret == Long JavaDoc.class ||
167             ret == Long.TYPE ||
168             ret == java.io.File JavaDoc.class ||
169             ret == Boolean JavaDoc.class ||
170             ret == Boolean.TYPE
171             ;
172     }
173     
174     /** Set the managed object.
175      *
176      * @todo Read an XML ( or .properties ) file containing descriptions,
177      * generated from source comments
178      * @todo Also filter methods based on config ( hide methods/attributes )
179      * @todo Adapters for notifications ( Interceptor hooks, etc ).
180      */

181     public void setReal( Object JavaDoc realBean ) {
182         real=realBean;
183     }
184
185     private void init() {
186         if( methods!=null ) return;
187         methods = real.getClass().getMethods();
188         for (int j = 0; j < methods.length; ++j) {
189             String JavaDoc name=methods[j].getName();
190             
191             if( name.startsWith( "get" ) ) {
192                 if( methods[j].getParameterTypes().length != 0 ) {
193                     continue;
194                 }
195                 if( ! Modifier.isPublic( methods[j].getModifiers() ) ) {
196                     //log.debug("not public " + methods[j] );
197
continue;
198                 }
199                 Class JavaDoc ret=methods[j].getReturnType();
200                 if( ! supportedType( ret ) ) {
201                     if( log.isDebugEnabled() )
202                         log.debug("Unsupported " + ret );
203                     continue;
204                 }
205                 name=unCapitalize( name.substring(3));
206
207                 getAttMap.put( name, methods[j] );
208                 // just a marker, we don't use the value
209
attMap.put( name, methods[j] );
210             } else if( name.startsWith( "is" ) ) {
211                 // not used in our code. Add later
212

213             } else if( name.startsWith( "set" ) ) {
214                 Class JavaDoc params[]=methods[j].getParameterTypes();
215                 if( params.length != 1 ) {
216                     continue;
217                 }
218                 if( ! Modifier.isPublic( methods[j].getModifiers() ) )
219                     continue;
220                 Class JavaDoc ret=params[0];
221                 if( ! supportedType( ret ) ) {
222                     continue;
223                 }
224                 name=unCapitalize( name.substring(3));
225                 setAttMap.put( name, methods[j] );
226                 attMap.put( name, methods[j] );
227             } else {
228                 if( methods[j].getParameterTypes().length != 0 ) {
229                     continue;
230                 }
231                 if( methods[j].getDeclaringClass() == Object JavaDoc.class )
232                     continue;
233                 if( ! Modifier.isPublic( methods[j].getModifiers() ) )
234                     continue;
235                 invokeAttMap.put( name, methods[j]);
236             }
237         }
238     }
239
240     /**
241      * @todo Find if the 'className' is the name of the MBean or
242      * the real class ( I suppose first )
243      * @todo Read (optional) descriptions from a .properties, generated
244      * from source
245      * @todo Deal with constructors
246      *
247      */

248     public MBeanInfo getMBeanInfo() {
249         if( methods==null ) {
250             init();
251         }
252         try {
253             MBeanAttributeInfo attributes[]=new MBeanAttributeInfo[attMap.size()];
254
255             Enumeration en=attMap.keys();
256             int i=0;
257             while( en.hasMoreElements() ) {
258                 String JavaDoc name=(String JavaDoc)en.nextElement();
259                 attributes[i++]=new MBeanAttributeInfo(name, "Attribute " + name ,
260                                                        (Method)getAttMap.get(name),
261                                                        (Method)setAttMap.get(name));
262             }
263             
264             MBeanOperationInfo operations[]=new MBeanOperationInfo[invokeAttMap.size()];
265             
266             en=invokeAttMap.keys();
267             i=0;
268             while( en.hasMoreElements() ) {
269                 String JavaDoc name=(String JavaDoc)en.nextElement();
270                 Method m=(Method)invokeAttMap.get(name);
271                 if( m!=null && name != null ) {
272                     operations[i++]=new MBeanOperationInfo(name, m);
273                 } else {
274                     if (log.isDebugEnabled())
275                         log.debug("Null arg " + name + " " + m );
276                 }
277             }
278             
279             if( log.isDebugEnabled() )
280                 log.debug(real.getClass().getName() + " getMBeanInfo()");
281             
282             return new MBeanInfo( real.getClass().getName(), /* ??? */
283                                   "MBean for " + getName(),
284                                   attributes,
285                                   new MBeanConstructorInfo[0],
286                                   operations,
287                                   new MBeanNotificationInfo[0]);
288         } catch( Exception JavaDoc ex ) {
289             ex.printStackTrace();
290             return null;
291         }
292     }
293
294     static final Object JavaDoc[] NO_ARGS_PARAM=new Object JavaDoc[0];
295     
296     public Object JavaDoc getAttribute(String JavaDoc attribute)
297         throws AttributeNotFoundException, MBeanException, ReflectionException
298     {
299         if( methods==null ) init();
300         Method m=(Method)getAttMap.get( attribute );
301         if( m==null ) throw new AttributeNotFoundException(attribute);
302
303         try {
304             if( log.isDebugEnabled() )
305                 log.debug(real.getClass().getName() + " getAttribute " + attribute);
306             return m.invoke(real, NO_ARGS_PARAM );
307         } catch( IllegalAccessException JavaDoc ex ) {
308             ex.printStackTrace();
309             throw new MBeanException( ex );
310         } catch( InvocationTargetException ex1 ) {
311             ex1.printStackTrace();
312             throw new MBeanException( ex1 );
313         }
314     }
315     
316     public void setAttribute(Attribute attribute)
317         throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException
318     {
319         if( methods==null ) init();
320         // XXX Send notification !!!
321
Method m=(Method)setAttMap.get( attribute.getName() );
322         if( m==null ) throw new AttributeNotFoundException(attribute.getName());
323
324         try {
325             log.info(real.getClass().getName() + "setAttribute " + attribute.getName());
326             m.invoke(real, new Object JavaDoc[] { attribute.getValue() } );
327         } catch( IllegalAccessException JavaDoc ex ) {
328             ex.printStackTrace();
329             throw new MBeanException( ex );
330         } catch( InvocationTargetException ex1 ) {
331             ex1.printStackTrace();
332             throw new MBeanException( ex1 );
333         }
334     }
335     
336     /**
337      * Invoke a method. Only no param methods are supported at the moment
338      * ( init, start, execute, etc ) ( that's the most common pattern we have
339      * in tomcat/ant/etc )
340      *
341      * @todo Implement invoke for methods with more arguments.
342      */

343     public Object JavaDoc invoke(String JavaDoc method, Object JavaDoc[] arguments, String JavaDoc[] params)
344         throws MBeanException, ReflectionException
345     {
346         if( methods==null ) init();
347         Method m=(Method)invokeAttMap.get( method );
348         if( m==null ) return null;
349
350         try {
351             log.info(real.getClass().getName() + "invoke " + m.getName());
352             return m.invoke(real, NO_ARGS_PARAM );
353         } catch( IllegalAccessException JavaDoc ex ) {
354             throw new MBeanException( ex );
355         } catch( InvocationTargetException ex1 ) {
356             throw new MBeanException( ex1 );
357         }
358     }
359
360
361     // -------------------- Auxiliary methods --------------------
362

363     public AttributeList setAttributes(AttributeList attributes) {
364         Iterator attE=attributes.iterator();
365         while( attE.hasNext() ) {
366             Attribute att=(Attribute)attE.next();
367
368             try {
369                 setAttribute( att );
370             } catch( Exception JavaDoc ex ) {
371                 ex.printStackTrace();
372             }
373         }
374         return attributes;
375     }
376
377     public AttributeList getAttributes(String JavaDoc[] attributes) {
378         AttributeList al=new AttributeList();
379         if( attributes==null ) return null;
380         
381         for( int i=0; i<attributes.length; i++ ) {
382             try {
383                 Attribute att=new Attribute( attributes[i], getAttribute( attributes[i] ));
384                 al.add( att );
385             } catch( Exception JavaDoc ex ) {
386                 ex.printStackTrace();
387             }
388         }
389         return al;
390     }
391     
392
393     // -------------------- Utils --------------------
394

395     public static String JavaDoc unCapitalize(String JavaDoc name) {
396     if (name == null || name.length() == 0) {
397         return name;
398     }
399     char chars[] = name.toCharArray();
400     chars[0] = Character.toLowerCase(chars[0]);
401     return new String JavaDoc(chars);
402     }
403
404     private static com.sun.org.apache.commons.logging.Log log=
405         com.sun.org.apache.commons.logging.LogFactory.getLog( DynamicMBeanProxy.class );
406
407 }
408
Popular Tags