KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > modeler > BaseModelMBean


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

16
17
18 package org.apache.commons.modeler;
19
20
21 import java.lang.reflect.InvocationTargetException JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Iterator JavaDoc;
26
27 import javax.management.Attribute JavaDoc;
28 import javax.management.AttributeChangeNotification JavaDoc;
29 import javax.management.AttributeList JavaDoc;
30 import javax.management.AttributeNotFoundException JavaDoc;
31 import javax.management.Descriptor JavaDoc;
32 import javax.management.DynamicMBean JavaDoc;
33 import javax.management.InstanceNotFoundException JavaDoc;
34 import javax.management.InvalidAttributeValueException JavaDoc;
35 import javax.management.ListenerNotFoundException JavaDoc;
36 import javax.management.MBeanException JavaDoc;
37 import javax.management.MBeanInfo JavaDoc;
38 import javax.management.MBeanNotificationInfo JavaDoc;
39 import javax.management.MBeanRegistration JavaDoc;
40 import javax.management.MBeanServer JavaDoc;
41 import javax.management.Notification JavaDoc;
42 import javax.management.NotificationFilter JavaDoc;
43 import javax.management.NotificationListener JavaDoc;
44 import javax.management.ObjectName JavaDoc;
45 import javax.management.ReflectionException JavaDoc;
46 import javax.management.RuntimeErrorException JavaDoc;
47 import javax.management.RuntimeOperationsException JavaDoc;
48 import javax.management.ServiceNotFoundException JavaDoc;
49 import javax.management.modelmbean.DescriptorSupport JavaDoc;
50 import javax.management.modelmbean.InvalidTargetObjectTypeException JavaDoc;
51 import javax.management.modelmbean.ModelMBean JavaDoc;
52 import javax.management.modelmbean.ModelMBeanAttributeInfo JavaDoc;
53 import javax.management.modelmbean.ModelMBeanInfo JavaDoc;
54 import javax.management.modelmbean.ModelMBeanInfoSupport JavaDoc;
55 import javax.management.modelmbean.ModelMBeanNotificationInfo JavaDoc;
56 import javax.management.modelmbean.ModelMBeanOperationInfo JavaDoc;
57
58 import org.apache.commons.logging.Log;
59 import org.apache.commons.logging.LogFactory;
60 import org.apache.commons.modeler.modules.ModelerSource;
61
62 // TODO: enable ant-like substitutions ? ( or at least discuss it )
63

64 /**
65  * <p>Basic implementation of the <code>ModelMBean</code> interface, which
66  * supports the minimal requirements of the interface contract.</p>
67  *
68  * <p>This can be used directly to wrap an existing java bean, or inside
69  * an mlet or anywhere an MBean would be used. The String parameter
70  * passed to the constructor will be used to construct an instance of the
71  * real object that we wrap.
72  *
73  * Limitations:
74  * <ul>
75  * <li>Only managed resources of type <code>objectReference</code> are
76  * supportd.</li>
77  * <li>Caching of attribute values and operation results is not supported.
78  * All calls to <code>invoke()</code> are immediately executed.</li>
79  * <li>Logging (under control of descriptors) is not supported.</li>
80  * <li>Persistence of MBean attributes and operations is not supported.</li>
81  * <li>All classes referenced as attribute types, operation parameters, or
82  * operation return values must be one of the following:
83  * <ul>
84  * <li>One of the Java primitive types (boolean, byte, char, double,
85  * float, integer, long, short). Corresponding value will be wrapped
86  * in the appropriate wrapper class automatically.</li>
87  * <li>Operations that return no value should declare a return type of
88  * <code>void</code>.</li>
89  * </ul>
90  * <li>Attribute caching is not supported</li>
91  * </ul>
92  *
93  * @author Craig R. McClanahan
94  * @author Costin Manolache
95  * @version $Revision$ $Date: 2005-02-26 05:12:25 -0800 (Sat, 26 Feb 2005) $
96  */

97
98 public class BaseModelMBean implements ModelMBean JavaDoc, MBeanRegistration JavaDoc {
99     private static Log log = LogFactory.getLog(BaseModelMBean.class);
100
101     // ----------------------------------------------------------- Constructors
102

103     /**
104      * Construct a <code>ModelMBean</code> with default
105      * <code>ModelMBeanInfo</code> information.
106      *
107      * @exception MBeanException if the initializer of an object
108      * throws an exception
109      * @exception RuntimeOperationsException if an IllegalArgumentException
110      * occurs
111      */

112     public BaseModelMBean() throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc {
113
114         super();
115         if( log.isDebugEnabled()) log.debug("default constructor");
116         setModelMBeanInfo(createDefaultModelMBeanInfo());
117     }
118
119
120     /**
121      * Construct a <code>ModelMBean</code> associated with the specified
122      * <code>ModelMBeanInfo</code> information.
123      *
124      * @param info ModelMBeanInfo for this MBean
125      *
126      * @exception MBeanException if the initializer of an object
127      * throws an exception
128      * @exception RuntimeOperationsException if an IllegalArgumentException
129      * occurs
130      */

131     public BaseModelMBean(ModelMBeanInfo JavaDoc info)
132         throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc {
133         // XXX should be deprecated - just call setInfo
134
super();
135         setModelMBeanInfo(info);
136         if( log.isDebugEnabled()) log.debug("ModelMBeanInfo constructor");
137     }
138
139     /** Construct a ModelMBean of a specified type.
140      * The type can be a class name or the key used in one of the descriptors.
141      *
142      * If no descriptor is available, we'll first try to locate one in
143      * the same package with the class, then use introspection.
144      *
145      * The mbean resource will be created.
146      *
147      * @param type Class name or the type key used in the descriptor.
148      * @throws MBeanException
149      * @throws RuntimeOperationsException
150      */

151     public BaseModelMBean( String JavaDoc type )
152         throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc
153     {
154         try {
155             // This constructor is used from <mlet>, it should create
156
// the resource
157
setModeledType(type);
158         } catch( Throwable JavaDoc ex ) {
159             log.error( "Error creating mbean ", ex);
160         }
161     }
162
163     public BaseModelMBean( String JavaDoc type, ModelerSource source )
164         throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc
165     {
166         try {
167             setModeledType(type);
168         } catch( Throwable JavaDoc ex ) {
169             log.error( "Error creating mbean ", ex);
170         }
171         this.source=source;
172     }
173
174     // ----------------------------------------------------- Instance Variables
175

176
177     /**
178      * Notification broadcaster for attribute changes.
179      */

180     protected BaseNotificationBroadcaster attributeBroadcaster = null;
181
182     /** Registry we are associated with
183      */

184     protected Registry registry=null;
185
186     /**
187      * Notification broadcaster for general notifications.
188      */

189     protected BaseNotificationBroadcaster generalBroadcaster = null;
190
191     protected ObjectName JavaDoc oname=null;
192
193     /**
194      * The <code>ModelMBeanInfo</code> object that controls our activity.
195      */

196     protected ModelMBeanInfo JavaDoc info = null;
197
198
199     /**
200      * The managed resource this MBean is associated with (if any).
201      */

202     protected Object JavaDoc resource = null;
203     protected String JavaDoc resourceType = null;
204
205     /** Source object used to read this mbean. Can be used to
206      * persist the mbean
207      */

208     protected ModelerSource source=null;
209
210     /** Attribute values. XXX That can be stored in the value Field
211      */

212     protected HashMap JavaDoc attributes=new HashMap JavaDoc();
213
214     // --------------------------------------------------- DynamicMBean Methods
215
static final Object JavaDoc[] NO_ARGS_PARAM=new Object JavaDoc[0];
216     static final Class JavaDoc[] NO_ARGS_PARAM_SIG=new Class JavaDoc[0];
217     // key: attribute val: getter method
218
private Hashtable JavaDoc getAttMap=new Hashtable JavaDoc();
219
220     // key: attribute val: setter method
221
private Hashtable JavaDoc setAttMap=new Hashtable JavaDoc();
222
223     // key: operation val: invoke method
224
private Hashtable JavaDoc invokeAttMap=new Hashtable JavaDoc();
225
226     /**
227      * Obtain and return the value of a specific attribute of this MBean.
228      *
229      * @param name Name of the requested attribute
230      *
231      * @exception AttributeNotFoundException if this attribute is not
232      * supported by this MBean
233      * @exception MBeanException if the initializer of an object
234      * throws an exception
235      * @exception ReflectionException if a Java reflection exception
236      * occurs when invoking the getter
237      */

238     public Object JavaDoc getAttribute(String JavaDoc name)
239         throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc,
240             ReflectionException JavaDoc {
241         // Validate the input parameters
242
if (name == null)
243             throw new RuntimeOperationsException JavaDoc
244                 (new IllegalArgumentException JavaDoc("Attribute name is null"),
245                  "Attribute name is null");
246
247         if( (resource instanceof DynamicMBean JavaDoc) &&
248              ! ( resource instanceof BaseModelMBean )) {
249             return ((DynamicMBean JavaDoc)resource).getAttribute(name);
250         }
251         
252         // Extract the method from cache
253
Method JavaDoc m=(Method JavaDoc)getAttMap.get( name );
254
255         if( m==null ) {
256             // Look up the actual operation to be used
257
ModelMBeanAttributeInfo JavaDoc attrInfo = info.getAttribute(name);
258             if (attrInfo == null)
259                 throw new AttributeNotFoundException JavaDoc(" Cannot find attribute " + name);
260             Descriptor JavaDoc attrDesc = attrInfo.getDescriptor();
261             if (attrDesc == null)
262                 throw new AttributeNotFoundException JavaDoc("Cannot find attribute " + name + " descriptor");
263             String JavaDoc getMethod = (String JavaDoc) attrDesc.getFieldValue("getMethod");
264
265             if (getMethod == null)
266                 throw new AttributeNotFoundException JavaDoc("Cannot find attribute " + name + " get method name");
267
268             Object JavaDoc object = null;
269             NoSuchMethodException JavaDoc exception = null;
270             try {
271                 object = this;
272                 m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG);
273             } catch (NoSuchMethodException JavaDoc e) {
274                 exception = e;;
275             }
276             if( m== null && resource != null ) {
277                 try {
278                     object = resource;
279                     m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG);
280                     exception=null;
281                 } catch (NoSuchMethodException JavaDoc e) {
282                     exception = e;
283                 }
284             }
285             if( exception != null )
286                 throw new ReflectionException JavaDoc(exception,
287                                               "Cannot find getter method " + getMethod);
288             getAttMap.put( name, m );
289         }
290
291         Object JavaDoc result = null;
292         try {
293             Class JavaDoc declaring=m.getDeclaringClass();
294             // workaround for catalina weird mbeans - the declaring class is BaseModelMBean.
295
// but this is the catalina class.
296
if( declaring.isAssignableFrom(this.getClass()) ) {
297                 result = m.invoke(this, NO_ARGS_PARAM );
298             } else {
299                 result = m.invoke(resource, NO_ARGS_PARAM );
300             }
301         } catch (InvocationTargetException JavaDoc e) {
302             Throwable JavaDoc t = e.getTargetException();
303             if (t == null)
304                 t = e;
305             if (t instanceof RuntimeException JavaDoc)
306                 throw new RuntimeOperationsException JavaDoc
307                     ((RuntimeException JavaDoc) t, "Exception invoking method " + name);
308             else if (t instanceof Error JavaDoc)
309                 throw new RuntimeErrorException JavaDoc
310                     ((Error JavaDoc) t, "Error invoking method " + name);
311             else
312                 throw new MBeanException JavaDoc
313                     (e, "Exception invoking method " + name);
314         } catch (Exception JavaDoc e) {
315             throw new MBeanException JavaDoc
316                 (e, "Exception invoking method " + name);
317         }
318
319         // Return the results of this method invocation
320
// FIXME - should we validate the return type?
321
return (result);
322     }
323
324
325     /**
326      * Obtain and return the values of several attributes of this MBean.
327      *
328      * @param names Names of the requested attributes
329      */

330     public AttributeList JavaDoc getAttributes(String JavaDoc names[]) {
331
332         // Validate the input parameters
333
if (names == null)
334             throw new RuntimeOperationsException JavaDoc
335                 (new IllegalArgumentException JavaDoc("Attribute names list is null"),
336                  "Attribute names list is null");
337
338         // Prepare our response, eating all exceptions
339
AttributeList JavaDoc response = new AttributeList JavaDoc();
340         for (int i = 0; i < names.length; i++) {
341             try {
342                 response.add(new Attribute JavaDoc(names[i],getAttribute(names[i])));
343             } catch (Exception JavaDoc e) {
344                 ; // Not having a particular attribute in the response
345
; // is the indication of a getter problem
346
}
347         }
348         return (response);
349
350     }
351
352
353     /**
354      * Return the <code>MBeanInfo</code> object for this MBean.
355      */

356     public MBeanInfo JavaDoc getMBeanInfo() {
357         // XXX Why do we have to clone ?
358
if( info== null ) return null;
359         return ((MBeanInfo JavaDoc) info.clone());
360     }
361
362
363     /**
364      * Invoke a particular method on this MBean, and return any returned
365      * value.
366      *
367      * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation will
368      * attempt to invoke this method on the MBean itself, or (if not
369      * available) on the managed resource object associated with this
370      * MBean.</p>
371      *
372      * @param name Name of the operation to be invoked
373      * @param params Array containing the method parameters of this operation
374      * @param signature Array containing the class names representing
375      * the signature of this operation
376      *
377      * @exception MBeanException if the initializer of an object
378      * throws an exception
379      * @exception ReflectioNException if a Java reflection exception
380      * occurs when invoking a method
381      */

382     public Object JavaDoc invoke(String JavaDoc name, Object JavaDoc params[], String JavaDoc signature[])
383         throws MBeanException JavaDoc, ReflectionException JavaDoc
384     {
385         if( (resource instanceof DynamicMBean JavaDoc) &&
386              ! ( resource instanceof BaseModelMBean )) {
387             return ((DynamicMBean JavaDoc)resource).invoke(name, params, signature);
388         }
389     
390         // Validate the input parameters
391
if (name == null)
392             throw new RuntimeOperationsException JavaDoc
393                 (new IllegalArgumentException JavaDoc("Method name is null"),
394                  "Method name is null");
395
396         if( log.isDebugEnabled()) log.debug("Invoke " + name);
397         Method JavaDoc method=(Method JavaDoc)invokeAttMap.get(name);
398         if( method==null ) {
399             if (params == null)
400                 params = new Object JavaDoc[0];
401             if (signature == null)
402                 signature = new String JavaDoc[0];
403             if (params.length != signature.length)
404                 throw new RuntimeOperationsException JavaDoc
405                     (new IllegalArgumentException JavaDoc("Inconsistent arguments and signature"),
406                      "Inconsistent arguments and signature");
407
408             // Acquire the ModelMBeanOperationInfo information for
409
// the requested operation
410
ModelMBeanOperationInfo JavaDoc opInfo = info.getOperation(name);
411             if (opInfo == null)
412                 throw new MBeanException JavaDoc
413                     (new ServiceNotFoundException JavaDoc("Cannot find operation " + name),
414                      "Cannot find operation " + name);
415
416             // Prepare the signature required by Java reflection APIs
417
// FIXME - should we use the signature from opInfo?
418
Class JavaDoc types[] = new Class JavaDoc[signature.length];
419             for (int i = 0; i < signature.length; i++) {
420                 types[i]=getAttributeClass( signature[i] );
421             }
422
423             // Locate the method to be invoked, either in this MBean itself
424
// or in the corresponding managed resource
425
// FIXME - Accessible methods in superinterfaces?
426
Object JavaDoc object = null;
427             Exception JavaDoc exception = null;
428             try {
429                 object = this;
430                 method = object.getClass().getMethod(name, types);
431             } catch (NoSuchMethodException JavaDoc e) {
432                 exception = e;;
433             }
434             try {
435                 if ((method == null) && (resource != null)) {
436                     object = resource;
437                     method = object.getClass().getMethod(name, types);
438                 }
439             } catch (NoSuchMethodException JavaDoc e) {
440                 exception = e;
441             }
442             if (method == null) {
443                 throw new ReflectionException JavaDoc(exception,
444                                               "Cannot find method " + name +
445                                               " with this signature");
446             }
447             invokeAttMap.put( name, method );
448         }
449
450         // Invoke the selected method on the appropriate object
451
Object JavaDoc result = null;
452         try {
453             if( method.getDeclaringClass().isAssignableFrom( this.getClass()) ) {
454                 result = method.invoke(this, params );
455             } else {
456                 result = method.invoke(resource, params);
457             }
458         } catch (InvocationTargetException JavaDoc e) {
459             Throwable JavaDoc t = e.getTargetException();
460             log.error("Exception invoking method " + name , t );
461             if (t == null)
462                 t = e;
463             if (t instanceof RuntimeException JavaDoc)
464                 throw new RuntimeOperationsException JavaDoc
465                     ((RuntimeException JavaDoc) t, "Exception invoking method " + name);
466             else if (t instanceof Error JavaDoc)
467                 throw new RuntimeErrorException JavaDoc
468                     ((Error JavaDoc) t, "Error invoking method " + name);
469             else
470                 throw new MBeanException JavaDoc
471                     ((Exception JavaDoc)t, "Exception invoking method " + name);
472         } catch (Exception JavaDoc e) {
473             log.error("Exception invoking method " + name , e );
474             throw new MBeanException JavaDoc
475                 (e, "Exception invoking method " + name);
476         }
477
478         // Return the results of this method invocation
479
// FIXME - should we validate the return type?
480
return (result);
481
482     }
483
484     private Class JavaDoc getAttributeClass(String JavaDoc signature)
485         throws ReflectionException JavaDoc
486     {
487         if (signature.equals(Boolean.TYPE.getName()))
488             return Boolean.TYPE;
489         else if (signature.equals(Byte.TYPE.getName()))
490             return Byte.TYPE;
491         else if (signature.equals(Character.TYPE.getName()))
492             return Character.TYPE;
493         else if (signature.equals(Double.TYPE.getName()))
494             return Double.TYPE;
495         else if (signature.equals(Float.TYPE.getName()))
496             return Float.TYPE;
497         else if (signature.equals(Integer.TYPE.getName()))
498             return Integer.TYPE;
499         else if (signature.equals(Long.TYPE.getName()))
500             return Long.TYPE;
501         else if (signature.equals(Short.TYPE.getName()))
502             return Short.TYPE;
503         else {
504             try {
505                 ClassLoader JavaDoc cl=Thread.currentThread().getContextClassLoader();
506                 if( cl!=null )
507                     return cl.loadClass(signature);
508             } catch( ClassNotFoundException JavaDoc e ) {
509             }
510             try {
511                 return Class.forName(signature);
512             } catch (ClassNotFoundException JavaDoc e) {
513                 throw new ReflectionException JavaDoc
514                     (e, "Cannot find Class for " + signature);
515             }
516         }
517     }
518
519     /**
520      * Set the value of a specific attribute of this MBean.
521      *
522      * @param attribute The identification of the attribute to be set
523      * and the new value
524      *
525      * @exception AttributeNotFoundException if this attribute is not
526      * supported by this MBean
527      * @exception MBeanException if the initializer of an object
528      * throws an exception
529      * @exception ReflectionException if a Java reflection exception
530      * occurs when invoking the getter
531      */

532     public void setAttribute(Attribute JavaDoc attribute)
533         throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc,
534         ReflectionException JavaDoc
535     {
536         if( log.isDebugEnabled() )
537             log.debug("Setting attribute " + this + " " + attribute );
538
539         if( (resource instanceof DynamicMBean JavaDoc) &&
540              ! ( resource instanceof BaseModelMBean )) {
541             try {
542                 ((DynamicMBean JavaDoc)resource).setAttribute(attribute);
543             } catch (InvalidAttributeValueException JavaDoc e) {
544                 throw new MBeanException JavaDoc(e);
545             }
546             return;
547         }
548         
549         // Validate the input parameters
550
if (attribute == null)
551             throw new RuntimeOperationsException JavaDoc
552                 (new IllegalArgumentException JavaDoc("Attribute is null"),
553                  "Attribute is null");
554
555         String JavaDoc name = attribute.getName();
556         Object JavaDoc value = attribute.getValue();
557
558         if (name == null)
559             throw new RuntimeOperationsException JavaDoc
560                 (new IllegalArgumentException JavaDoc("Attribute name is null"),
561                  "Attribute name is null");
562
563         ModelMBeanAttributeInfo JavaDoc attrInfo=info.getAttribute(name);
564         if (attrInfo == null)
565             throw new AttributeNotFoundException JavaDoc("Cannot find attribute " + name);
566
567         Descriptor JavaDoc attrDesc=attrInfo.getDescriptor();
568         if (attrDesc == null)
569             throw new AttributeNotFoundException JavaDoc("Cannot find attribute " + name + " descriptor");
570
571         try {
572             // XXX Is it before or after ?
573
Object JavaDoc oldValue=null;
574             if( getAttMap.get(name) != null )
575                 oldValue=getAttribute( name );
576             sendAttributeChangeNotification(new Attribute JavaDoc( name, oldValue),
577                     attribute);
578         } catch( Exception JavaDoc ex ) {
579             log.error( "Error sending notification " + name, ex );
580         }
581
582         // Extract the method from cache
583
Method JavaDoc m=(Method JavaDoc)setAttMap.get( name );
584
585         if( m==null ) {
586             // Look up the actual operation to be used
587
String JavaDoc setMethod = (String JavaDoc) attrDesc.getFieldValue("setMethod");
588             if (setMethod == null)
589                 throw new AttributeNotFoundException JavaDoc("Cannot find attribute " + name + " set method name");
590
591             String JavaDoc argType=attrInfo.getType();
592
593             Class JavaDoc signature[] = new Class JavaDoc[] { getAttributeClass( argType ) };
594
595             Object JavaDoc object = null;
596             NoSuchMethodException JavaDoc exception = null;
597             try {
598                 object = this;
599                 m = object.getClass().getMethod(setMethod, signature);
600             } catch (NoSuchMethodException JavaDoc e) {
601                 exception = e;;
602             }
603             if( m== null && resource != null ) {
604                 try {
605                     object = resource;
606                     m = object.getClass().getMethod(setMethod, signature);
607                     exception=null;
608                 } catch (NoSuchMethodException JavaDoc e) {
609                     if( log.isDebugEnabled())
610                         log.debug("Method not found in resource " +resource);
611                     exception = e;
612                 }
613             }
614             if( exception != null )
615                 throw new ReflectionException JavaDoc(exception,
616                                               "Cannot find setter method " + setMethod +
617                         " " + resource);
618             setAttMap.put( name, m );
619         }
620
621         Object JavaDoc result = null;
622         try {
623             if( m.getDeclaringClass().isAssignableFrom( this.getClass()) ) {
624                 result = m.invoke(this, new Object JavaDoc[] { value });
625             } else {
626                 result = m.invoke(resource, new Object JavaDoc[] { value });
627             }
628         } catch (InvocationTargetException JavaDoc e) {
629             Throwable JavaDoc t = e.getTargetException();
630             if (t == null)
631                 t = e;
632             if (t instanceof RuntimeException JavaDoc)
633                 throw new RuntimeOperationsException JavaDoc
634                     ((RuntimeException JavaDoc) t, "Exception invoking method " + name);
635             else if (t instanceof Error JavaDoc)
636                 throw new RuntimeErrorException JavaDoc
637                     ((Error JavaDoc) t, "Error invoking method " + name);
638             else
639                 throw new MBeanException JavaDoc
640                     (e, "Exception invoking method " + name);
641         } catch (Exception JavaDoc e) {
642             log.error("Exception invoking method " + name , e );
643             throw new MBeanException JavaDoc
644                 (e, "Exception invoking method " + name);
645         }
646
647         attributes.put( name, value );
648         if( source != null ) {
649             // this mbean is asscoiated with a source - maybe we want to persist
650
source.updateField(oname, name, value);
651         }
652     }
653
654     public String JavaDoc toString() {
655         if( resource==null )
656             return "BaseModelMbean[" + resourceType + "]";
657         return resource.toString();