KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > StandardMBean


1 /*
2  * @(#)StandardMBean.java 1.23 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 javax.management;
9
10 import com.sun.jmx.mbeanserver.StandardMBeanMetaDataImpl;
11 import com.sun.jmx.trace.Trace;
12 import java.io.PrintWriter JavaDoc;
13 import java.io.StringWriter JavaDoc;
14 import java.lang.reflect.UndeclaredThrowableException JavaDoc;
15
16 /**
17  * <p>An MBean whose management interface is determined by reflection
18  * on a Java interface.</p>
19  *
20  * <p>This class brings more flexibility to the notion of Management
21  * Interface in the use of Standard MBeans. Straightforward use of
22  * the patterns for Standard MBeans described in the JMX Specification
23  * means that there is a fixed relationship between the implementation
24  * class of an MBean and its management interface (i.e., if the
25  * implementation class is Thing, the management interface must be
26  * ThingMBean). This class makes it possible to keep the convenience
27  * of specifying the management interface with a Java interface,
28  * without requiring that there be any naming relationship between the
29  * implementation and interface classes.</p>
30  *
31  * <p>By making a DynamicMBean out of an MBean, this class makes
32  * it possible to select any interface implemented by the MBean as its
33  * management interface, provided that it complies with JMX patterns
34  * (i.e., attributes defined by getter/setter etc...).</p>
35  *
36  * <p> This class also provides hooks that make it possible to supply
37  * custom descriptions and names for the {@link MBeanInfo} returned by
38  * the DynamicMBean interface.</p>
39  *
40  * <p>Using this class, an MBean can be created with any
41  * implementation class name <i>Impl</i> and with a management
42  * interface defined (as for current Standard MBeans) by any interface
43  * <i>Intf</i>, in one of two general ways:</p>
44  *
45  * <ul>
46  *
47  * <li>Using the public constructor
48  * {@link #StandardMBean(java.lang.Object, java.lang.Class)
49  * StandardMBean(impl,interface)}:
50  * <pre>
51  * MBeanServer mbs;
52  * ...
53  * Impl impl = new Impl(...);
54  * StandardMBean mbean = new StandardMBean(impl, Intf.class);
55  * mbs.registerMBean(mbean, objectName);
56  * </pre></li>
57  *
58  * <li>Subclassing StandardMBean:
59  * <pre>
60  * public class Impl extends StandardMBean implements Intf {
61  * public Impl() {
62  * super(Intf.class);
63  * }
64  * // implement methods of Intf
65  * }
66  *
67  * [...]
68  *
69  * MBeanServer mbs;
70  * ....
71  * Impl impl = new Impl();
72  * mbs.registerMBean(impl, objectName);
73  * </pre></li>
74  *
75  * </ul>
76  *
77  * <p>In either case, the class <i>Impl</i> must implement the
78  * interface <i>Intf</i>.</p>
79  *
80  * <p>Standard MBeans based on the naming relationship between
81  * implementation and interface classes are of course still
82  * available.</p>
83  *
84  * @since 1.5
85  * @since.unbundled JMX 1.2
86  */

87 public class StandardMBean implements DynamicMBean JavaDoc {
88     /** The name of this class to be used for tracing */
89     private final static String JavaDoc dbgTag = "StandardMBean";
90
91     /**
92      * The management interface.
93      **/

94     private Class JavaDoc mbeanInterface;
95
96     /**
97      * The implementation.
98      **/

99     private Object JavaDoc implementation;
100
101     /**
102      * The MetaData object used for invoking reflection.
103      **/

104     private final StandardMBeanMetaDataImpl meta;
105
106     /**
107      * The cached MBeanInfo.
108      **/

109     private MBeanInfo JavaDoc cachedMBeanInfo;
110
111     /**
112      * Make a DynamicMBean out of <var>implementation</var>, using the
113      * specified <var>mbeanInterface</var> class.
114      * @param implementation The implementation of this MBean.
115      * If <code>null</code>, and null implementation is allowed,
116      * then the implementation is assumed to be <var>this</var>.
117      * @param mbeanInterface The Management Interface exported by this
118      * MBean's implementation. If <code>null</code>, then this
119      * object will use standard JMX design pattern to determine
120      * the management interface associated with the given
121      * implementation.
122      * @param nullImplementationAllowed <code>true</code> if a null
123      * implementation is allowed. If null implementation is allowed,
124      * and a null implementation is passed, then the implementation
125      * is assumed to be <var>this</var>.
126      * @exception IllegalArgumentException if the given
127      * <var>implementation</var> is null, and null is not allowed.
128      * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
129      * does not follow JMX design patterns for Management Interfaces, or
130      * if the given <var>implementation</var> does not implement the
131      * specified interface.
132      **/

133     private StandardMBean(Object JavaDoc implementation, Class JavaDoc mbeanInterface,
134               boolean nullImplementationAllowed)
135     throws NotCompliantMBeanException JavaDoc {
136     if (implementation == null) {
137         if (nullImplementationAllowed) implementation = this;
138         else throw new IllegalArgumentException JavaDoc("implementation is null");
139     }
140     this.meta = new StandardMBeanMetaDataImpl(this);
141     setImplementation(implementation,mbeanInterface);
142     }
143
144     /**
145      * <p>Make a DynamicMBean out of the object
146      * <var>implementation</var>, using the specified
147      * <var>mbeanInterface</var> class.</p>
148      *
149      * @param implementation The implementation of this MBean.
150      * @param mbeanInterface The Management Interface exported by this
151      * MBean's implementation. If <code>null</code>, then this
152      * object will use standard JMX design pattern to determine
153      * the management interface associated with the given
154      * implementation.
155      *
156      * @exception IllegalArgumentException if the given
157      * <var>implementation</var> is null.
158      * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
159      * does not follow JMX design patterns for Management Interfaces, or
160      * if the given <var>implementation</var> does not implement the
161      * specified interface.
162      **/

163     public StandardMBean(Object JavaDoc implementation,Class JavaDoc mbeanInterface)
164         throws NotCompliantMBeanException JavaDoc {
165     this(implementation,mbeanInterface,false);
166     }
167
168     /**
169      * <p>Make a DynamicMBean out of <var>this</var>, using the specified
170      * <var>mbeanInterface</var> class.</p>
171      *
172      * <p>Call {@link #StandardMBean(java.lang.Object, java.lang.Class)
173      * this(this,mbeanInterface)}.
174      * This constructor is reserved to subclasses.</p>
175      *
176      * @param mbeanInterface The Management Interface exported by this
177      * MBean.
178      *
179      * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
180      * does not follow JMX design patterns for Management Interfaces, or
181      * if <var>this</var> does not implement the specified interface.
182      **/

183     protected StandardMBean(Class JavaDoc mbeanInterface)
184         throws NotCompliantMBeanException JavaDoc {
185     this(null,mbeanInterface,true);
186     }
187
188     /**
189      * <p>Replace the implementation object wrapped in this
190      * object.</p>
191      *
192      * @param implementation The new implementation of this MBean.
193      * The <code>implementation</code> object must implement the MBean
194      * interface that was supplied when this
195      * <code>StandardMBean</code> was constructed.
196      *
197      * @exception IllegalArgumentException if the given
198      * <var>implementation</var> is null.
199      *
200      * @exception NotCompliantMBeanException if the given
201      * <var>implementation</var> does not implement the MBean
202      * interface that was supplied at construction.
203      *
204      * @see #getImplementation
205      **/

206     public synchronized void setImplementation(Object JavaDoc implementation)
207         throws NotCompliantMBeanException JavaDoc {
208     setImplementation(implementation, getMBeanInterface());
209     }
210
211     /**
212      * Replace the implementation and management interface wrapped in
213      * this object.
214      * @param implementation The new implementation of this MBean.
215      * @param mbeanInterface The Management Interface exported by this
216      * MBean's implementation. If <code>null</code>, then this
217      * object will use standard JMX design patterns to determine
218      * the management interface associated with the given
219      * implementation.
220      * @exception IllegalArgumentException if the given
221      * <var>implementation</var> is null.
222      * @exception NotCompliantMBeanException if the <var>mbeanInterface</var>
223      * does not follow JMX design patterns for Management Interfaces, or
224      * if the given <var>implementation</var> does not implement the
225      * specified interface.
226      **/

227     private synchronized void setImplementation(Object JavaDoc implementation,
228                         Class JavaDoc mbeanInterface)
229         throws NotCompliantMBeanException JavaDoc {
230     if (implementation == null)
231         throw new IllegalArgumentException JavaDoc("implementation is null");
232
233     // test compliance
234
this.meta.testCompliance(implementation.getClass(),mbeanInterface);
235
236     // flush the cache...
237
cacheMBeanInfo(null);
238     this.implementation = implementation;
239     this.mbeanInterface = mbeanInterface;
240     if (this.mbeanInterface == null)
241         this.mbeanInterface =
242         meta.getStandardMBeanInterface(implementation.getClass());
243     }
244
245     /**
246      * Get the implementation of this MBean.
247      * @return The implementation of this MBean.
248      *
249      * @see #setImplementation
250      **/

251     public synchronized Object JavaDoc getImplementation() {
252     return implementation;
253     }
254
255     /**
256      * Get the Management Interface of this MBean.
257      * @return The management interface of this MBean.
258      **/

259     public final synchronized Class JavaDoc getMBeanInterface() {
260     return mbeanInterface;
261     }
262
263     /**
264      * Get the class of the implementation of this MBean.
265      * @return The class of the implementation of this MBean.
266      **/

267     public synchronized Class JavaDoc getImplementationClass() {
268     if (implementation == null) return null;
269     return implementation.getClass();
270     }
271
272     // ------------------------------------------------------------------
273
// From the DynamicMBean interface.
274
// ------------------------------------------------------------------
275
public Object JavaDoc getAttribute(String JavaDoc attribute)
276     throws AttributeNotFoundException JavaDoc,
277            MBeanException JavaDoc, ReflectionException JavaDoc {
278     return meta.getAttribute(getImplementation(),attribute);
279     }
280     
281     // ------------------------------------------------------------------
282
// From the DynamicMBean interface.
283
// ------------------------------------------------------------------
284
public void setAttribute(Attribute JavaDoc attribute)
285     throws AttributeNotFoundException JavaDoc,
286            InvalidAttributeValueException JavaDoc, MBeanException JavaDoc,
287            ReflectionException JavaDoc {
288     meta.setAttribute(getImplementation(),attribute);
289     }
290         
291     // ------------------------------------------------------------------
292
// From the DynamicMBean interface.
293
// ------------------------------------------------------------------
294
public AttributeList JavaDoc getAttributes(String JavaDoc[] attributes) {
295     try {
296         return meta.getAttributes(getImplementation(),attributes);
297     } catch (ReflectionException JavaDoc x) {
298         final RuntimeException JavaDoc r =
299         new UndeclaredThrowableException JavaDoc(x,x.getMessage());
300         throw new RuntimeOperationsException JavaDoc(r,x.getMessage());
301     }
302     }
303
304     // ------------------------------------------------------------------
305
// From the DynamicMBean interface.
306
// ------------------------------------------------------------------
307
public AttributeList JavaDoc setAttributes(AttributeList JavaDoc attributes) {
308     try {
309         return meta.setAttributes(getImplementation(),attributes);
310     } catch (ReflectionException JavaDoc x) {
311         final RuntimeException JavaDoc r =
312         new UndeclaredThrowableException JavaDoc(x,x.getMessage());
313         throw new RuntimeOperationsException JavaDoc(r,x.getMessage());
314     }
315     }
316     
317     // ------------------------------------------------------------------
318
// From the DynamicMBean interface.
319
// ------------------------------------------------------------------
320
public Object JavaDoc invoke(String JavaDoc actionName, Object JavaDoc params[],
321              String JavaDoc signature[])
322     throws MBeanException JavaDoc, ReflectionException JavaDoc {
323     return meta.invoke(getImplementation(),actionName,params,signature);
324     }
325
326     /**
327      * Get the {@link MBeanInfo} for this MBean.
328      * <p>
329      * This method implements
330      * {@link javax.management.DynamicMBean#getMBeanInfo()
331      * DynamicMBean.getMBeanInfo()}.
332      * <p>
333      * This method first calls {@link #getCachedMBeanInfo()} in order to
334      * retrieve the cached MBeanInfo for this MBean, if any. If the
335      * MBeanInfo returned by {@link #getCachedMBeanInfo()} is not null,
336      * then it is returned.<br>
337      * Otherwise, this method builds a default MBeanInfo for this MBean,
338      * using the Management Interface specified for this MBean.
339      * <p>
340      * While building the MBeanInfo, this method calls the customization
341      * hooks that make it possible for subclasses to supply their custom
342      * descriptions, parameter names, etc...<br>
343      * Finally, it calls {@link #cacheMBeanInfo(javax.management.MBeanInfo)
344      * cacheMBeanInfo()} in order to cache the new MBeanInfo.
345      * @return The cached MBeanInfo for that MBean, if not null, or a
346      * newly built MBeanInfo if none was cached.
347      **/

348     public MBeanInfo JavaDoc getMBeanInfo() {
349     try {
350         final MBeanInfo JavaDoc cached = getCachedMBeanInfo();
351         if (cached != null) return (MBeanInfo JavaDoc)cached;
352     } catch (RuntimeException JavaDoc x) {
353         debug("getMBeanInfo","failed to get cached MBeanInfo: "+x);
354         debugX("getMBeanInfo",x);
355     }
356
357     if (isTraceOn()) {
358         trace("getMBeanInfo", "Building MBeanInfo for "+
359           getImplementationClass().getName());
360     }
361
362     final MBeanInfo JavaDoc bi;
363     final Object JavaDoc impl;
364     try {
365         synchronized (this) {
366         impl = getImplementation();
367         bi = buildStandardMBeanInfo();
368         }
369     } catch (NotCompliantMBeanException JavaDoc x) {
370         final RuntimeException JavaDoc r =
371         new UndeclaredThrowableException JavaDoc(x,x.getMessage());
372         throw new RuntimeOperationsException JavaDoc(r,x.getMessage());
373     }
374
375     final String JavaDoc cname = getClassName(bi);
376     final String JavaDoc text = getDescription(bi);
377     final MBeanConstructorInfo JavaDoc[] ctors = getConstructors(bi,impl);
378     final MBeanAttributeInfo JavaDoc[] attrs = getAttributes(bi);
379     final MBeanOperationInfo JavaDoc[] ops = getOperations(bi);
380     final MBeanNotificationInfo JavaDoc[] ntfs = getNotifications(bi);
381     final MBeanInfo JavaDoc nmbi =
382         new MBeanInfo JavaDoc(cname,text,attrs,ctors,ops,ntfs);
383
384     try { cacheMBeanInfo(nmbi); } catch (RuntimeException JavaDoc x) {
385         debug("cacheMBeanInfo","failed to cache MBeanInfo: "+x);
386         debugX("cacheMBeanInfo",x);
387     }
388
389     return nmbi;
390     }
391
392     /**
393      * Customization hook:
394      * Get the className that will be used in the MBeanInfo returned by
395      * this MBean.
396      * <br>
397      * Subclasses may redefine this method in order to supply their
398      * custom class name. The default implementation returns
399      * {@link MBeanInfo#getClassName() info.getClassName()}.
400      * @param info The default MBeanInfo derived by reflection.
401      * @return the class name for the new MBeanInfo.
402      **/

403     protected String JavaDoc getClassName(MBeanInfo JavaDoc info) {
404     if (info == null) return getImplementationClass().getName();
405     return info.getClassName();
406     }
407
408     /**
409      * Customization hook:
410      * Get the description that will be used in the MBeanInfo returned by
411      * this MBean.
412      * <br>
413      * Subclasses may redefine this method in order to supply their
414      * custom MBean description. The default implementation returns
415      * {@link MBeanInfo#getDescription() info.getDescription()}.
416      * @param info The default MBeanInfo derived by reflection.
417      * @return the description for the new MBeanInfo.
418      **/

419     protected String JavaDoc getDescription(MBeanInfo JavaDoc info) {
420     if (info == null) return null;
421     return info.getDescription();
422     }
423
424     /**
425      * <p>Customization hook:
426      * Get the description that will be used in the MBeanFeatureInfo
427      * returned by this MBean.</p>
428      *
429      * <p>Subclasses may redefine this method in order to supply
430      * their custom description. The default implementation returns
431      * {@link MBeanFeatureInfo#getDescription()
432      * info.getDescription()}.</p>
433      *
434      * <p>This method is called by
435      * {@link #getDescription(MBeanAttributeInfo)},
436      * {@link #getDescription(MBeanOperationInfo)},
437      * {@link #getDescription(MBeanConstructorInfo)}.</p>
438      *
439      * @param info The default MBeanFeatureInfo derived by reflection.
440      * @return the description for the given MBeanFeatureInfo.
441      **/

442     protected String JavaDoc getDescription(MBeanFeatureInfo JavaDoc info) {
443     if (info == null) return null;
444     return info.getDescription();
445     }
446
447     /**
448      * Customization hook:
449      * Get the description that will be used in the MBeanAttributeInfo
450      * returned by this MBean.
451      *
452      * <p>Subclasses may redefine this method in order to supply their
453      * custom description. The default implementation returns {@link
454      * #getDescription(MBeanFeatureInfo)
455      * getDescription((MBeanFeatureInfo) info)}.
456      * @param info The default MBeanAttributeInfo derived by reflection.
457      * @return the description for the given MBeanAttributeInfo.
458      **/

459     protected String JavaDoc getDescription(MBeanAttributeInfo JavaDoc info) {
460     return getDescription((MBeanFeatureInfo JavaDoc)info);
461     }
462
463     /**
464      * Customization hook:
465      * Get the description that will be used in the MBeanConstructorInfo
466      * returned by this MBean.
467      * <br>
468      * Subclasses may redefine this method in order to supply their
469      * custom description.
470      * The default implementation returns {@link
471      * #getDescription(MBeanFeatureInfo)
472      * getDescription((MBeanFeatureInfo) info)}.
473      * @param info The default MBeanConstructorInfo derived by reflection.
474      * @return the description for the given MBeanConstructorInfo.
475      **/

476     protected String JavaDoc getDescription(MBeanConstructorInfo JavaDoc info) {
477     return getDescription((MBeanFeatureInfo JavaDoc)info);
478     }
479
480     /**
481      * Customization hook:
482      * Get the description that will be used for the <var>sequence</var>
483      * MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
484      * <br>
485      * Subclasses may redefine this method in order to supply their
486      * custom description. The default implementation returns
487      * {@link MBeanParameterInfo#getDescription() param.getDescription()}.
488      *
489      * @param ctor The default MBeanConstructorInfo derived by reflection.
490      * @param param The default MBeanParameterInfo derived by reflection.
491      * @param sequence The sequence number of the parameter considered
492      * ("0" for the first parameter, "1" for the second parameter,
493      * etc...).
494      * @return the description for the given MBeanParameterInfo.
495      **/

496     protected String JavaDoc getDescription(MBeanConstructorInfo JavaDoc ctor,
497                     MBeanParameterInfo JavaDoc param,
498                     int sequence) {
499     if (param == null) return null;
500     return param.getDescription();
501     }
502
503     /**
504      * Customization hook:
505      * Get the name that will be used for the <var>sequence</var>
506      * MBeanParameterInfo of the MBeanConstructorInfo returned by this MBean.
507      * <br>
508      * Subclasses may redefine this method in order to supply their
509      * custom parameter name. The default implementation returns
510      * {@link MBeanParameterInfo#getName() param.getName()}.
511      *
512      * @param ctor The default MBeanConstructorInfo derived by reflection.
513      * @param param The default MBeanParameterInfo derived by reflection.
514      * @param sequence The sequence number of the parameter considered
515      * ("0" for the first parameter, "1" for the second parameter,
516      * etc...).
517      * @return the name for the given MBeanParameterInfo.
518      **/

519     protected String JavaDoc getParameterName(MBeanConstructorInfo JavaDoc ctor,
520                       MBeanParameterInfo JavaDoc param,
521                       int sequence) {
522     if (param == null) return null;
523     return param.getName();
524     }
525
526     /**
527      * Customization hook:
528      * Get the description that will be used in the MBeanOperationInfo
529      * returned by this MBean.
530      * <br>
531      * Subclasses may redefine this method in order to supply their
532      * custom description. The default implementation returns
533      * {@link #getDescription(MBeanFeatureInfo)
534      * getDescription((MBeanFeatureInfo) info)}.
535      * @param info The default MBeanOperationInfo derived by reflection.
536      * @return the description for the given MBeanOperationInfo.
537      **/

538     protected String JavaDoc getDescription(MBeanOperationInfo JavaDoc info) {
539     return getDescription((MBeanFeatureInfo JavaDoc)info);
540     }
541
542     /**
543      * Customization hook:
544      * Get the <var>impact</var> flag of the operation that will be used in
545      * the MBeanOperationInfo returned by this MBean.
546      * <br>
547      * Subclasses may redefine this method in order to supply their
548      * custom impact flag. The default implementation returns
549      * {@link MBeanOperationInfo#getImpact() info.getImpact()}.
550      * @param info The default MBeanOperationInfo derived by reflection.
551      * @return the impact flag for the given MBeanOperationInfo.
552      **/

553     protected int getImpact(MBeanOperationInfo JavaDoc info) {
554     if (info == null) return MBeanOperationInfo.UNKNOWN;
555     return info.getImpact();
556     }
557
558     /**
559      * Customization hook:
560      * Get the name that will be used for the <var>sequence</var>
561      * MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
562      * <br>
563      * Subclasses may redefine this method in order to supply their
564      * custom parameter name. The default implementation returns
565      * {@link MBeanParameterInfo#getName() param.getName()}.
566      *
567      * @param op The default MBeanOperationInfo derived by reflection.
568      * @param param The default MBeanParameterInfo derived by reflection.
569      * @param sequence The sequence number of the parameter considered
570      * ("0" for the first parameter, "1" for the second parameter,
571      * etc...).
572      * @return the name to use for the given MBeanParameterInfo.
573      **/

574     protected String JavaDoc getParameterName(MBeanOperationInfo JavaDoc op,
575                       MBeanParameterInfo JavaDoc param,
576                       int sequence) {
577     if (param == null) return null;
578     return param.getName();
579     }
580
581     /**
582      * Customization hook:
583      * Get the description that will be used for the <var>sequence</var>
584      * MBeanParameterInfo of the MBeanOperationInfo returned by this MBean.
585      * <br>
586      * Subclasses may redefine this method in order to supply their
587      * custom description. The default implementation returns
588      * {@link MBeanParameterInfo#getDescription() param.getDescription()}.
589      *
590      * @param op The default MBeanOperationInfo derived by reflection.
591      * @param param The default MBeanParameterInfo derived by reflection.
592      * @param sequence The sequence number of the parameter considered
593      * ("0" for the first parameter, "1" for the second parameter,
594      * etc...).
595      * @return the description for the given MBeanParameterInfo.
596      **/

597     protected String JavaDoc getDescription(MBeanOperationInfo JavaDoc op,
598                     MBeanParameterInfo JavaDoc param,
599                     int sequence) {
600     if (param == null) return null;
601     return param.getDescription();
602     }
603
604     /**
605      * Customization hook:
606      * Get the MBeanConstructorInfo[] that will be used in the MBeanInfo
607      * returned by this MBean.
608      * <br>
609      * By default, this method returns <code>null</code> if the wrapped
610      * implementation is not <var>this</var>. Indeed, if the wrapped
611      * implementation is not this object itself, it will not be possible
612      * to recreate a wrapped implementation by calling the implementation
613      * constructors through <code>MBeanServer.createMBean(...)</code>.<br>
614      * Otherwise, if the wrapped implementation is <var>this</var>,
615      * <var>ctors</var> is returned.
616      * <br>
617      * Subclasses may redefine this method in order to modify this
618      * behavior, if needed.
619      * @param ctors The default MBeanConstructorInfo[] derived by reflection.
620      * @param impl The wrapped implementation. If <code>null</code> is
621      * passed, the wrapped implementation is ignored and
622      * <var>ctors</var> is returned.
623      * @return the MBeanConstructorInfo[] for the new MBeanInfo.
624      **/

625     protected MBeanConstructorInfo JavaDoc[]
626     getConstructors(MBeanConstructorInfo JavaDoc[] ctors, Object JavaDoc impl) {
627         if (ctors == null) return null;
628         if (impl != null && impl != this) return null;
629         return ctors;
630     }
631
632     /**
633      * Customization hook:
634      * Get the MBeanNotificationInfo[] that will be used in the MBeanInfo
635      * returned by this MBean.
636      * <br>
637      * Subclasses may redefine this method in order to supply their
638      * custom notifications.
639      * @param info The default MBeanInfo derived by reflection.
640      * @return the MBeanNotificationInfo[] for the new MBeanInfo.
641      **/

642     // Private because not needed - the StandardMBeanMetaDataImpl already
643
// calls getNotificationInfo() on the implementation....
644
private MBeanNotificationInfo JavaDoc[]
645     getNotifications(MBeanInfo JavaDoc info) {
646     if (info == null) return null;
647         return info.getNotifications();
648     }
649     
650     /**
651      * Customization hook:
652      * Return the MBeanInfo cached for this object.
653      *
654      * <p>Subclasses may redefine this method in order to implement their
655      * own caching policy. The default implementation stores one
656      * {@link MBeanInfo} object per instance.
657      *
658      * @return The cached MBeanInfo, or null if no MBeanInfo is cached.
659      *
660      * @see #cacheMBeanInfo(MBeanInfo)
661      **/

662     protected synchronized MBeanInfo JavaDoc getCachedMBeanInfo() {
663     return cachedMBeanInfo;
664     }
665
666     /**
667      * Customization hook:
668      * cache the MBeanInfo built for this object.
669      *
670      * <p>Subclasses may redefine this method in order to implement
671      * their own caching policy. The default implementation stores
672      * <code>info</code> in this instance. A subclass can define
673      * other policies, such as not saving <code>info</code> (so it is
674      * reconstructed every time {@link #getMBeanInfo()} is called) or
675      * sharing a unique {@link MBeanInfo} object when several
676      * <code>StandardMBean</code> instances have equal {@link
677      * MBeanInfo} values.
678      *
679      * @param info the new <code>MBeanInfo</code> to cache. Any
680      * previously cached value is discarded. This parameter may be
681      * null, in which case there is no new cached value.
682      **/

683     protected synchronized void cacheMBeanInfo(MBeanInfo JavaDoc info) {
684     cachedMBeanInfo = info;
685     }
686
687     // ------------------------------------------------------------------
688
// Build the defaullt standard MBeanInfo.
689
// ------------------------------------------------------------------
690
private synchronized MBeanInfo JavaDoc buildStandardMBeanInfo()
691     throws NotCompliantMBeanException JavaDoc {
692     return meta.buildMBeanInfo(getImplementationClass(),
693                    getMBeanInterface());
694     }
695
696     // ------------------------------------------------------------------
697
// Build the custom MBeanConstructorInfo[]
698
// ------------------------------------------------------------------
699
private MBeanConstructorInfo JavaDoc[]
700     getConstructors(MBeanInfo JavaDoc info,Object JavaDoc impl) {
701     final MBeanConstructorInfo JavaDoc[] ctors =
702         getConstructors(info.getConstructors(),impl);
703     final MBeanConstructorInfo JavaDoc[] nctors;
704     if (ctors != null) {
705         final int ctorlen = ctors.length;
706         nctors = new MBeanConstructorInfo JavaDoc[ctorlen];
707         for (int i=0; i<ctorlen; i++) {
708         final MBeanConstructorInfo JavaDoc c = ctors[i];
709         final MBeanParameterInfo JavaDoc[] params = c.getSignature();
710         final MBeanParameterInfo JavaDoc[] nps;
711         if (params != null) {
712             final int plen = params.length;
713             nps = new MBeanParameterInfo JavaDoc[plen];
714             for (int ii=0;ii<plen;ii++) {
715             MBeanParameterInfo JavaDoc p = params[ii];
716             final String JavaDoc name = getParameterName(c,p,ii);
717             final String JavaDoc text = getDescription(c,p,ii);
718             nps[ii] = new MBeanParameterInfo JavaDoc(name,
719                              p.getType(),
720                              text);
721             }
722         } else {
723             nps = null;
724         }
725         nctors[i] = new MBeanConstructorInfo JavaDoc(c.getName(),
726                              getDescription(c),
727                              nps);
728         }
729     } else {
730         nctors = null;
731     }
732     return nctors;
733     }
734
735     // ------------------------------------------------------------------
736
// Build the custom MBeanOperationInfo[]
737
// ------------------------------------------------------------------
738
private MBeanOperationInfo JavaDoc[] getOperations(MBeanInfo JavaDoc info) {
739     final MBeanOperationInfo JavaDoc[] ops = info.getOperations();
740     final MBeanOperationInfo JavaDoc[] nops;
741     if (ops != null) {
742         final int oplen = ops.length;
743         nops = new MBeanOperationInfo JavaDoc[oplen];
744         for (int i=0; i<oplen; i++) {
745         final MBeanOperationInfo JavaDoc o = ops[i];
746         final MBeanParameterInfo JavaDoc[] params = o.getSignature();
747         final MBeanParameterInfo JavaDoc[] nps;
748         if (params != null) {
749             final int plen = params.length;
750             nps = new MBeanParameterInfo JavaDoc[plen];
751             for (int ii=0;ii<plen;ii++) {
752             MBeanParameterInfo JavaDoc p = params[ii];
753             final String JavaDoc name = getParameterName(o,p,ii);
754             final String JavaDoc text = getDescription(o,p,ii);
755             nps[ii] = new MBeanParameterInfo JavaDoc(name,
756                              p.getType(),
757                              text);
758             }
759         } else {
760             nps = null;
761         }
762         nops[i] = new MBeanOperationInfo JavaDoc(o.getName(),
763                          getDescription(o),
764                          nps,
765                          o.getReturnType(),
766                          getImpact(o));
767         }
768     } else {
769         nops = null;
770     }
771     return nops;
772     }
773
774     // ------------------------------------------------------------------
775
// Build the custom MBeanAttributeInfo[]
776
// ------------------------------------------------------------------
777
private MBeanAttributeInfo JavaDoc[] getAttributes(MBeanInfo JavaDoc info) {
778     final MBeanAttributeInfo JavaDoc[] atts = info.getAttributes();
779     final MBeanAttributeInfo JavaDoc[] natts;
780     if (atts != null) {
781         final int attlen = atts.length;
782         natts = new MBeanAttributeInfo JavaDoc[attlen];
783         for (int i=0; i<attlen; i++) {
784         final MBeanAttributeInfo JavaDoc a = atts[i];
785         natts[i] = new MBeanAttributeInfo JavaDoc(a.getName(),
786                           a.getType(),
787                           getDescription(a),
788                           a.isReadable(),
789                           a.isWritable(),
790                           a.isIs());
791         }
792     } else {
793         natts = null;
794     }
795     return natts;
796     }
797
798     // private stuff
799

800     private static boolean isTraceOn() {
801         return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MISC);
802     }
803
804     private static void trace(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
805         Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MISC, clz, func, info);
806     }
807     
808     private static void trace(String JavaDoc func, String JavaDoc info) {
809         trace(dbgTag, func, info);
810     }
811     
812     private static boolean isDebugOn() {
813         return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MISC);
814     }
815     
816     private static void debug(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
817         Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MISC, clz, func, info);
818     }
819     
820     private static void debug(String JavaDoc func, String JavaDoc info) {
821         debug(dbgTag, func, info);
822     }
823     
824     private static void debugX(String JavaDoc func,Throwable JavaDoc e) {
825     if (isDebugOn()) {
826         final StringWriter JavaDoc s = new StringWriter JavaDoc();
827         e.printStackTrace(new PrintWriter JavaDoc(s));
828         final String JavaDoc stack = s.toString();
829         
830         debug(dbgTag,func,"Exception caught in "+ func+"(): "+e);
831         debug(dbgTag,func,stack);
832     
833         // java.lang.System.err.println("**** Exception caught in "+
834
// func+"(): "+e);
835
// java.lang.System.err.println(stack);
836
}
837     }
838     
839 }
840
Popular Tags