KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > util > modeler > BaseModelMBean


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

17
18
19 package org.apache.tomcat.util.modeler;
20
21
22 import java.lang.reflect.InvocationTargetException JavaDoc;
23 import java.lang.reflect.Method JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26 import javax.management.Attribute JavaDoc;
27 import javax.management.AttributeChangeNotification JavaDoc;
28 import javax.management.AttributeList JavaDoc;
29 import javax.management.AttributeNotFoundException JavaDoc;
30 import javax.management.DynamicMBean JavaDoc;
31 import javax.management.InstanceNotFoundException JavaDoc;
32 import javax.management.InvalidAttributeValueException JavaDoc;
33 import javax.management.ListenerNotFoundException JavaDoc;
34 import javax.management.MBeanException JavaDoc;
35 import javax.management.MBeanInfo JavaDoc;
36 import javax.management.MBeanNotificationInfo JavaDoc;
37 import javax.management.MBeanRegistration JavaDoc;
38 import javax.management.MBeanServer JavaDoc;
39 import javax.management.Notification JavaDoc;
40 import javax.management.NotificationFilter JavaDoc;
41 import javax.management.NotificationListener JavaDoc;
42 import javax.management.ObjectName JavaDoc;
43 import javax.management.ReflectionException JavaDoc;
44 import javax.management.RuntimeErrorException JavaDoc;
45 import javax.management.RuntimeOperationsException JavaDoc;
46 import javax.management.modelmbean.InvalidTargetObjectTypeException JavaDoc;
47 import javax.management.modelmbean.ModelMBeanNotificationBroadcaster JavaDoc;
48
49 import org.apache.commons.logging.Log;
50 import org.apache.commons.logging.LogFactory;
51
52 /*
53  * Changes from commons.modeler:
54  *
55  * - use DynamicMBean
56  * - remove methods not used in tomcat and redundant/not very generic
57  * - must be created from the ManagedBean - I don't think there were any direct
58  * uses, but now it is required.
59  * - some of the gratuituous flexibility removed - instead this is more predictive and
60  * strict with the use cases.
61  * - all Method and metadata is stored in ManagedBean. BaseModelBMean and ManagedBean act
62  * like Object and Class.
63  * - setModelMBean is no longer called on resources ( not used in tomcat )
64  * - no caching of Methods for now - operations and setters are not called repeatedly in most
65  * management use cases. Getters should't be called very frequently either - and even if they
66  * are, the overhead of getting the method should be small compared with other JMX costs ( RMI, etc ).
67  * We can add getter cache if needed.
68  * - removed unused constructor, fields
69  *
70  * TODO:
71  * - clean up catalina.mbeans, stop using weird inheritance
72  */

73
74 /**
75  * <p>Basic implementation of the <code>DynamicMBean</code> interface, which
76  * supports the minimal requirements of the interface contract.</p>
77  *
78  * <p>This can be used directly to wrap an existing java bean, or inside
79  * an mlet or anywhere an MBean would be used.
80  *
81  * Limitations:
82  * <ul>
83  * <li>Only managed resources of type <code>objectReference</code> are
84  * supportd.</li>
85  * <li>Caching of attribute values and operation results is not supported.
86  * All calls to <code>invoke()</code> are immediately executed.</li>
87  * <li>Persistence of MBean attributes and operations is not supported.</li>
88  * <li>All classes referenced as attribute types, operation parameters, or
89  * operation return values must be one of the following:
90  * <ul>
91  * <li>One of the Java primitive types (boolean, byte, char, double,
92  * float, integer, long, short). Corresponding value will be wrapped
93  * in the appropriate wrapper class automatically.</li>
94  * <li>Operations that return no value should declare a return type of
95  * <code>void</code>.</li>
96  * </ul>
97  * <li>Attribute caching is not supported</li>
98  * </ul>
99  *
100  * @author Craig R. McClanahan
101  * @author Costin Manolache
102  */

103 public class BaseModelMBean implements DynamicMBean JavaDoc, MBeanRegistration JavaDoc, ModelMBeanNotificationBroadcaster JavaDoc {
104     private static Log log = LogFactory.getLog(BaseModelMBean.class);
105
106     // ----------------------------------------------------------- Constructors
107

108     /**
109      * Construct a <code>ModelMBean</code> with default
110      * <code>ModelMBeanInfo</code> information.
111      *
112      * @exception MBeanException if the initializer of an object
113      * throws an exception
114      * @exception RuntimeOperationsException if an IllegalArgumentException
115      * occurs
116      */

117     protected BaseModelMBean() throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc {
118         super();
119     }
120
121     // ----------------------------------------------------- Instance Variables
122

123     protected ObjectName JavaDoc oname=null;
124
125     /**
126      * Notification broadcaster for attribute changes.
127      */

128     protected BaseNotificationBroadcaster attributeBroadcaster = null;
129
130     /**
131      * Notification broadcaster for general notifications.
132      */

133     protected BaseNotificationBroadcaster generalBroadcaster = null;
134     
135     /** Metadata for the mbean instance.
136      */

137     protected ManagedBean managedBean = null;
138
139     /**
140      * The managed resource this MBean is associated with (if any).
141      */

142     protected Object JavaDoc resource = null;
143
144     // --------------------------------------------------- DynamicMBean Methods
145
// TODO: move to ManagedBean
146
static final Object JavaDoc[] NO_ARGS_PARAM=new Object JavaDoc[0];
147     static final Class JavaDoc[] NO_ARGS_PARAM_SIG=new Class JavaDoc[0];
148     
149     protected String JavaDoc resourceType = null;
150
151     // key: operation val: invoke method
152
//private Hashtable invokeAttMap=new Hashtable();
153

154     /**
155      * Obtain and return the value of a specific attribute of this MBean.
156      *
157      * @param name Name of the requested attribute
158      *
159      * @exception AttributeNotFoundException if this attribute is not
160      * supported by this MBean
161      * @exception MBeanException if the initializer of an object
162      * throws an exception
163      * @exception ReflectionException if a Java reflection exception
164      * occurs when invoking the getter
165      */

166     public Object JavaDoc getAttribute(String JavaDoc name)
167         throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc,
168             ReflectionException JavaDoc {
169         // Validate the input parameters
170
if (name == null)
171             throw new RuntimeOperationsException JavaDoc
172                 (new IllegalArgumentException JavaDoc("Attribute name is null"),
173                  "Attribute name is null");
174
175         if( (resource instanceof DynamicMBean JavaDoc) &&
176              ! ( resource instanceof BaseModelMBean )) {
177             return ((DynamicMBean JavaDoc)resource).getAttribute(name);
178         }
179         
180         Method JavaDoc m=managedBean.getGetter(name, this, resource);
181         Object JavaDoc result = null;
182         try {
183             Class JavaDoc declaring=m.getDeclaringClass();
184             // workaround for catalina weird mbeans - the declaring class is BaseModelMBean.
185
// but this is the catalina class.
186
if( declaring.isAssignableFrom(this.getClass()) ) {
187                 result = m.invoke(this, NO_ARGS_PARAM );
188             } else {
189                 result = m.invoke(resource, NO_ARGS_PARAM );
190             }
191         } catch (InvocationTargetException JavaDoc e) {
192             Throwable JavaDoc t = e.getTargetException();
193             if (t == null)
194                 t = e;
195             if (t instanceof RuntimeException JavaDoc)
196                 throw new RuntimeOperationsException JavaDoc
197                     ((RuntimeException JavaDoc) t, "Exception invoking method " + name);
198             else if (t instanceof Error JavaDoc)
199                 throw new RuntimeErrorException JavaDoc
200                     ((Error JavaDoc) t, "Error invoking method " + name);
201             else
202                 throw new MBeanException JavaDoc
203                     (e, "Exception invoking method " + name);
204         } catch (Exception JavaDoc e) {
205             throw new MBeanException JavaDoc
206                 (e, "Exception invoking method " + name);
207         }
208
209         // Return the results of this method invocation
210
// FIXME - should we validate the return type?
211
return (result);
212     }
213
214
215     /**
216      * Obtain and return the values of several attributes of this MBean.
217      *
218      * @param names Names of the requested attributes
219      */

220     public AttributeList JavaDoc getAttributes(String JavaDoc names[]) {
221
222         // Validate the input parameters
223
if (names == null)
224             throw new RuntimeOperationsException JavaDoc
225                 (new IllegalArgumentException JavaDoc("Attribute names list is null"),
226                  "Attribute names list is null");
227
228         // Prepare our response, eating all exceptions
229
AttributeList JavaDoc response = new AttributeList JavaDoc();
230         for (int i = 0; i < names.length; i++) {
231             try {
232                 response.add(new Attribute JavaDoc(names[i],getAttribute(names[i])));
233             } catch (Exception JavaDoc e) {
234                 ; // Not having a particular attribute in the response
235
; // is the indication of a getter problem
236
}
237         }
238         return (response);
239
240     }
241
242     public void setManagedBean(ManagedBean managedBean) {
243         this.managedBean = managedBean;
244     }
245
246     /**
247      * Return the <code>MBeanInfo</code> object for this MBean.
248      */

249     public MBeanInfo JavaDoc getMBeanInfo() {
250         return managedBean.getMBeanInfo();
251     }
252
253
254     /**
255      * Invoke a particular method on this MBean, and return any returned
256      * value.
257      *
258      * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation will
259      * attempt to invoke this method on the MBean itself, or (if not
260      * available) on the managed resource object associated with this
261      * MBean.</p>
262      *
263      * @param name Name of the operation to be invoked
264      * @param params Array containing the method parameters of this operation
265      * @param signature Array containing the class names representing
266      * the signature of this operation
267      *
268      * @exception MBeanException if the initializer of an object
269      * throws an exception
270      * @exception ReflectioNException if a Java reflection exception
271      * occurs when invoking a method
272      */

273     public Object JavaDoc invoke(String JavaDoc name, Object JavaDoc params[], String JavaDoc signature[])
274         throws MBeanException JavaDoc, ReflectionException JavaDoc
275     {
276         if( (resource instanceof DynamicMBean JavaDoc) &&
277              ! ( resource instanceof BaseModelMBean )) {
278             return ((DynamicMBean JavaDoc)resource).invoke(name, params, signature);
279         }
280     
281         // Validate the input parameters
282
if (name == null)
283             throw new RuntimeOperationsException JavaDoc
284                 (new IllegalArgumentException JavaDoc("Method name is null"),
285                  "Method name is null");
286
287         if( log.isDebugEnabled()) log.debug("Invoke " + name);
288     MethodKey mkey = new MethodKey(name, signature);
289         Method JavaDoc method= managedBean.getInvoke(name, params, signature, this, resource);
290         
291         // Invoke the selected method on the appropriate object
292
Object JavaDoc result = null;
293         try {
294             if( method.getDeclaringClass().isAssignableFrom( this.getClass()) ) {
295                 result = method.invoke(this, params );
296             } else {
297                 result = method.invoke(resource, params);
298             }
299         } catch (InvocationTargetException JavaDoc e) {
300             Throwable JavaDoc t = e.getTargetException();
301             log.error("Exception invoking method " + name , t );
302             if (t == null)
303                 t = e;
304             if (t instanceof RuntimeException JavaDoc)
305                 throw new RuntimeOperationsException JavaDoc
306                     ((RuntimeException JavaDoc) t, "Exception invoking method " + name);
307             else if (t instanceof Error JavaDoc)
308                 throw new RuntimeErrorException JavaDoc
309                     ((Error JavaDoc) t, "Error invoking method " + name);
310             else
311                 throw new MBeanException JavaDoc
312                     ((Exception JavaDoc)t, "Exception invoking method " + name);
313         } catch (Exception JavaDoc e) {
314             log.error("Exception invoking method " + name , 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     static Class JavaDoc getAttributeClass(String JavaDoc signature)
326         throws ReflectionException JavaDoc
327     {
328         if (signature.equals(Boolean.TYPE.getName()))
329             return Boolean.TYPE;
330         else if (signature.equals(Byte.TYPE.getName()))
331             return Byte.TYPE;
332         else if (signature.equals(Character.TYPE.getName()))
333             return Character.TYPE;
334         else if (signature.equals(Double.TYPE.getName()))
335             return Double.TYPE;
336         else if (signature.equals(Float.TYPE.getName()))
337             return Float.TYPE;
338         else if (signature.equals(Integer.TYPE.getName()))
339             return Integer.TYPE;
340         else if (signature.equals(Long.TYPE.getName()))
341             return Long.TYPE;
342         else if (signature.equals(Short.TYPE.getName()))
343             return Short.TYPE;
344         else {
345             try {
346                 ClassLoader JavaDoc cl=Thread.currentThread().getContextClassLoader();
347                 if( cl!=null )
348                     return cl.loadClass(signature);
349             } catch( ClassNotFoundException JavaDoc e ) {
350             }
351             try {
352                 return Class.forName(signature);
353             } catch (ClassNotFoundException JavaDoc e) {
354                 throw new ReflectionException JavaDoc
355                     (e, "Cannot find Class for " + signature);
356             }
357         }
358     }
359
360     /**
361      * Set the value of a specific attribute of this MBean.
362      *
363      * @param attribute The identification of the attribute to be set
364      * and the new value
365      *
366      * @exception AttributeNotFoundException if this attribute is not
367      * supported by this MBean
368      * @exception MBeanException if the initializer of an object
369      * throws an exception
370      * @exception ReflectionException if a Java reflection exception
371      * occurs when invoking the getter
372      */

373     public void setAttribute(Attribute JavaDoc attribute)
374         throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc,
375         ReflectionException JavaDoc
376     {
377         if( log.isDebugEnabled() )
378             log.debug("Setting attribute " + this + " " + attribute );
379
380         if( (resource instanceof DynamicMBean JavaDoc) &&
381              ! ( resource instanceof BaseModelMBean )) {
382             try {
383                 ((DynamicMBean JavaDoc)resource).setAttribute(attribute);
384             } catch (InvalidAttributeValueException JavaDoc e) {
385                 throw new MBeanException JavaDoc(e);
386             }
387             return;
388         }
389         
390         // Validate the input parameters
391
if (attribute == null)
392             throw new RuntimeOperationsException JavaDoc
393                 (new IllegalArgumentException JavaDoc("Attribute is null"),
394                  "Attribute is null");
395
396         String JavaDoc name = attribute.getName();
397         Object JavaDoc value = attribute.getValue();
398
399         if (name == null)
400             throw new RuntimeOperationsException JavaDoc
401                 (new IllegalArgumentException JavaDoc("Attribute name is null"),
402                  "Attribute name is null");
403
404         Object JavaDoc oldValue=null;
405         //if( getAttMap.get(name) != null )
406
// oldValue=getAttribute( name );
407

408         Method JavaDoc m=managedBean.getSetter(name,this,resource);
409
410         try {
411             if( m.getDeclaringClass().isAssignableFrom( this.getClass()) ) {
412                 m.invoke(this, new Object JavaDoc[] { value });
413             } else {
414                 m.invoke(resource, new Object JavaDoc[] { value });
415             }
416         } catch (InvocationTargetException JavaDoc e) {
417             Throwable JavaDoc t = e.getTargetException();
418             if (t == null)
419                 t = e;
420             if (t instanceof RuntimeException JavaDoc)
421                 throw new RuntimeOperationsException JavaDoc
422                     ((RuntimeException JavaDoc) t, "Exception invoking method " + name);
423             else if (t instanceof Error JavaDoc)
424                 throw new RuntimeErrorException JavaDoc
425                     ((Error JavaDoc) t, "Error invoking method " + name);
426             else
427                 throw new MBeanException JavaDoc
428                     (e, "Exception invoking method " + name);
429         } catch (Exception JavaDoc e) {
430             log.error("Exception invoking method " + name , e );
431             throw new MBeanException JavaDoc
432                 (e, "Exception invoking method " + name);
433         }
434         try {
435             sendAttributeChangeNotification(new Attribute JavaDoc( name, oldValue),
436                     attribute);
437         } catch(Exception JavaDoc ex) {
438             log.error("Error sending notification " + name, ex);
439         }
440         //attributes.put( name, value );
441
// if( source != null ) {
442
// // this mbean is asscoiated with a source - maybe we want to persist
443
// source.updateField(oname, name, value);
444
// }
445
}
446
447     public String JavaDoc toString() {
448         if( resource==null )
449             return "BaseModelMbean[" + resourceType + "]";
450         return resource.toString();
451     }
452
453     /**
454      * Set the values of several attributes of this MBean.
455      *
456      * @param attributes THe names and values to be set
457      *
458      * @return The list of attributes that were set and their new values
459      */

460     public AttributeList JavaDoc setAttributes(AttributeList JavaDoc attributes) {
461         AttributeList JavaDoc response = new AttributeList JavaDoc();
462
463         // Validate the input parameters
464
if (attributes == null)
465             return response;
466         
467         // Prepare and return our response, eating all exceptions
468
String JavaDoc names[] = new String JavaDoc[attributes.size()];
469         int n = 0;
470         Iterator JavaDoc items = attributes.iterator();
471         while (items.hasNext()) {
472             Attribute JavaDoc item = (Attribute JavaDoc) items.next();
473             names[n++] = item.getName();
474             try {
475                 setAttribute(item);
476             } catch (Exception JavaDoc e) {
477                 ; // Ignore all exceptions
478
}
479         }
480
481         return (getAttributes(names));
482
483     }
484
485
486     // ----------------------------------------------------- ModelMBean Methods
487

488
489     /**
490      * Get the instance handle of the object against which we execute
491      * all methods in this ModelMBean management interface.
492      *
493      * @exception InstanceNotFoundException if the managed resource object
494      * cannot be found
495      * @exception MBeanException if the initializer of the object throws
496      * an exception
497      * @exception RuntimeOperationsException if the managed resource or the
498      * resource type is <code>null</code> or invalid
499      */

500     public Object JavaDoc getManagedResource()
501         throws InstanceNotFoundException JavaDoc, InvalidTargetObjectTypeException JavaDoc,
502         MBeanException JavaDoc, RuntimeOperationsException JavaDoc {
503
504         if (resource == null)
505             throw new RuntimeOperationsException JavaDoc
506                 (new IllegalArgumentException JavaDoc("Managed resource is null"),
507                  "Managed resource is null");
508
509         return resource;
510
511     }
512
513
514     /**
515      * Set the instance handle of the object against which we will execute
516      * all methods in this ModelMBean management interface.
517      *
518      * <strike>This method will detect and call "setModelMbean" method. A resource
519      * can implement this method to get a reference to the model mbean.
520      * The reference can be used to send notification and access the
521      * registry.
522      * </strike> The caller can provide the mbean instance or the object name to
523      * the resource, if needed.
524      *
525      * @param resource The resource object to be managed
526      * @param type The type of reference for the managed resource
527      * ("ObjectReference", "Handle", "IOR", "EJBHandle", or
528      * "RMIReference")
529      *
530      * @exception InstanceNotFoundException if the managed resource object
531      * cannot be found
532      * @exception InvalidTargetObjectTypeException if this ModelMBean is
533      * asked to handle a reference type it cannot deal with
534      * @exception MBeanException if the initializer of the object throws
535      * an exception
536      * @exception RuntimeOperationsException if the managed resource or the
537      * resource type is <code>null</code> or invalid
538      */

539     public void setManagedResource(Object JavaDoc resource, String JavaDoc type)
540         throws InstanceNotFoundException JavaDoc,
541         MBeanException JavaDoc, RuntimeOperationsException JavaDoc
542     {
543         if (resource == null)
544             throw new RuntimeOperationsException JavaDoc
545                 (new IllegalArgumentException JavaDoc("Managed resource is null"),
546                  "Managed resource is null");
547
548 // if (!"objectreference".equalsIgnoreCase(type))
549
// throw new InvalidTargetObjectTypeException(type);
550

551         this.resource = resource;
552         this.resourceType = resource.getClass().getName();
553         
554 // // Make the resource aware of the model mbean.
555
// try {
556
// Method m=resource.getClass().getMethod("setModelMBean",
557
// new Class[] {ModelMBean.class});
558
// if( m!= null ) {
559
// m.invoke(resource, new Object[] {this});
560
// }
561
// } catch( NoSuchMethodException t ) {
562
// // ignore
563
// } catch( Throwable t ) {
564
// log.error( "Can't set model mbean ", t );
565
// }
566
}
567
568
569     // ------------------------------ ModelMBeanNotificationBroadcaster Methods
570

571
572     /**
573      * Add an attribute change notification event listener to this MBean.
574      *
575      * @param listener Listener that will receive event notifications
576      * @param name Name of the attribute of interest, or <code>null</code>
577      * to indicate interest in all attributes
578      * @param handback Handback object to be sent along with event
579      * notifications
580      *
581      * @exception IllegalArgumentException if the listener parameter is null
582      */

583     public void addAttributeChangeNotificationListener
584         (NotificationListener JavaDoc listener, String JavaDoc name, Object JavaDoc handback)
585         throws IllegalArgumentException JavaDoc {
586
587         if (listener == null)
588             throw new IllegalArgumentException JavaDoc("Listener is null");
589         if (attributeBroadcaster == null)
590             attributeBroadcaster = new BaseNotificationBroadcaster();
591
592         if( log.isDebugEnabled() )
593             log.debug("addAttributeNotificationListener " + listener);
594
595         BaseAttributeFilter filter = new BaseAttributeFilter(name);
596         attributeBroadcaster.addNotificationListener
597             (listener, filter, handback);
598
599     }
600
601
602     /**
603      * Remove an attribute change notification event listener from
604      * this MBean.
605      *
606      * @param listener The listener to be removed
607      * @param name The attribute name for which no more events are required
608      *
609      *
610      * @exception ListenerNotFoundException if this listener is not
611      * registered in the MBean
612      */

613     public void removeAttributeChangeNotificationListener
614         (NotificationListener JavaDoc listener, String JavaDoc name)
615         throws ListenerNotFoundException JavaDoc {
616
617         if (listener == null)
618             throw new IllegalArgumentException JavaDoc("Listener is null");
619         if (attributeBroadcaster == null)
620             attributeBroadcaster = new BaseNotificationBroadcaster();
621
622         // FIXME - currently this removes *all* notifications for this listener
623
attributeBroadcaster.removeNotificationListener(listener);
624
625     }
626
627
628     /**
629      * Remove an attribute change notification event listener from
630      * this MBean.
631      *
632      * @param listener The listener to be removed
633      * @param attributeName The attribute name for which no more events are required
634      * @param handback Handback object to be sent along with event
635      * notifications
636      *
637      *
638      * @exception ListenerNotFoundException if this listener is not
639      * registered in the MBean
640      */

641     public void removeAttributeChangeNotificationListener
642         (NotificationListener JavaDoc listener, String JavaDoc attributeName, Object JavaDoc handback)
643         throws ListenerNotFoundException JavaDoc {
644
645         removeAttributeChangeNotificationListener(listener, attributeName);
646
647     }
648
649
650     /**
651      * Send an <code>AttributeChangeNotification</code> to all registered
652      * listeners.
653      *
654      * @param notification The <code>AttributeChangeNotification</code>
655      * that will be passed
656      *
657      * @exception MBeanException if an object initializer throws an
658      * exception
659      * @exception RuntimeOperationsException wraps IllegalArgumentException
660      * when the specified notification is <code>null</code> or invalid
661      */

662     public void sendAttributeChangeNotification
663         (AttributeChangeNotification JavaDoc notification)
664         throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc {
665
666         if (notification == null)
667             throw new RuntimeOperationsException JavaDoc
668                 (new IllegalArgumentException JavaDoc("Notification is null"),
669                  "Notification is null");
670         if (attributeBroadcaster == null)
671             return; // This means there are no registered listeners
672
if( log.isDebugEnabled() )
673             log.debug( "AttributeChangeNotification " + notification );
674         attributeBroadcaster.sendNotification(notification);
675
676     }
677
678
679     /**
680      * Send an <code>AttributeChangeNotification</code> to all registered
681      * listeners.
682      *
683      * @param oldValue The original value of the <code>Attribute</code>
684      * @param newValue The new value of the <code>Attribute</code>
685      *
686      * @exception MBeanException if an object initializer throws an
687      * exception
688      * @exception RuntimeOperationsException wraps IllegalArgumentException
689      * when the specified notification is <code>null</code> or invalid
690      */

691     public void sendAttributeChangeNotification
692         (Attribute JavaDoc oldValue, Attribute JavaDoc newValue)
693         throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc {
694
695         // Calculate the class name for the change notification
696
String JavaDoc type = null;
697         if (newValue.getValue() != null)
698             type = newValue.getValue().getClass().getName();
699         else if (oldValue.getValue() != null)
700             type = oldValue.getValue().getClass().getName();
701         else
702             return; // Old and new are both null == no change
703

704         AttributeChangeNotification JavaDoc notification =
705             new AttributeChangeNotification JavaDoc
706             (this, 1, System.currentTimeMillis(),
707              "Attribute value has changed",
708              oldValue.getName(), type,
709              oldValue.getValue(), newValue.getValue());
710         sendAttributeChangeNotification(notification);
711
712     }
713
714
715
716
717     /**
718      * Send a <code>Notification</code> to all registered listeners as a
719      * <code>jmx.modelmbean.general</code> notification.
720      *
721      * @param notification The <code>Notification</code> that will be passed
722      *
723      * @exception MBeanException if an object initializer throws an
724      * exception
725      * @exception RuntimeOperationsException wraps IllegalArgumentException
726      * when the specified notification is <code>null</code> or invalid
727      */

728     public void sendNotification(Notification JavaDoc notification)
729         throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc {
730
731         if (notification == null)
732             throw new RuntimeOperationsException JavaDoc
733                 (new IllegalArgumentException JavaDoc("Notification is null"),
734                  "Notification is null");
735         if (generalBroadcaster == null)
736             return; // This means there are no registered listeners
737
generalBroadcaster.sendNotification(notification);
738
739     }
740
741
742     /**
743      * Send a <code>Notification</code> which contains the specified string
744      * as a <code>jmx.modelmbean.generic</code> notification.
745      *
746      * @param message The message string to be passed
747      *
748      * @exception MBeanException if an object initializer throws an
749      * exception
750      * @exception RuntimeOperationsException wraps IllegalArgumentException
751      * when the specified notification is <code>null</code> or invalid
752      */

753     public void sendNotification(String JavaDoc message)
754         throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc {
755
756         if (message == null)
757             throw new RuntimeOperationsException JavaDoc
758                 (new IllegalArgumentException JavaDoc("Message is null"),
759                  "Message is null");
760         Notification JavaDoc notification = new Notification JavaDoc
761             ("jmx.modelmbean.generic", this, 1, message);
762         sendNotification(notification);
763
764     }
765
766
767
768
769     // ---------------------------------------- NotificationBroadcaster Methods
770

771
772     /**
773      * Add a notification event listener to this MBean.
774      *
775      * @param listener Listener that will receive event notifications
776      * @param filter Filter object used to filter event notifications
777      * actually delivered, or <code>null</code> for no filtering
778      * @param handback Handback object to be sent along with event
779      * notifications
780      *
781      * @exception IllegalArgumentException if the listener parameter is null
782      */

783     public void addNotificationListener(NotificationListener JavaDoc listener,
784                                         NotificationFilter JavaDoc filter,
785                                         Object JavaDoc handback)
786         throws IllegalArgumentException JavaDoc {
787
788         if (listener == null)
789             throw new IllegalArgumentException JavaDoc("Listener is null");
790
791         if( log.isDebugEnabled() ) log.debug("addNotificationListener " + listener);
792
793         if (generalBroadcaster == null)
794             generalBroadcaster = new BaseNotificationBroadcaster();
795         generalBroadcaster.addNotificationListener
796             (listener, filter, handback);
797
798         // We'll send the attribute change notifications to all listeners ( who care )
799
// The normal filtering can be used.
800
// The problem is that there is no other way to add attribute change listeners
801
// to a model mbean ( AFAIK ). I suppose the spec should be fixed.
802
if (attributeBroadcaster == null)
803             attributeBroadcaster = new BaseNotificationBroadcaster();
804
805         if( log.isDebugEnabled() )
806             log.debug("addAttributeNotificationListener " + listener);
807
808         attributeBroadcaster.addNotificationListener
809                 (listener, filter, handback);
810     }
811
812
813     /**
814      * Return an <code>MBeanNotificationInfo</code> object describing the
815      * notifications sent by this MBean.
816      */

817     public MBeanNotificationInfo JavaDoc[] getNotificationInfo() {
818
819         // Acquire the set of application notifications
820
MBeanNotificationInfo JavaDoc current[] = getMBeanInfo().getNotifications();
821         if (current == null)
822             current = new MBeanNotificationInfo JavaDoc[0];
823         MBeanNotificationInfo JavaDoc response[] =
824             new MBeanNotificationInfo JavaDoc[current.length + 2];
825  // Descriptor descriptor = null;
826

827         // Fill in entry for general notifications
828
// descriptor = new DescriptorSupport
829
// (new String[] { "name=GENERIC",
830
// "descriptorType=notification",
831
// "log=T",
832
// "severity=5",
833
// "displayName=jmx.modelmbean.generic" });
834
response[0] = new MBeanNotificationInfo JavaDoc
835             (new String JavaDoc[] { "jmx.modelmbean.generic" },
836              "GENERIC",
837              "Text message notification from the managed resource");
838              //descriptor);
839

840         // Fill in entry for attribute change notifications
841
// descriptor = new DescriptorSupport
842
// (new String[] { "name=ATTRIBUTE_CHANGE",
843
// "descriptorType=notification",
844
// "log=T",
845
// "severity=5",
846
// "displayName=jmx.attribute.change" });
847
response[1] = new MBeanNotificationInfo JavaDoc
848             (new String JavaDoc[] { "jmx.attribute.change" },
849              "ATTRIBUTE_CHANGE",
850              "Observed MBean attribute value has changed");
851              //descriptor);
852

853         // Copy remaining notifications as reported by the application
854
System.arraycopy(current, 0, response, 2, current.length);
855         return (response);
856
857     }
858
859
860     /**
861      * Remove a notification event listener from this MBean.
862      *
863      * @param listener The listener to be removed (any and all registrations
864      * for this listener will be eliminated)
865      *
866      * @exception ListenerNotFoundException if this listener is not
867      * registered in the MBean
868      */

869     public void removeNotificationListener(NotificationListener JavaDoc listener)
870         throws ListenerNotFoundException JavaDoc {
871
872         if (listener == null)
873             throw new IllegalArgumentException JavaDoc("Listener is null");
874         if (generalBroadcaster == null)
875             generalBroadcaster = new BaseNotificationBroadcaster();
876         generalBroadcaster.removeNotificationListener(listener);
877
878
879     }
880
881
882     /**
883      * Remove a notification event listener from this MBean.
884      *
885      * @param listener The listener to be removed (any and all registrations
886      * for this listener will be eliminated)
887      * @param handback Handback object to be sent along with event
888      * notifications
889      *
890      * @exception ListenerNotFoundException if this listener is not
891      * registered in the MBean
892      */

893     public void removeNotificationListener(NotificationListener JavaDoc listener,
894                                            Object JavaDoc handback)
895         throws ListenerNotFoundException JavaDoc {
896
897         removeNotificationListener(listener);
898
899     }
900
901
902     /**
903      * Remove a notification event listener from this MBean.
904      *
905      * @param listener The listener to be removed (any and all registrations
906      * for this listener will be eliminated)
907      * @param filter Filter object used to filter event notifications
908      * actually delivered, or <code>null</code> for no filtering
909      * @param handback Handback object to be sent along with event
910      * notifications
911      *
912      * @exception ListenerNotFoundException if this listener is not
913      * registered in the MBean
914      */

915     public void removeNotificationListener(NotificationListener JavaDoc listener,
916                                            NotificationFilter JavaDoc filter,
917                                            Object JavaDoc handback)
918         throws ListenerNotFoundException JavaDoc {
919
920         removeNotificationListener(listener);
921
922     }
923
924
925     // ------------------------------------------------ PersistentMBean Methods
926

927
928     /**
929      * Instantiates this MBean instance from data found in the persistent
930      * store. The data loaded could include attribute and operation values.
931      * This method should be called during construction or initialization
932      * of the instance, and before the MBean is registered with the
933      * <code>MBeanServer</code>.
934      *
935      * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation does
936      * not support persistence.</p>
937      *
938      * @exception InstanceNotFoundException if the managed resource object
939      * cannot be found
940      * @exception MBeanException if the initializer of the object throws
941      * an exception
942      * @exception RuntimeOperationsException if an exception is reported
943      * by the persistence mechanism
944      */

945 // public void load() throws InstanceNotFoundException,
946
// MBeanException, RuntimeOperationsException {
947
// // XXX If a context was set, use it to load the data
948
// throw new MBeanException
949
// (new IllegalStateException("Persistence is not supported"),
950
// "Persistence is not supported");
951
//
952
// }
953

954
955     /**
956      * Capture the current state of this MBean instance and write it out
957      * to the persistent store. The state stored could include attribute
958      * and operation values. If one of these methods of persistence is not
959      * supported, a "service not found" exception will be thrown.
960      *
961      * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation does
962      * not support persistence.</p>
963      *
964      * @exception InstanceNotFoundException if the managed resource object
965      * cannot be found
966      * @exception MBeanException if the initializer of the object throws
967      * an exception, or persistence is not supported
968      * @exception RuntimeOperationsException if an exception is reported
969      * by the persistence mechanism
970      */

971 // public void store() throws InstanceNotFoundException,
972
// MBeanException, RuntimeOperationsException {
973
//
974
// // XXX if a context was set, use it to store the data
975
// throw new MBeanException
976
// (new IllegalStateException("Persistence is not supported"),
977
// "Persistence is not supported");
978
//
979
// }
980

981     // -------------------- BaseModelMBean methods --------------------
982

983     /** Set the type of the mbean. This is used as a key to locate
984      * the description in the Registry.
985      *
986      * @param type the type of classname of the modeled object
987      */

988 // void setModeledType( String type ) {
989
// initModelInfo(type);
990
// createResource();
991
// }
992
/** Set the type of the mbean. This is used as a key to locate
993      * the description in the Registry.
994      *
995      * @param type the type of classname of the modeled object
996      */

997 // void initModelInfo( String type ) {
998
// try {
999
// if( log.isDebugEnabled())
1000
// log.debug("setModeledType " + type);
1001
//
1002
// log.debug( "Set model Info " + type);
1003
// if(type==null) {
1004
// return;
1005
// }
1006
// resourceType=type;
1007
// //Thread.currentThread().setContextClassLoader(BaseModelMBean.class.getClassLoader());
1008
// Class c=null;
1009
// try {
1010
// c=Class.forName( type);
1011
// } catch( Throwable t ) {
1012
// log.debug( "Error creating class " + t);
1013
// }
1014
//
1015
// // The class c doesn't need to exist
1016
// ManagedBean descriptor=getRegistry().findManagedBean(c, type);
1017
// if( descriptor==null )
1018
// return;
1019
// this.setModelMBeanInfo(descriptor.createMBeanInfo());
1020
// } catch( Throwable ex) {
1021
// log.error( "TCL: " + Thread.currentThread().getContextClassLoader(),
1022
// ex);
1023
// }
1024
// }
1025

1026    /** Set the type of the mbean. This is used as a key to locate
1027     * the description in the Registry.
1028     */

1029// protected void createResource() {
1030
// try {
1031
// //Thread.currentThread().setContextClassLoader(BaseModelMBean.class.getClassLoader());
1032
// Class c=null;
1033
// try {
1034
// c=Class.forName( resourceType );
1035
// resource = c.newInstance();
1036
// } catch( Throwable t ) {
1037
// log.error( "Error creating class " + t);
1038
// }
1039
// } catch( Throwable ex) {
1040
// log.error( "TCL: " + Thread.currentThread().getContextClassLoader(),
1041
// ex);
1042
// }
1043
// }
1044

1045
1046    public String JavaDoc getModelerType() {
1047        return resourceType;
1048    }
1049
1050    public String JavaDoc getClassName() {
1051        return getModelerType();
1052    }
1053
1054    public ObjectName JavaDoc getJmxName() {
1055        return oname;
1056    }
1057
1058    public String JavaDoc getObjectName() {
1059        if (oname != null) {
1060            return oname.toString();
1061        } else {
1062            return null;
1063        }
1064    }
1065
1066// public void setRegistry(Registry registry) {
1067
// this.registry = registry;
1068
// }
1069
//
1070
// public Registry getRegistry() {
1071
// // XXX Need a better solution - to avoid the static
1072
// if( registry == null )
1073
// registry=Registry.getRegistry();
1074
//
1075
// return registry;
1076
// }
1077

1078    // ------------------------------------------------------ Protected Methods
1079

1080
1081    /**
1082     * Create and return a default <code>ModelMBeanInfo</code> object.
1083     */

1084// protected ModelMBeanInfo createDefaultModelMBeanInfo() {
1085
//
1086
// return (new ModelMBeanInfoSupport(this.getClass().getName(),
1087
// "Default ModelMBean",
1088
// null, null, null, null));
1089
//
1090
// }
1091

1092    /**
1093     * Is the specified <code>ModelMBeanInfo</code> instance valid?
1094     *
1095     * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation
1096     * does not check anything, but this method can be overridden
1097     * as required.</p>
1098     *
1099     * @param info The <code>ModelMBeanInfo object to check
1100     */

1101// protected boolean isModelMBeanInfoValid(ModelMBeanInfo info) {
1102
// return (true);
1103
// }
1104

1105    // -------------------- Registration --------------------
1106
// XXX We can add some method patterns here- like setName() and
1107
// setDomain() for code that doesn't implement the Registration
1108

1109    public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server,
1110                                  ObjectName JavaDoc name)
1111            throws Exception JavaDoc
1112    {
1113        if( log.isDebugEnabled())
1114            log.debug("preRegister " + resource + " " + name );
1115        oname=name;
1116        if( resource instanceof MBeanRegistration JavaDoc ) {
1117            oname = ((MBeanRegistration JavaDoc)resource).preRegister(server, name );
1118        }
1119        return oname;
1120    }
1121
1122    public void postRegister(Boolean JavaDoc registrationDone) {
1123        if( resource instanceof MBeanRegistration JavaDoc ) {
1124            ((MBeanRegistration JavaDoc)resource).postRegister(registrationDone);
1125        }
1126    }
1127
1128    public void preDeregister() throws Exception JavaDoc {
1129        if( resource instanceof MBeanRegistration JavaDoc ) {
1130            ((MBeanRegistration JavaDoc)resource).preDeregister();
1131        }
1132    }
1133
1134    public void postDeregister() {
1135        if( resource instanceof MBeanRegistration JavaDoc ) {
1136            ((MBeanRegistration JavaDoc)resource).postDeregister();
1137        }
1138    }
1139
1140    static class MethodKey {
1141    private String JavaDoc name;
1142    private String JavaDoc[] signature;
1143
1144    MethodKey(String JavaDoc name, String JavaDoc[] signature) {
1145        this.name = name;
1146        if(signature == null) {
1147        signature = new String JavaDoc[0];
1148        }
1149        this.signature = signature;
1150    }
1151
1152    public boolean equals(Object JavaDoc other) {
1153        if(!(other instanceof MethodKey)) {
1154        return false;
1155        }
1156        MethodKey omk = (MethodKey)other;
1157        if(!name.equals(omk.name)) {
1158        return false;
1159        }
1160        if(signature.length != omk.signature.length) {
1161        return false;
1162        }
1163        for(int i=0; i < signature.length; i++) {
1164        if(!signature[i].equals(omk.signature[i])) {
1165            return false;
1166        }
1167        }
1168        return true;
1169    }
1170
1171    public int hashCode() {
1172        return name.hashCode();
1173    }
1174    }
1175}
1176
Popular Tags