KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mchange > v2 > c3p0 > management > DynamicPooledDataSourceManagerMBean


1 /*
2  * Distributed as part of c3p0 v.0.9.1
3  *
4  * Copyright (C) 2005 Machinery For Change, Inc.
5  *
6  * Author: Steve Waldman <swaldman@mchange.com>
7  *
8  * This library is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License version 2.1, as
10  * published by the Free Software Foundation.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this software; see the file LICENSE. If not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */

22
23
24 package com.mchange.v2.c3p0.management;
25
26 import java.beans.BeanInfo JavaDoc;
27 import java.beans.Introspector JavaDoc;
28 import java.beans.PropertyChangeEvent JavaDoc;
29 import java.beans.PropertyChangeListener JavaDoc;
30 import java.beans.PropertyDescriptor JavaDoc;
31 import java.lang.reflect.Method JavaDoc;
32 import java.util.*;
33 import javax.management.Attribute JavaDoc;
34 import javax.management.AttributeList JavaDoc;
35 import javax.management.AttributeNotFoundException JavaDoc;
36 import javax.management.DynamicMBean JavaDoc;
37 import javax.management.InvalidAttributeValueException JavaDoc;
38 import javax.management.MBeanAttributeInfo JavaDoc;
39 import javax.management.MBeanConstructorInfo JavaDoc;
40 import javax.management.MBeanException JavaDoc;
41 import javax.management.MBeanInfo JavaDoc;
42 import javax.management.MBeanOperationInfo JavaDoc;
43 import javax.management.MBeanParameterInfo JavaDoc;
44 import javax.management.MBeanServer JavaDoc;
45 import javax.management.ObjectName JavaDoc;
46 import javax.management.ReflectionException JavaDoc;
47 import javax.sql.ConnectionPoolDataSource JavaDoc;
48 import javax.sql.DataSource JavaDoc;
49
50 import com.mchange.v1.lang.ClassUtils;
51 import com.mchange.v2.c3p0.ComboPooledDataSource;
52 import com.mchange.v2.c3p0.DriverManagerDataSource;
53 import com.mchange.v2.c3p0.PooledDataSource;
54 import com.mchange.v2.c3p0.PoolBackedDataSource;
55 import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource;
56 import com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource;
57 import com.mchange.v2.log.MLog;
58 import com.mchange.v2.log.MLogger;
59 import com.mchange.v2.log.MLevel;
60 import com.mchange.v2.management.ManagementUtils;
61
62 public class DynamicPooledDataSourceManagerMBean implements DynamicMBean JavaDoc
63 {
64     final static MLogger logger = MLog.getLogger( DynamicPooledDataSourceManagerMBean.class );
65
66     final static Set HIDE_PROPS;
67     final static Set HIDE_OPS;
68     final static Set FORCE_OPS;
69     
70     final static Set FORCE_READ_ONLY_PROPS;
71
72     static
73     {
74         Set hpTmp = new HashSet();
75         hpTmp.add("connectionPoolDataSource");
76         hpTmp.add("nestedDataSource");
77         hpTmp.add("reference");
78         hpTmp.add("connection");
79         hpTmp.add("password");
80         hpTmp.add("pooledConnection");
81         hpTmp.add("logWriter");
82         hpTmp.add("lastAcquisitionFailureDefaultUser");
83         hpTmp.add("lastCheckoutFailureDefaultUser");
84         hpTmp.add("lastCheckinFailureDefaultUser");
85         hpTmp.add("lastIdleTestFailureDefaultUser");
86         hpTmp.add("lastConnectionTestFailureDefaultUser");
87         HIDE_PROPS = Collections.unmodifiableSet( hpTmp );
88         
89     Class JavaDoc[] userPassArgs = new Class JavaDoc[] { String JavaDoc.class, String JavaDoc.class };
90         Set hoTmp = new HashSet();
91         try
92         {
93             hoTmp.add(PooledDataSource.class.getMethod("close", new Class JavaDoc[] { boolean.class }) );
94             hoTmp.add(PooledDataSource.class.getMethod("getConnection", userPassArgs ) );
95
96             hoTmp.add(PooledDataSource.class.getMethod("getLastAcquisitionFailure", userPassArgs ) );
97             hoTmp.add(PooledDataSource.class.getMethod("getLastCheckinFailure", userPassArgs ) );
98             hoTmp.add(PooledDataSource.class.getMethod("getLastCheckoutFailure", userPassArgs ) );
99             hoTmp.add(PooledDataSource.class.getMethod("getLastIdleTestFailure", userPassArgs ) );
100             hoTmp.add(PooledDataSource.class.getMethod("getLastConnectionTestFailure", userPassArgs ) );
101         }
102         catch (Exception JavaDoc e)
103         {
104             logger.log(MLevel.WARNING, "Tried to hide an operation from being exposed by mbean, but failed to find the operation!", e);
105         }
106         HIDE_OPS = Collections.unmodifiableSet(hoTmp);
107         
108         Set fropTmp = new HashSet();
109         fropTmp.add("identityToken");
110         FORCE_READ_ONLY_PROPS = Collections.unmodifiableSet(fropTmp);
111
112     Set foTmp = new HashSet();
113     FORCE_OPS = Collections.unmodifiableSet(foTmp);
114     }
115
116     final static MBeanOperationInfo JavaDoc[] OP_INFS = extractOpInfs();
117
118     MBeanInfo JavaDoc info = null;
119
120     PooledDataSource pds;
121     String JavaDoc mbeanName;
122     MBeanServer JavaDoc mbs;
123     
124     ConnectionPoolDataSource JavaDoc cpds;
125     DataSource JavaDoc unpooledDataSource;
126
127     //attr names to attr infos
128
Map pdsAttrInfos;
129     Map cpdsAttrInfos;
130     Map unpooledDataSourceAttrInfos;
131     
132     PropertyChangeListener JavaDoc pcl = new PropertyChangeListener JavaDoc()
133     {
134         public void propertyChange(PropertyChangeEvent JavaDoc evt)
135         {
136             String JavaDoc propName = evt.getPropertyName();
137             Object JavaDoc val = evt.getNewValue();
138
139             if ("nestedDataSource".equals(propName) || "connectionPoolDataSource".equals(propName))
140                 reinitialize();
141         }
142     };
143
144     public DynamicPooledDataSourceManagerMBean(PooledDataSource pds, String JavaDoc mbeanName, MBeanServer JavaDoc mbs)
145         throws Exception JavaDoc
146     {
147         this.pds = pds;
148         this.mbeanName = mbeanName;
149         this.mbs = mbs;
150         
151         if (pds instanceof ComboPooledDataSource)
152             /* do nothing */;
153         else if (pds instanceof AbstractPoolBackedDataSource)
154             ((AbstractPoolBackedDataSource) pds).addPropertyChangeListener(pcl);
155         else
156             logger.warning(this + "managing an unexpected PooledDataSource. Only top-level attributes will be available. PooledDataSource: " + pds);
157         
158         Exception JavaDoc e = reinitialize();
159         if (e != null)
160             throw e;
161     }
162     
163     private synchronized Exception JavaDoc reinitialize()
164     {
165         try
166         {
167             // for ComboPooledDataSource, everything we care about is exposed via the PooledDataSource
168
// for other implementations, we have to pay attention to nested DataSources
169
if (!(pds instanceof ComboPooledDataSource) && pds instanceof AbstractPoolBackedDataSource)
170             {
171                 if (this.cpds instanceof WrapperConnectionPoolDataSource) //implies non-null, this is a reinit
172
((WrapperConnectionPoolDataSource) this.cpds).removePropertyChangeListener(pcl);
173                 
174                 
175                 // yeah, we reassign instantly, but for my comfort...
176
this.cpds = null;
177                 this.unpooledDataSource = null;
178                 
179                 this.cpds = ((AbstractPoolBackedDataSource) pds).getConnectionPoolDataSource();
180
181                 if (cpds instanceof WrapperConnectionPoolDataSource)
182                 {
183                     this.unpooledDataSource = ((WrapperConnectionPoolDataSource) cpds).getNestedDataSource();
184                     ((WrapperConnectionPoolDataSource) this.cpds).addPropertyChangeListener(pcl);
185                 }
186             }
187
188             pdsAttrInfos = extractAttributeInfos( pds );
189             cpdsAttrInfos = extractAttributeInfos( cpds );
190             unpooledDataSourceAttrInfos = extractAttributeInfos( unpooledDataSource );
191
192             Set allAttrNames = new HashSet();
193             allAttrNames.addAll(pdsAttrInfos.keySet());
194             allAttrNames.addAll(cpdsAttrInfos.keySet());
195             allAttrNames.addAll(unpooledDataSourceAttrInfos.keySet());
196
197             Set allAttrs = new HashSet();
198             for(Iterator ii = allAttrNames.iterator(); ii.hasNext();)
199             {
200                 String JavaDoc name = (String JavaDoc) ii.next();
201                 Object JavaDoc attrInfo;
202                 attrInfo = pdsAttrInfos.get(name);
203                 if (attrInfo == null)
204                     attrInfo = cpdsAttrInfos.get(name);
205                 if (attrInfo == null)
206                     attrInfo = unpooledDataSourceAttrInfos.get(name);
207                 allAttrs.add(attrInfo);
208             }
209
210             String JavaDoc className = this.getClass().getName();
211             MBeanAttributeInfo JavaDoc[] attrInfos = (MBeanAttributeInfo JavaDoc[]) allAttrs.toArray(new MBeanAttributeInfo JavaDoc[ allAttrs.size() ]);
212             Class JavaDoc[] ctorArgClasses = {PooledDataSource.class, String JavaDoc.class, MBeanServer JavaDoc.class};
213             MBeanConstructorInfo JavaDoc[] constrInfos
214                = new MBeanConstructorInfo JavaDoc[] { new MBeanConstructorInfo JavaDoc("Constructor from PooledDataSource", this.getClass().getConstructor(ctorArgClasses)) };
215             this.info = new MBeanInfo JavaDoc( this.getClass().getName(),
216                             "An MBean to monitor and manage a PooledDataSource",
217                             attrInfos,
218                             constrInfos,
219                             OP_INFS,
220                             null);
221             
222             // we need to reregister when the attributes we support may have changed, to be sure
223
// that the MBeanInfo is reread.
224
try
225             {
226                 ObjectName JavaDoc oname = ObjectName.getInstance( mbeanName );
227                 if (mbs.isRegistered( oname ))
228                 {
229                     mbs.unregisterMBean( oname );
230                     if (logger.isLoggable(MLevel.FINER))
231                         logger.log(MLevel.FINER, "MBean: " + mbeanName + " unregistered, in order to be reregistered after update.");
232                 }
233                 mbs.registerMBean( this, oname );
234                 if (logger.isLoggable(MLevel.FINER))
235                     logger.log(MLevel.FINER, "MBean: " + mbeanName + " registered.");
236                 
237                 return null;
238             }
239             catch (Exception JavaDoc e)
240             {
241                 if ( logger.isLoggable(MLevel.WARNING) )
242                     logger.log(MLevel.WARNING,
243                                "An Exception occurred while registering/reregistering mbean " + mbeanName +
244                                ". MBean may not be registered, or may not work properly.",
245                                e );
246                 return e;
247             }
248         }
249         catch (NoSuchMethodException JavaDoc e)
250         {
251             if (logger.isLoggable(MLevel.SEVERE))
252                 logger.log( MLevel.SEVERE,
253                                 "Huh? We can't find our own constructor?? The one we're in?",
254                                 e);
255             return e;
256         }
257     }
258
259     // this method is fragile, makes assumptions that may have to change with
260
// the PooledDataSource interface. It presumes that methods that look like
261
// JavaBean properties should be skipped as attributes, that methods with
262
// two string arguments are always username and password, that methods with
263
// a return value are simple getters, while void methods are modifiers. At the
264
// time of this writing, these assumptions all hold for PooledDataSource.
265
// But beware the future.
266
private static MBeanOperationInfo JavaDoc[] extractOpInfs()
267     {
268         MBeanParameterInfo JavaDoc user = new MBeanParameterInfo JavaDoc("user", "java.lang.String", "The database username of a pool-owner.");
269         MBeanParameterInfo JavaDoc pwd = new MBeanParameterInfo JavaDoc("password", "java.lang.String", "The database password of a pool-owner.");
270         MBeanParameterInfo JavaDoc[] userPass = {user, pwd};
271         MBeanParameterInfo JavaDoc[] empty = {};
272
273         Method JavaDoc[] meths = PooledDataSource.class.getMethods();
274         Set attrInfos = new TreeSet(ManagementUtils.OP_INFO_COMPARATOR);
275
276         for (int i = 0; i < meths.length; ++i)
277         {
278             Method JavaDoc meth = meths[i];
279             if (HIDE_OPS.contains(meth))
280                 continue;
281             
282             String JavaDoc mname = meth.getName();
283             Class JavaDoc[] params = meth.getParameterTypes();
284
285         if (! FORCE_OPS.contains(mname))
286         {
287             //get rid of things we'd have picked up as attributes
288
if (mname.startsWith("set") && params.length == 1)
289             continue;
290             if ((mname.startsWith("get") || mname.startsWith("is")) && params.length == 0)
291             continue;
292         }
293
294             Class JavaDoc retType = meth.getReturnType();
295             int impact = (retType == void.class ? MBeanOperationInfo.ACTION : MBeanOperationInfo.INFO);
296             MBeanParameterInfo JavaDoc[] pi;
297             if (params.length == 2 && params[0] == String JavaDoc.class && params[1] == String JavaDoc.class)
298                 pi = userPass;
299             else if (params.length == 0)
300                 pi = empty;
301             else
302                 pi = null;
303
304             MBeanOperationInfo JavaDoc opi;
305             if (pi != null)
306                 opi = new MBeanOperationInfo JavaDoc( mname, // name
307
null, // desc
308
pi,
309                                 retType.getName(),
310                                 impact );
311             else
312             {
313                 //System.err.println("autobuilding opi from meth " + meth);
314
opi = new MBeanOperationInfo JavaDoc(meth.toString(), meth);
315             }
316
317             //System.err.println("Created MBeanOperationInfo: " + opi + " [" + opi.getName() + ']');
318
attrInfos.add( opi );
319         }
320
321         return (MBeanOperationInfo JavaDoc[]) attrInfos.toArray( new MBeanOperationInfo JavaDoc[ attrInfos.size() ] );
322     }
323
324     public synchronized Object JavaDoc getAttribute(String JavaDoc attr) throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc, ReflectionException JavaDoc
325     {
326         try
327         {
328             AttrRec rec = attrRecForAttribute(attr);
329             if (rec == null)
330                 throw new AttributeNotFoundException JavaDoc(attr);
331             else
332             {
333                 MBeanAttributeInfo JavaDoc ai = rec.attrInfo;
334                 if (! ai.isReadable() )
335                     throw new IllegalArgumentException JavaDoc(attr + " not readable.");
336                 else
337                 {
338                     String JavaDoc name = ai.getName();
339                     String JavaDoc pfx = ai.isIs() ? "is" : "get";
340                     String JavaDoc mname = pfx + Character.toUpperCase(name.charAt(0)) + name.substring(1);
341                     Object JavaDoc target = rec.target;
342                     Method JavaDoc m = target.getClass().getMethod(mname, null);
343                     return m.invoke(target, null);
344                 }
345             }
346         }
347         catch (Exception JavaDoc e)
348         {
349             if (logger.isLoggable(MLevel.WARNING))
350                 logger.log(MLevel.WARNING, "Failed to get requested attribute: " + attr, e);
351             throw new MBeanException JavaDoc(e);
352         }
353     }
354
355     public synchronized AttributeList JavaDoc getAttributes(String JavaDoc[] attrs)
356     {
357         AttributeList JavaDoc al = new AttributeList JavaDoc();
358         for (int i = 0, len = attrs.length; i < len; ++i)
359         {
360             String JavaDoc attr = attrs[i];
361             try
362             {
363                 Object JavaDoc val = getAttribute(attr);
364                 al.add(new Attribute JavaDoc(attr, val));
365             }
366             catch (Exception JavaDoc e)
367             {
368                 if (logger.isLoggable(MLevel.WARNING))
369                     logger.log(MLevel.WARNING, "Failed to get requested attribute (for list): " + attr, e);
370             }
371         }
372         return al;
373     }
374
375     private AttrRec attrRecForAttribute(String JavaDoc attr)
376     {
377         assert (Thread.holdsLock(this));
378         
379         if (pdsAttrInfos.containsKey(attr))
380             return new AttrRec(pds, (MBeanAttributeInfo JavaDoc) pdsAttrInfos.get(attr));
381         else if (cpdsAttrInfos.containsKey(attr))
382             return new AttrRec(cpds, (MBeanAttributeInfo JavaDoc) cpdsAttrInfos.get(attr));
383         else if (unpooledDataSourceAttrInfos.containsKey(attr))
384             return new AttrRec(unpooledDataSource, (MBeanAttributeInfo JavaDoc) unpooledDataSourceAttrInfos.get(attr));
385         else
386             return null;
387     }
388
389     public synchronized MBeanInfo JavaDoc getMBeanInfo()
390     {
391         if (info == null)
392             reinitialize();
393         return info;
394     }
395
396     public synchronized Object JavaDoc invoke(String JavaDoc operation, Object JavaDoc[] paramVals, String JavaDoc[] signature) throws MBeanException JavaDoc, ReflectionException JavaDoc
397     {
398         try
399         {
400             int slen = signature.length;
401             Class JavaDoc[] paramTypes = new Class JavaDoc[ slen ];
402             for (int i = 0; i < slen; ++i)
403                 paramTypes[i] = ClassUtils.forName( signature[i] );
404             
405             //all operations should be on pds
406
Method JavaDoc m = pds.getClass().getMethod(operation, paramTypes);
407             return m.invoke(pds, paramVals);
408         }
409         catch (NoSuchMethodException JavaDoc e)
410         {
411             // although not generally legal as of the latest JMX spec,
412
// someone could be trying to work with attributes through
413
// invoke. If so, we try to deal
414
try
415             {
416             boolean two = false;
417             if (signature.length == 0 && ( operation.startsWith("get") || (two = operation.startsWith("is")) ))
418             {
419                 int i = two ? 2 : 3;
420                 String JavaDoc attr = Character.toLowerCase(operation.charAt(i)) + operation.substring(i + 1);
421                 return getAttribute( attr );
422             }
423             else if (signature.length == 1 && operation.startsWith("set"))
424             {
425                 setAttribute(new Attribute JavaDoc(Character.toLowerCase(operation.charAt(3)) + operation.substring(4), paramVals[0]));
426                 return null;
427             }
428             else
429                 throw new MBeanException JavaDoc(e);
430             }
431             catch (Exception JavaDoc e2)
432             { throw new MBeanException JavaDoc(e2); }
433         }
434         catch (Exception JavaDoc e)
435         { throw new MBeanException JavaDoc(e); }
436     }
437
438     public synchronized void setAttribute(Attribute JavaDoc attrObj) throws AttributeNotFoundException JavaDoc, InvalidAttributeValueException JavaDoc, MBeanException JavaDoc, ReflectionException JavaDoc
439     {
440         try
441         {
442             String JavaDoc attr = attrObj.getName();
443             
444             if (attr == "factoryClassLocation") // special case
445
{
446                 if (pds instanceof ComboPooledDataSource)
447                 {
448                     ((ComboPooledDataSource) pds).setFactoryClassLocation((String JavaDoc) attrObj.getValue());
449                     return;
450                 }
451                 else if (pds instanceof AbstractPoolBackedDataSource)
452                 {
453                     String JavaDoc val = (String JavaDoc) attrObj.getValue();
454                     AbstractPoolBackedDataSource apbds = ((AbstractPoolBackedDataSource) pds);
455                     apbds.setFactoryClassLocation( val );
456                     ConnectionPoolDataSource JavaDoc checkDs1 = apbds.getConnectionPoolDataSource();
457                     if (checkDs1 instanceof WrapperConnectionPoolDataSource)
458                     {
459                         WrapperConnectionPoolDataSource wcheckDs1 = (WrapperConnectionPoolDataSource) checkDs1;
460                         wcheckDs1.setFactoryClassLocation( val );
461                         DataSource JavaDoc checkDs2 = wcheckDs1.getNestedDataSource();
462                         if (checkDs2 instanceof DriverManagerDataSource)
463                             ((DriverManagerDataSource) checkDs2).setFactoryClassLocation( val );
464                     }
465                     return;
466                 }
467                 // else try treating factoryClassLocation like any other attribute
468
// on the presumption that some future, unexpected DataSource that
469
// exposes this property will not require the property to be set at
470
// multiple levels, as PoolBackedDataSource does...
471
}
472             
473             AttrRec rec = attrRecForAttribute(attr);
474             if (rec == null)
475                 throw new AttributeNotFoundException JavaDoc(attr);
476             else
477             {
478                 MBeanAttributeInfo JavaDoc ai = rec.attrInfo;
479                 if (! ai.isWritable() )
480                     throw new IllegalArgumentException JavaDoc(attr + " not writable.");
481                 else
482                 {
483                     Class JavaDoc attrType = ClassUtils.forName( rec.attrInfo.getType() );
484                     String JavaDoc name = ai.getName();
485                     String JavaDoc pfx = "set";
486                     String JavaDoc mname = pfx + Character.toUpperCase(name.charAt(0)) + name.substring(1);
487                     Object JavaDoc target = rec.target;
488                     Method JavaDoc m = target.getClass().getMethod(mname, new Class JavaDoc[] {attrType});
489                     m.invoke(target, new Object JavaDoc[] { attrObj.getValue() });
490                     
491                     // if we were unable to set this attribute directly in the PooledDataSource,
492
// we are updating a property of a nested DataSource, and we should reset
493
// the pool manager of the PooledDataSource implementation so that these
494
// properties are reread and the changes take effect.
495
if (target != pds)
496                     {
497                          if (pds instanceof AbstractPoolBackedDataSource)
498                             ((AbstractPoolBackedDataSource) pds).resetPoolManager(false);
499                          else if (logger.isLoggable(MLevel.WARNING))
500                              logger.warning("MBean set a nested ConnectionPoolDataSource or DataSource parameter on an unknown PooledDataSource type. " +
501                                              "Could not reset the pool manager, so the changes may not take effect. " + "" +
502                                               "c3p0 may need to be updated for PooledDataSource type " + pds.getClass() + ".");
503                              
504                     }
505                 }
506             }
507         }
508         catch (Exception JavaDoc e)
509         {
510             if (logger.isLoggable(MLevel.WARNING))
511                 logger.log(MLevel.WARNING, "Failed to set requested attribute: " + attrObj, e);
512             throw new MBeanException JavaDoc(e);
513         }
514     }
515
516     public synchronized AttributeList JavaDoc setAttributes(AttributeList JavaDoc al)
517     {
518         AttributeList JavaDoc out = new AttributeList JavaDoc();
519         for (int i = 0, len = al.size(); i < len; ++i)
520         {
521             Attribute JavaDoc attrObj = (Attribute JavaDoc) al.get(i);
522             
523             try
524             {
525                 this.setAttribute( attrObj );
526                 out.add(attrObj);
527             }
528             catch (Exception JavaDoc e)
529             {
530                 if (logger.isLoggable(MLevel.WARNING))
531                     logger.log(MLevel.WARNING, "Failed to set requested attribute (from list): " + attrObj, e);
532             }
533         }
534         return out;
535     }
536
537     private static Map extractAttributeInfos(Object JavaDoc bean)
538     {
539         if ( bean != null)
540         {
541             try
542             {
543                 Map out = new HashMap();
544                 BeanInfo JavaDoc beanInfo = Introspector.getBeanInfo( bean.getClass(), Object JavaDoc.class ); //so we don't see getClass() as a property
545
PropertyDescriptor JavaDoc[] pds = beanInfo.getPropertyDescriptors();
546                 //System.err.println("ignoreProps: " + ignoreProps );
547
for( int i = 0, len = pds.length; i < len; ++i)
548                 {
549                     PropertyDescriptor JavaDoc pd = pds[i];
550
551                     String JavaDoc name;
552                     String JavaDoc desc;
553                     Method JavaDoc getter;
554                     Method JavaDoc setter;
555
556                     name = pd.getName();
557
558                     if (HIDE_PROPS.contains( name ))
559                         continue;
560
561                     desc = getDescription( name );
562                     getter = pd.getReadMethod();
563                     setter = pd.getWriteMethod();
564                     
565                     if (FORCE_READ_ONLY_PROPS.contains(name))
566                         setter = null;
567
568                     /*
569                      * Note that it's not a problem that these
570                      * getters and setters are not against this class
571                      * the MBeanAttributInfo just uses the method
572                      * names and attribute type to construct itself,
573                      * and does not hold the methods themselves for
574                      * future invocation.
575                      */

576
577                     try
578                     {
579                         out.put( name, new MBeanAttributeInfo JavaDoc(name, desc, getter, setter) );
580                     }
581                     catch (javax.management.IntrospectionException JavaDoc e)
582                     {
583                         if (logger.isLoggable( MLevel.WARNING ))
584                             logger.log( MLevel.WARNING, "IntrospectionException while setting up MBean attribute '" + name + "'", e);
585                     }
586                 }
587
588                 return Collections.synchronizedMap(out);
589             }
590             catch (java.beans.IntrospectionException JavaDoc e)
591             {
592                 if (logger.isLoggable( MLevel.WARNING ))
593                     logger.log( MLevel.WARNING, "IntrospectionException while setting up MBean attributes for " + bean, e);
594                 return Collections.EMPTY_MAP;
595             }
596         }
597         else
598             return Collections.EMPTY_MAP;
599     }
600
601     // TODO: use a ResourceBundle for attribute descriptions.
602
// (Extra credit -- build from xml file, build docs same way)
603
private static String JavaDoc getDescription(String JavaDoc attrName)
604     { return null; }
605
606     private static class AttrRec
607     {
608         Object JavaDoc target;
609         MBeanAttributeInfo JavaDoc attrInfo;
610     
611         AttrRec(Object JavaDoc target, MBeanAttributeInfo JavaDoc attrInfo)
612         {
613             this.target = target;
614             this.attrInfo = attrInfo;
615         }
616     }
617
618 }
619
Popular Tags