KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > mbeanserver > StandardMetaDataImpl


1 /*
2  * @(#)StandardMetaDataImpl.java 1.24 05/05/27
3  *
4  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.jmx.mbeanserver;
9
10
11
12 // java import
13

14 import java.lang.reflect.Method JavaDoc;
15 import java.lang.reflect.Constructor JavaDoc;
16 import java.lang.reflect.InvocationTargetException JavaDoc;
17 import java.lang.ref.WeakReference JavaDoc;
18 import java.security.AccessController JavaDoc;
19 import java.security.PrivilegedAction JavaDoc;
20 import java.util.Hashtable JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.io.PrintWriter JavaDoc;
23 import java.io.StringWriter JavaDoc;
24
25 // RI import
26
import javax.management.* ;
27 import com.sun.jmx.trace.Trace;
28 import com.sun.jmx.mbeanserver.GetPropertyAction;
29
30 /**
31  * The MetaData class provides local access to the metadata service in
32  * an agent.
33  *
34  * @since 1.5
35  * @since.unbundled JMX RI 1.2
36  */

37 class StandardMetaDataImpl extends BaseMetaDataImpl {
38
39
40     /** The name of this class to be used for tracing */
41     private final static String JavaDoc dbgTag = "StandardMetaDataImpl";
42     
43     /**
44      * Cache of MBeanInfo objects.
45      */

46     private static java.util.Map JavaDoc mbeanInfoCache =
47     new java.util.WeakHashMap JavaDoc();
48     
49     /**
50      * Cache of MBean Interface objects.
51      */

52     private static java.util.Map JavaDoc mbeanInterfaceCache =
53     new java.util.WeakHashMap JavaDoc();
54
55     /**
56      * True if RuntimeExceptions from getters, setters, and operations
57      * should be wrapped in RuntimeMBeanException. We do not have
58      * similar logic for Errors because DynamicMetaDataImpl does not
59      * re-wrap RuntimeErrorException as it would
60      * RuntimeMBeanException.
61      */

62     private final boolean wrapRuntimeExceptions;
63
64     /**
65      * objects maps from primitive classes to primitive object classes.
66      */

67     // private static Hashtable primitiveobjects = new Hashtable();
68
// {
69
// primitiveobjects.put(Boolean.TYPE, getClass("java.lang.Boolean"));
70
// primitiveobjects.put(Character.TYPE, getClass("java.lang.Character"));
71
// primitiveobjects.put(Byte.TYPE, getClass("java.lang.Byte"));
72
// primitiveobjects.put(Short.TYPE, getClass("java.lang.Short"));
73
// primitiveobjects.put(Integer.TYPE, getClass("java.lang.Integer"));
74
// primitiveobjects.put(Long.TYPE, getClass("java.lang.Long"));
75
// primitiveobjects.put(Float.TYPE, getClass("java.lang.Float"));
76
// primitiveobjects.put(Double.TYPE, getClass("java.lang.Double"));
77
// }
78
private final static Hashtable JavaDoc primitiveClasses = new Hashtable JavaDoc(8);
79     {
80         primitiveClasses.put(Boolean.TYPE.toString(), Boolean.TYPE);
81         primitiveClasses.put(Character.TYPE.toString(), Character.TYPE);
82         primitiveClasses.put(Byte.TYPE.toString(), Byte.TYPE);
83         primitiveClasses.put(Short.TYPE.toString(), Short.TYPE);
84         primitiveClasses.put(Integer.TYPE.toString(), Integer.TYPE);
85         primitiveClasses.put(Long.TYPE.toString(), Long.TYPE);
86         primitiveClasses.put(Float.TYPE.toString(), Float.TYPE);
87         primitiveClasses.put(Double.TYPE.toString(), Double.TYPE);
88      }
89
90
91
92     /**
93      * Creates a Metadata Service.
94      */

95     public StandardMetaDataImpl() {
96         this(true);
97     }
98
99     StandardMetaDataImpl(boolean wrapRuntimeExceptions) {
100     this.wrapRuntimeExceptions = wrapRuntimeExceptions;
101     }
102
103     /**
104      * Builds the MBeanInfo from the given concrete MBean class.
105      * @param c The concrete MBean class from which the MBeanInfo
106      * must be built.
107      *
108      * @exception NotCompliantMBeanException if the given class
109      * is not MBean compliant.
110      * @return the MBeanInfo built from class <var>c</var>, or null
111      * if class <var>c</var> implements
112      * {@link javax.management.DynamicMBean}
113      */

114     public synchronized MBeanInfo buildMBeanInfo(Class JavaDoc c)
115     throws NotCompliantMBeanException {
116     return Introspector.testCompliance(c);
117     }
118
119     /**
120      * Builds the MBeanInfo from the given concrete MBean class,
121      * using the given <var>mbeanInterface</var> as Management Interface.
122      *
123      * @param c The concrete MBean class from which the MBeanInfo
124      * must be built.
125      * @param mbeanInterface The management interface of the MBean.
126      * If <code>null</code>, will use the regular design pattern
127      * to determine the management interface.
128      * @exception NotCompliantMBeanException if the given class and interface
129      * are not MBean compliant. Does not enforce that if class <var>c</var>
130      * is "X", then interface <var>mbeanInterface</var> is "XMBean".
131      * @return the MBeanInfo built from class <var>c</var>, according
132      * to interface <var>mbeanInterface</var>. Does not check whether
133      * class <var>c</var> implements {@link javax.management.DynamicMBean}.
134      **/

135     public synchronized
136     MBeanInfo buildMBeanInfo(Class JavaDoc c, Class JavaDoc mbeanInterface)
137     throws NotCompliantMBeanException {
138     return Introspector.testCompliance(c,mbeanInterface);
139     }
140
141     /**
142      * This methods tests if the MBean is JMX compliant
143      */

144     public synchronized void testCompliance(Class JavaDoc c)
145     throws NotCompliantMBeanException {
146     // ------------------------------
147
// ------------------------------
148

149     final MBeanInfo mbeanInfo = buildMBeanInfo(c);
150     final Class JavaDoc mbeanInterface = Introspector.getMBeanInterface(c);
151     cacheMBeanInfo(c,mbeanInterface,mbeanInfo);
152     }
153     
154     /**
155      * This methods tests if the MBean is JMX compliant.
156      * <li>It does not enforce that if c="X", mbeanInterface="XMBean".</li>
157      * <li>It does not check whether c is a DynamicMBean</li>
158      */

159     public synchronized void testCompliance(Class JavaDoc c, Class JavaDoc mbeanInterface)
160     throws NotCompliantMBeanException {
161     // ------------------------------
162
// ------------------------------
163

164     final MBeanInfo mbeanInfo =
165         buildMBeanInfo(c,mbeanInterface);
166     if (mbeanInterface == null)
167         mbeanInterface = Introspector.getStandardMBeanInterface(c);
168     cacheMBeanInfo(c,mbeanInterface,mbeanInfo);
169     }
170
171     /**
172      * This methods returns the MBean interface of an MBean
173      */

174     public Class JavaDoc getMBeanInterfaceFromClass(Class JavaDoc c) {
175     final Class JavaDoc itf = getCachedMBeanInterface(c);
176     if (itf != null) return itf;
177     synchronized (this) {
178         return Introspector.getMBeanInterface(c);
179     }
180     }
181
182     /**
183      * This methods analizes the passed MBean class and
184      * returns the default MBean interface according to JMX patterns.
185      */

186     public Class JavaDoc getStandardMBeanInterface(Class JavaDoc c) {
187     synchronized (this) {
188         return Introspector.getStandardMBeanInterface(c);
189     }
190     }
191
192     /**
193      * This method discovers the attributes and operations that an MBean
194      * exposes for management.
195      *
196      * @param beanClass The class to be analyzed.
197      *
198      * @return An instance of MBeanInfo allowing to retrieve all methods
199      * and operations of this class.
200      *
201      * @exception IntrospectionException if an exception occurs during
202      * introspection.
203      * @exception NotCompliantMBeanException if the MBean class is not
204      * MBean compliant.
205      *
206      */

207     public MBeanInfo getMBeanInfoFromClass(Class JavaDoc beanClass)
208     throws IntrospectionException, NotCompliantMBeanException {
209
210     // Check the mbean information cache.
211
MBeanInfo bi = getCachedMBeanInfo(beanClass);
212
213     // Make an independent copy of the MBeanInfo.
214
if (bi != null) return (MBeanInfo) bi.clone() ;
215
216     // We don't have have any MBeanInfo for that class yet.
217
// => test compliance.
218
testCompliance(beanClass);
219
220     bi = getCachedMBeanInfo(beanClass);;
221
222     // Make an independent copy of the MBeanInfo.
223
if (bi != null) return (MBeanInfo) bi.clone() ;
224     return bi;
225     }
226        
227
228     //---------------------------------------------------------------------
229
//
230
// From the MetaData interface
231
//
232
//---------------------------------------------------------------------
233

234     public String JavaDoc getMBeanClassName(Object JavaDoc moi)
235     throws IntrospectionException, NotCompliantMBeanException {
236     return moi.getClass().getName();
237     }
238
239     public MBeanInfo getMBeanInfo(Object JavaDoc moi)
240     throws IntrospectionException {
241     try {
242         final MBeanInfo mbi = getMBeanInfoFromClass(moi.getClass());
243         return new MBeanInfo(mbi.getClassName(), mbi.getDescription(),
244                  mbi.getAttributes(),
245                  mbi.getConstructors(),
246                  mbi.getOperations(),
247                  findNotifications(moi));
248     } catch (NotCompliantMBeanException x) {
249         debugX("getMBeanInfo",x);
250         throw new IntrospectionException("Can't build MBeanInfo for "+
251                          moi.getClass().getName());
252     }
253     }
254
255     public Object JavaDoc getAttribute(Object JavaDoc instance, String JavaDoc attribute)
256     throws MBeanException, AttributeNotFoundException,
257            ReflectionException {
258
259         Class JavaDoc mbeanClass = getMBeanInterfaceFromInstance(instance);
260     if (isDebugOn()) {
261         debug("getAttribute","MBean Class is " + instance.getClass());
262         debug("getAttribute","MBean Interface is " + mbeanClass);
263     }
264
265         return getAttribute(instance, attribute, mbeanClass);
266     }
267
268  
269     public AttributeList getAttributes(Object JavaDoc instance, String JavaDoc[] attributes)
270     throws ReflectionException {
271
272     final Class JavaDoc mbeanClass =
273         getMBeanInterfaceFromInstance(instance);
274
275     if (isDebugOn()) {
276         debug("getAttributes","MBean Class is " + instance.getClass());
277         debug("getAttributes","MBean Interface is " + mbeanClass);
278     }
279
280         if (attributes == null) {
281             throw new RuntimeOperationsException(new
282         IllegalArgumentException JavaDoc("Attributes cannot be null"),
283                 "Exception occured trying to invoke the getter on the MBean");
284         }
285
286     // Go through the list of attributes
287
//
288
final int maxLimit = attributes.length;
289     final AttributeList result = new AttributeList(maxLimit);
290
291         for (int i=0;i<maxLimit;i++) {
292             final String JavaDoc elmt = (String JavaDoc)attributes[i];
293             try {
294                 final Object JavaDoc value =
295             getAttribute(instance, elmt, mbeanClass);
296                 result.add(new Attribute(elmt, value));
297             } catch (Exception JavaDoc excep) {
298                 if (isDebugOn()) {
299                     debug("getAttributes", "Object= " + instance +
300               ", Attribute=" + elmt + " failed: " + excep);
301                 }
302             }
303         }
304         return result;
305     }
306
307
308     public AttributeList setAttributes(Object JavaDoc instance,
309                        AttributeList attributes)
310     throws ReflectionException {
311     
312     final Class JavaDoc objClass = instance.getClass();
313         final Class JavaDoc mbeanClass = getMBeanInterfaceFromInstance(instance);
314     final ClassLoader JavaDoc aLoader = objClass.getClassLoader();
315     
316     if (isDebugOn()) {
317         debug("setAttributes","MBean Class is " + instance.getClass());
318         debug("setAttributes","MBean Interface is " + mbeanClass);
319     }
320
321     if (attributes == null) return new AttributeList();
322
323     final AttributeList result = new AttributeList(attributes.size());
324
325     // Go through the list of attributes
326
for (final Iterator JavaDoc i = attributes.iterator(); i.hasNext();) {
327             final Attribute attr = (Attribute) i.next();
328             final String JavaDoc id = attr.getName();
329             final Object JavaDoc value = attr.getValue();
330             try {
331                 final Object JavaDoc newValue =
332             setAttribute(instance, attr, mbeanClass);
333                 if (isTraceOn()) {
334                     trace("setAttributes", "Updating the list\n");
335                 }
336                 result.add(new Attribute(id, newValue));
337             } catch (Exception JavaDoc excep) {
338                 if (isDebugOn()) {
339                     debug("setAttributes", "Unexpected exception occured: " +
340               excep.getClass().getName());
341                 }
342             }
343         }
344         return result;
345
346     }
347     
348     public Object JavaDoc setAttribute(Object JavaDoc instance, Attribute attribute)
349     throws AttributeNotFoundException, InvalidAttributeValueException,
350            MBeanException, ReflectionException {
351
352         final Class JavaDoc mbeanClass =
353         getMBeanInterfaceFromInstance(instance);
354
355     if (isDebugOn()) {
356         debug("setAttribute","MBean Class is " + instance.getClass());
357         debug("setAttribute","MBean Interface is " + mbeanClass);
358     }
359
360     return setAttribute(instance,attribute,mbeanClass);
361     }
362
363     public Object JavaDoc invoke(Object JavaDoc instance, String JavaDoc operationName,
364              Object JavaDoc params[], String JavaDoc signature[])
365     throws MBeanException, ReflectionException {
366
367         if (operationName == null) {
368         final RuntimeException JavaDoc r =
369           new IllegalArgumentException JavaDoc("Operation name cannot be null");
370             throw new RuntimeOperationsException(r,
371               "Exception occured trying to invoke the operation on the MBean");
372         }
373
374     final Class JavaDoc objClass = instance.getClass();
375         final Class JavaDoc mbeanClass = getMBeanInterfaceFromInstance(instance);
376     final ClassLoader JavaDoc aLoader = objClass.getClassLoader();
377
378     if (isDebugOn()) {
379         debug("invoke","MBean Class is " + instance.getClass());
380         debug("invoke","MBean Interface is " + mbeanClass);
381     }
382
383         // Build the signature of the method
384
//
385
final Class JavaDoc[] tab =
386         ((signature == null)?null:
387          findSignatureClasses(signature,aLoader));
388     
389         // Query the metadata service to get the right method
390
//
391
Method JavaDoc mth= findMethod(mbeanClass, operationName, tab);
392         
393         if (mth == null) {
394             if (isTraceOn()) {
395                 trace("invoke", operationName + " not found in class " +
396               mbeanClass.getName());
397             }
398             throw new ReflectionException(
399                   new NoSuchMethodException JavaDoc(operationName),
400                           "The operation with name " + operationName +
401               " could not be found");
402         }
403
404         // Make it impossible to call getters and setters through invoke()
405
//
406
forbidInvokeGetterSetter(mth, operationName);
407
408         // invoke the method
409
if (isTraceOn()) {
410             trace("invoke", "Invoking " + operationName);
411         }
412         Object JavaDoc result=null;
413         try {
414             result= mth.invoke(instance, params);
415         } catch (IllegalAccessException JavaDoc e) {
416         debugX("invoke",e);
417             throw new ReflectionException(e, "IllegalAccessException" +
418            " occured trying to invoke operation " + operationName);
419         } catch (RuntimeException JavaDoc e) {
420         debugX("invoke",e);
421             throw new RuntimeOperationsException(e, "RuntimeException" +
422                    " occured trying to invoke operation " + operationName);
423         } catch (InvocationTargetException JavaDoc e) {
424             // Wrap the exception.
425
Throwable JavaDoc t = e.getTargetException();
426         debugX("invoke",t);
427             if (t instanceof RuntimeException JavaDoc) {
428         final String JavaDoc msg = "RuntimeException thrown in operation " +
429             operationName;
430         throw wrapRuntimeException((RuntimeException JavaDoc) t, msg);
431             } else if (t instanceof Error JavaDoc) {
432                 throw new RuntimeErrorException((Error JavaDoc) t,
433                    "Error thrown in operation " + operationName);
434             } else {
435                 throw new MBeanException((Exception JavaDoc) t,
436                    "Exception thrown in operation " + operationName);
437             }
438         }
439         if (isTraceOn()) {
440             trace("invoke", "Send the result");
441         }
442         return (result);
443     }
444
445     private static boolean startsWithAndHasMore(String JavaDoc s, String JavaDoc prefix) {
446     return (s.startsWith(prefix) && s.length() > prefix.length());
447     }
448
449     private static void forbidInvokeGetterSetter(Method JavaDoc mth,
450                          String JavaDoc operationName)
451         throws ReflectionException {
452
453         final Class JavaDoc argTypes[] = mth.getParameterTypes();
454         final Class JavaDoc resultType = mth.getReturnType();
455         final int argCount = argTypes.length;
456
457     boolean isInvokeGetterSetter = false;
458
459     switch (argCount) {
460     case 0: // might be a getter
461
if ((startsWithAndHasMore(operationName, "get") &&
462          resultType != Void.TYPE) ||
463         (startsWithAndHasMore(operationName, "is") &&
464          resultType == Boolean.TYPE)) {
465         // Operation is a getter
466
isInvokeGetterSetter = true;
467         }
468         break;
469
470     case 1: // might be a setter
471
if (startsWithAndHasMore(operationName, "set") &&
472         resultType == Void.TYPE) {
473         // Operation is a setter
474
isInvokeGetterSetter = true;
475         }
476         break;
477     }
478
479     if (isInvokeGetterSetter) {
480         boolean allow;
481         try {
482         GetPropertyAction getProp =
483             new GetPropertyAction("jmx.invoke.getters");
484         allow = (AccessController.doPrivileged(getProp) != null);
485         } catch (SecurityException JavaDoc e) {
486         // too bad, don't allow it
487
allow = false;
488         }
489         if (!allow) {
490         final String JavaDoc msg =
491             "Cannot invoke getter or setter (" + operationName +
492             ") as operation unless jmx.invoke.getters property is set";
493         final Exception JavaDoc nested =
494             new NoSuchMethodException JavaDoc(operationName);
495         throw new ReflectionException(nested, msg);
496         }
497     }
498     }
499
500     public boolean isInstanceOf(Object JavaDoc instance, String JavaDoc className)
501     throws ReflectionException {
502     
503     final Class JavaDoc c =
504         findClass(className, instance.getClass().getClassLoader());
505
506     return c.isInstance(instance);
507     }
508
509    /**
510     * This methods returns the MBean interface of the given MBean
511     * instance.
512     * <p>It does so by calling
513     * <code>getMBeanInterfaceFromClass(instance.getClass());</code>
514     * @param instance the MBean instance.
515     */

516     Class JavaDoc getMBeanInterfaceFromInstance(Object JavaDoc instance) {
517     if (instance == null) return null;
518     return getMBeanInterfaceFromClass(instance.getClass());
519     }
520
521     /**
522      * Cache the MBeanInfo and MBean interface obtained for class
523      * <var>c</var>.
524      * <p>This method is called by <code>testCompliance(...)</code>
525      * after compliance is successfully verified. It uses two
526      * {@link java.util.WeakHashMap WeakHashMaps} - one for the
527      * MBeanInfo, one for the MBeanInterface, with calss <var>c</var>
528      * as the key.
529      *
530      * @param c The concrete MBean class from which the MBeanInfo
531      * was be built.
532      *
533      * @param mbeanInterface The management interface of the MBean.
534      * Note that caching will not work if two MBeans of the same
535      * class can have different mbeanInterface's. If you want
536      * to use caching nonetheless, you will have to
537      * to do it by redefining the method
538      * {@link #getMBeanInterfaceFromInstance(java.lang.Object)
539      * getMBeanInterfaceFromInstance()}.
540      * @param info The MBeanInfo obtained from class <var>c</var> using
541      * interface <var>mbeanInterface</var>.
542      *
543      **/

544     void cacheMBeanInfo(Class JavaDoc c, Class JavaDoc mbeanInterface,
545                   MBeanInfo info)
546     throws NotCompliantMBeanException {
547     if (info != null) {
548         synchronized (mbeanInfoCache) {
549         if (mbeanInfoCache.get(c) == null) {
550             mbeanInfoCache.put(c, info);
551         }
552         }
553     }
554     if (mbeanInterface != null) {
555         synchronized (mbeanInterfaceCache) {
556         if ((mbeanInterfaceCache.get(c) == null) || (((WeakReference JavaDoc)mbeanInterfaceCache.get(c)).get() == null)) {
557             mbeanInterfaceCache.put(c, new WeakReference JavaDoc(mbeanInterface));
558         }
559         }
560     }
561     }
562   
563     /**
564      * Returns the MBean interface that was cached for class <var>c</var>.
565      * @param c The concrete MBean class.
566      * @return The cached MBean interface if found, null otherwise.
567      **/

568     Class JavaDoc getCachedMBeanInterface(Class JavaDoc c) {
569     synchronized (mbeanInterfaceCache) {
570         return (Class JavaDoc)(((WeakReference JavaDoc)mbeanInterfaceCache.get(c)).get());
571     }
572     }
573     
574     /**
575      * Returns the MBeanInfo that was cached for class <var>c</var>.
576      * @param c The concrete MBean class.
577      * @return The cached MBeanInfo if found, null otherwise.
578      **/

579     MBeanInfo getCachedMBeanInfo(Class JavaDoc c) {
580         synchronized (mbeanInfoCache) {
581         return (MBeanInfo)mbeanInfoCache.get(c);
582     }
583     }
584
585     /**
586      * Find a class using the specified ClassLoader.
587      **/

588     Class JavaDoc findClass(String JavaDoc className, ClassLoader JavaDoc loader)
589     throws ReflectionException {
590     return MBeanInstantiatorImpl.loadClass(className,
591                            loader);
592     }
593
594     /**
595      * Find the classes from a signature using the specified ClassLoader.
596      **/

597     Class JavaDoc[] findSignatureClasses(String JavaDoc[] signature,
598                        ClassLoader JavaDoc loader)
599     throws ReflectionException {
600     return ((signature == null)?null:
601         MBeanInstantiatorImpl.loadSignatureClasses(signature,loader));
602     }
603
604     /**
605      * Invoke getAttribute through reflection on a standard MBean instance.
606      **/

607     Object JavaDoc getAttribute(Object JavaDoc instance, String JavaDoc attribute,
608                   Class JavaDoc mbeanClass)
609     throws MBeanException, AttributeNotFoundException,
610            ReflectionException {
611
612         if (attribute == null) {
613         final RuntimeException JavaDoc r =
614         new IllegalArgumentException JavaDoc("Attribute name cannot be null");
615             throw new RuntimeOperationsException(r,
616                 "Exception occured trying to invoke the getter on the MBean");
617         }
618  
619     // Standard MBean: need to reflect...
620
Method JavaDoc meth = null;
621         meth = findGetter(mbeanClass, attribute);
622         if (meth == null) {
623         if (isTraceOn()) {
624         trace("getAttribute", "Cannot find getter for "+attribute+
625               " in class " + mbeanClass.getName());
626         }
627             throw new AttributeNotFoundException(attribute +
628                          " not accessible");
629         }
630
631         // Invoke the getter
632
if (isTraceOn()) {
633             trace("getAttribute", "Invoke callback");
634         }
635         Object JavaDoc result= null;
636         try {
637             result = meth.invoke(instance, (Object JavaDoc[]) null);
638         } catch (InvocationTargetException JavaDoc e) {
639             Throwable JavaDoc t = e.getTargetException();
640             if (t instanceof RuntimeException JavaDoc) {
641         debugX("getAttribute",t);
642         final String JavaDoc msg =
643             "RuntimeException thrown in the getter for the attribute "
644             + attribute;
645         throw wrapRuntimeException((RuntimeException JavaDoc) t, msg);
646             } else if (t instanceof Error JavaDoc) {
647         debugX("getAttribute",t);
648                 throw new RuntimeErrorException((Error JavaDoc) t ,
649           "Error thrown in the getter for the attribute " +
650                         attribute);
651             } else {
652         debugX("getAttribute",t);
653                 throw new MBeanException((Exception JavaDoc) t,
654           "Exception thrown in the getter for the attribute " +
655           attribute);
656             }
657         } catch (RuntimeException JavaDoc e) {
658         debugX("getAttribute",e);
659             throw new RuntimeOperationsException(e,
660                   "RuntimeException thrown trying to invoke the getter" +
661           " for the attribute " + attribute);
662         } catch (IllegalAccessException JavaDoc e) {
663         debugX("getAttribute",e);
664             throw new ReflectionException(e, "Exception thrown trying to" +
665                   " invoke the getter for the attribute " + attribute);
666         } catch (Error JavaDoc e) {
667         debugX("getAttribute",e);
668             throw new RuntimeErrorException((Error JavaDoc)e,
669           "Error thrown trying to invoke the getter " +
670           " for the attribute " + attribute);
671         }
672
673         if (isTraceOn()) {
674             trace("getAttribute", attribute + "= " + result + "\n");
675         }
676         return result;
677     }
678
679     /**
680      * Invoke setAttribute through reflection on a standard MBean instance.
681      **/

682     Object JavaDoc setAttribute(Object JavaDoc instance, Attribute attribute,
683                   Class JavaDoc mbeanClass)
684     throws AttributeNotFoundException, InvalidAttributeValueException,
685            MBeanException, ReflectionException {
686
687         if (attribute == null) {
688         final RuntimeException JavaDoc r =
689         new IllegalArgumentException JavaDoc("Attribute name cannot be null");
690             throw new RuntimeOperationsException(r,
691                 "Exception occured trying to invoke the setter on the MBean");
692         }
693  
694     final Class JavaDoc objClass = instance.getClass();
695     final ClassLoader JavaDoc aLoader = objClass.getClassLoader();
696
697         Object JavaDoc result = null;
698         final Object JavaDoc value = attribute.getValue();
699     final String JavaDoc attname = attribute.getName();
700
701         // Query the metadata service to get the appropriate setter
702
// of the object.
703
Method JavaDoc meth = null;
704
705     if (value == null) {
706         meth = findSetter(mbeanClass, attname);
707     } else {
708         meth = findSetter(mbeanClass, attname, value.getClass());
709     }
710         if (meth == null) {
711             // Check whether the type is a primitive one
712
Class JavaDoc primClass = findPrimForClass(value);
713        
714             if (primClass != null) {
715                 meth = findSetter(mbeanClass, attname, primClass);
716             }
717         }
718         if (meth == null) {
719             // Try to check if the attribute name does correspond to a
720
// valid property
721
meth= findSetter(mbeanClass, attname);
722         if (meth == null) {
723         if (isTraceOn()) {
724             trace("setAttribute", "Cannot find setter for "+attribute+
725               " in class " + mbeanClass.getName());
726         }
727                 throw new AttributeNotFoundException( attname +
728                               " not accessible");
729             } else {
730         final Object JavaDoc v = attribute.getValue();
731         if (v == null) {
732             throw new InvalidAttributeValueException("attribute= " +
733                                 attname + " value = null");
734         } else {
735             throw new InvalidAttributeValueException("attribute= " +
736                                 attname + " value = " + v);
737         }
738             }
739         }
740         // Invoke the setter
741
if (isTraceOn()) {
742             trace("setAttribute", "Invoking the set method for " +
743           attname);
744         }
745      
746         final Object JavaDoc[] values = new Object JavaDoc[1];
747         values[0] = value;
748
749         try {
750             result = meth.invoke(instance,values);
751         } catch (IllegalAccessException JavaDoc e) {
752         debugX("setAttribute",e);
753             // Wrap the exception.
754
throw new ReflectionException(e, "IllegalAccessException" +
755                           " occured trying to invoke the setter on the MBean");
756         } catch (InvocationTargetException JavaDoc e) {
757             Throwable JavaDoc t = e.getTargetException();
758         debugX("setAttribute",t);
759         if (t instanceof RuntimeException JavaDoc) {
760         final String JavaDoc msg =
761             "RuntimeException thrown in the setter for the attribute "
762             + attribute;
763         throw wrapRuntimeException((RuntimeException JavaDoc) t, msg);
764             } else if (t instanceof Error JavaDoc) {
765                 throw new RuntimeErrorException((Error JavaDoc) t,
766                            "Error thrown in the MBean's setter");
767             } else {
768                 throw new MBeanException((Exception JavaDoc) t,
769                            "Exception thrown in the MBean's setter");
770             }
771         }
772         if (isTraceOn()) {
773             trace("setAttribute", attname + "= " + value);
774         }
775         return value;
776     }
777
778
779     /**
780      * Returns the MBeanNotificationInfo of the MBeans that implement
781      * the NotificationBroadcaster interface.
782      */

783     MBeanNotificationInfo[] findNotifications(Object JavaDoc moi) {
784         
785         if (moi instanceof javax.management.NotificationBroadcaster JavaDoc) {
786             MBeanNotificationInfo[] mbn =
787         ((NotificationBroadcaster)moi).getNotificationInfo();
788             if (mbn == null) {
789                 return new MBeanNotificationInfo[0];
790             }
791             MBeanNotificationInfo[] result =
792         new MBeanNotificationInfo[mbn.length];
793             for (int i = 0; i < mbn.length; i++) {
794                 result[i] = (MBeanNotificationInfo) mbn[i].clone();
795             }
796             return result;
797         }
798         return new MBeanNotificationInfo[0];
799     }
800
801     /**
802      * Finds a specific method of an object.
803      * Returns the method or null if not found
804      */

805     public static Method JavaDoc findMethod(Class JavaDoc classObj, String JavaDoc name,
806                  Class JavaDoc parameterTypes[]) {
807     Method JavaDoc method=null;
808     try {
809         method= classObj.getMethod(name, parameterTypes);
810     } catch(Exception JavaDoc e) {
811         // OK: will return null.
812
}
813     
814     return method;
815     }
816     
817     /**
818      * Finds a specific method of an object without knowing the parameter
819      * types.
820      * Returns the method or null if not found
821      */

822     public static Method JavaDoc findMethod(Class JavaDoc classObj, String JavaDoc name) {
823     Method JavaDoc method = null ;
824     
825     try {
826         Method JavaDoc[] methods=classObj.getMethods();
827         int i = 0;
828         while ((i < methods.length) &&
829            !methods[i].getName().equals(name)) {
830         i++;
831         }
832         if (i < methods.length) {
833         method = methods[i];
834         }
835     } catch(Exception JavaDoc e) {
836         // OK: will return null.
837
}
838     return method;
839     }
840
841  
842     /**
843     * Finds a specific method of an object given the number of parameters.
844     * Returns the method or null if not found
845     */

846     public static Method JavaDoc findMethod(Class JavaDoc classObj, String JavaDoc name,
847                     int paramCount) {
848  
849     Method JavaDoc method = null;
850     try {
851             Method JavaDoc[] methods=classObj.getMethods();
852             int i = 0;
853             boolean found = false;
854             while ((i < methods.length) && !found) {
855                 found = methods[i].getName().equals(name);
856                 if (found) { // Now check if the number of parameters
857
found = (methods[i].getParameterTypes().length ==
858                  paramCount);
859                 }
860                 i++;
861             }
862             if (found) {
863                 method = methods[i-1] ; // Note i-1 !
864
}
865         } catch(Exception JavaDoc e) {
866         // OK: will return null;
867
}
868         return method;
869     }
870     
871    
872     /**
873      * Finds the getter of a specific attribute in an object.
874      * Returns the method for accessing the attributes, null otherwise
875      */

876     public static Method JavaDoc findGetter(Class JavaDoc classObj, String JavaDoc attribute) {
877     // Methods called "is" or "get" tout court are not getters
878
if (attribute.length() == 0)
879         return null;
880
881     // Look for a method T getX(), where T is not void
882

883     Method JavaDoc m = findMethod(classObj, "get" + attribute, null);
884     if (m != null && m.getReturnType() != void.class)
885         return m;
886
887
888     // Look for a method boolean isX()
889
// must not be any other type than "boolean", including not "Boolean"
890

891     m = findMethod(classObj, "is" + attribute, null);
892     if (m != null && m.getReturnType() == boolean.class)
893         return m;
894
895     return null;
896     }
897     
898    
899     /**
900      * Finds the setter of a specific attribute in an object.
901      * Returns the method for accessing the attribute, null otherwise
902      */

903     public static Method JavaDoc findSetter(Class JavaDoc classObj, String JavaDoc attribute,
904                     Class JavaDoc type) {
905
906     Method JavaDoc mth= findMethod(classObj, "set" + attribute, 1);
907     if (mth != null) {
908         Class JavaDoc[] pars = mth.getParameterTypes();
909         if (pars[0].isAssignableFrom(type)) {
910         return mth;
911         }
912     }
913     return null;
914     }
915
916     /**
917      * Finds the setter of a specific attribute without knowing its type.
918      * Returns the method for accessing the attribute, null otherwise
919      */

920     public static Method JavaDoc findSetter(Class JavaDoc classObj, String JavaDoc attribute) {
921     return findMethod(classObj, "set" + attribute, 1) ;
922     }
923       
924    /**
925     * Finds a specific constructor of a class
926     * Returns the requested constructor or null if not found
927     */

928     public static Constructor JavaDoc findConstructor(Class JavaDoc theClass,
929                           Class JavaDoc parameterTypes[]) {
930     // Get the list of methods
931
Constructor JavaDoc mth = null;
932     
933     try {
934         mth = theClass.getConstructor(parameterTypes);
935     } catch(Exception JavaDoc e) {
936         return null;
937     }
938     return mth;
939     }
940    
941     /**
942      * Get the class of the constructed type
943      * corresponding to the given primitive type
944      */

945     public static Class JavaDoc findClassForPrim(String JavaDoc primName) {
946     return (Class JavaDoc) primitiveClasses.get(primName);
947     }
948       
949     /**
950      * Get the class of the primitive type
951      * corresponding to the given constructed object.
952      */

953     public static Class JavaDoc findPrimForClass(Object JavaDoc value) {
954     if (value instanceof Boolean JavaDoc)
955         return Boolean.TYPE;
956     else if (value instanceof Character JavaDoc)
957         return Character.TYPE;
958     else if (value instanceof Byte JavaDoc)
959         return Byte.TYPE;
960     else if (value instanceof Short JavaDoc)
961         return Short.TYPE;
962     else if (value instanceof Integer JavaDoc)
963         return Integer.TYPE;
964     else if (value instanceof Long JavaDoc)
965      return Long.TYPE;
966     else if (value instanceof Float JavaDoc)
967         return Float.TYPE;
968     else if (value instanceof Double JavaDoc)
969         return Double.TYPE;
970     return null;
971     }
972
973     /**
974      * Converts the array of classes to an array of class signatures.
975      */

976     static String JavaDoc[] findSignatures(Class JavaDoc[] clz) {
977         String JavaDoc signers[] = new String JavaDoc[clz.length];
978         for (int i = 0; i < clz.length; i++) {
979             signers[i] = findSignature(clz[i]);
980         }
981         return signers;
982     }
983     
984     /**
985      * Converts the class to a class signature.
986      */

987     static String JavaDoc findSignature(Class JavaDoc clz) {
988         return clz.getName();
989     }
990
991     private RuntimeException JavaDoc wrapRuntimeException(RuntimeException JavaDoc re,
992                           String JavaDoc msg) {
993     if (wrapRuntimeExceptions)
994         return new RuntimeMBeanException(re, msg);
995     else
996         return re;
997     }
998     
999
1000    // TRACES & DEBUG
1001
//---------------
1002

1003    private static boolean isTraceOn() {
1004        return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER);
1005    }
1006
1007    private static void trace(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
1008        Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER, clz, func, info);
1009    }
1010    
1011    private static void trace(String JavaDoc func, String JavaDoc info) {
1012        trace(dbgTag, func, info);
1013    }
1014    
1015    private static boolean isDebugOn() {
1016        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER);
1017    }
1018    
1019    private static void debug(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
1020        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER, clz, func, info);
1021    }
1022    
1023    private static void debug(String JavaDoc func, String JavaDoc info) {
1024        debug(dbgTag, func, info);
1025    }
1026    
1027    private static void debugX(String JavaDoc func,Throwable JavaDoc e) {
1028    if (isDebugOn()) {
1029        final StringWriter JavaDoc s = new StringWriter JavaDoc();
1030        e.printStackTrace(new PrintWriter JavaDoc(s));
1031        final String JavaDoc stack = s.toString();
1032        
1033        debug(dbgTag,func,"Exception caught in "+ func+"(): "+e);
1034        debug(dbgTag,func,stack);
1035    
1036        // java.lang.System.err.println("**** Exception caught in "+
1037
// func+"(): "+e);
1038
// java.lang.System.err.println(stack);
1039
}
1040    }
1041    
1042}
1043
Popular Tags