jdk/src/share/classes/javax/management/StandardEmitterMBean.java
changeset 4156 acaa49a2768a
parent 1636 eb801ce73ac9
child 5506 202f599c92aa
equal deleted inserted replaced
4155:460e37d40f12 4156:acaa49a2768a
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    23  * have any questions.
    24  */
    24  */
    25 
    25 
    26 package javax.management;
    26 package javax.management;
    27 
       
    28 import com.sun.jmx.mbeanserver.MBeanInjector;
       
    29 import com.sun.jmx.mbeanserver.MBeanIntrospector;
       
    30 import static javax.management.JMX.MBeanOptions;
       
    31 
    27 
    32 /**
    28 /**
    33  * <p>An MBean whose management interface is determined by reflection
    29  * <p>An MBean whose management interface is determined by reflection
    34  * on a Java interface, and that emits notifications.</p>
    30  * on a Java interface, and that emits notifications.</p>
    35  *
    31  *
    64  * @see StandardMBean
    60  * @see StandardMBean
    65  *
    61  *
    66  * @since 1.6
    62  * @since 1.6
    67  */
    63  */
    68 public class StandardEmitterMBean extends StandardMBean
    64 public class StandardEmitterMBean extends StandardMBean
    69         implements NotificationEmitter, SendNotification {
    65         implements NotificationEmitter {
    70 
    66 
    71     private final NotificationEmitter emitter;
    67     private final NotificationEmitter emitter;
    72     private final MBeanNotificationInfo[] notificationInfo;
    68     private final MBeanNotificationInfo[] notificationInfo;
    73 
    69 
    74     /**
    70     /**
    78      * The resultant MBean implements the {@code NotificationEmitter} interface
    74      * The resultant MBean implements the {@code NotificationEmitter} interface
    79      * by forwarding its methods to {@code emitter}.  It is legal and useful
    75      * by forwarding its methods to {@code emitter}.  It is legal and useful
    80      * for {@code implementation} and {@code emitter} to be the same object.</p>
    76      * for {@code implementation} and {@code emitter} to be the same object.</p>
    81      *
    77      *
    82      * <p>If {@code emitter} is an instance of {@code
    78      * <p>If {@code emitter} is an instance of {@code
    83      * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
    79      * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
    84      * then the MBean's {@link #sendNotification
    80      * sendNotification} method will call {@code emitter.}{@link
    85      * sendNotification} method will call {@code emitter.}{@link
    81      * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
    86      * SendNotification#sendNotification sendNotification}.</p>
       
    87      *
    82      *
    88      * <p>The array returned by {@link #getNotificationInfo()} on the
    83      * <p>The array returned by {@link #getNotificationInfo()} on the
    89      * new MBean is a copy of the array returned by
    84      * new MBean is a copy of the array returned by
    90      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
    85      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
    91      * getNotificationInfo()} at the time of construction.  If the array
    86      * getNotificationInfo()} at the time of construction.  If the array
    93      * that will have no effect on this object's
    88      * that will have no effect on this object's
    94      * {@code getNotificationInfo()}.</p>
    89      * {@code getNotificationInfo()}.</p>
    95      *
    90      *
    96      * @param implementation the implementation of the MBean interface.
    91      * @param implementation the implementation of the MBean interface.
    97      * @param mbeanInterface a Standard MBean interface.
    92      * @param mbeanInterface a Standard MBean interface.
    98      * @param emitter the object that will handle notifications.  If null,
    93      * @param emitter the object that will handle notifications.
    99      * a new {@code NotificationEmitter} will be constructed that also
       
   100      * implements {@link SendNotification}.
       
   101      *
    94      *
   102      * @throws IllegalArgumentException if the {@code mbeanInterface}
    95      * @throws IllegalArgumentException if the {@code mbeanInterface}
   103      *    does not follow JMX design patterns for Management Interfaces, or
    96      *    does not follow JMX design patterns for Management Interfaces, or
   104      *    if the given {@code implementation} does not implement the
    97      *    if the given {@code implementation} does not implement the
   105      *    specified interface.
    98      *    specified interface, or if {@code emitter} is null.
   106      */
    99      */
   107     public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
   100     public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
   108                                     NotificationEmitter emitter) {
   101                                     NotificationEmitter emitter) {
   109         this(implementation, mbeanInterface, false, emitter);
   102         super(implementation, mbeanInterface, false);
       
   103         if (emitter == null)
       
   104             throw new IllegalArgumentException("Null emitter");
       
   105         this.emitter = emitter;
       
   106         this.notificationInfo = emitter.getNotificationInfo();
   110     }
   107     }
   111 
   108 
   112     /**
   109     /**
   113      * <p>Make an MBean whose management interface is specified by
   110      * <p>Make an MBean whose management interface is specified by
   114      * {@code mbeanInterface}, with the given implementation and where
   111      * {@code mbeanInterface}, with the given implementation and where
   119      * forwarding its methods to {@code emitter}.  It is legal and
   116      * forwarding its methods to {@code emitter}.  It is legal and
   120      * useful for {@code implementation} and {@code emitter} to be the
   117      * useful for {@code implementation} and {@code emitter} to be the
   121      * same object.</p>
   118      * same object.</p>
   122      *
   119      *
   123      * <p>If {@code emitter} is an instance of {@code
   120      * <p>If {@code emitter} is an instance of {@code
   124      * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
   121      * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
   125      * then the MBean's {@link #sendNotification
   122      * sendNotification} method will call {@code emitter.}{@link
   126      * sendNotification} method will call {@code emitter.}{@link
   123      * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
   127      * SendNotification#sendNotification sendNotification}.</p>
       
   128      *
   124      *
   129      * <p>The array returned by {@link #getNotificationInfo()} on the
   125      * <p>The array returned by {@link #getNotificationInfo()} on the
   130      * new MBean is a copy of the array returned by
   126      * new MBean is a copy of the array returned by
   131      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
   127      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
   132      * getNotificationInfo()} at the time of construction.  If the array
   128      * getNotificationInfo()} at the time of construction.  If the array
   136      *
   132      *
   137      * @param implementation the implementation of the MBean interface.
   133      * @param implementation the implementation of the MBean interface.
   138      * @param mbeanInterface a Standard MBean interface.
   134      * @param mbeanInterface a Standard MBean interface.
   139      * @param isMXBean If true, the {@code mbeanInterface} parameter
   135      * @param isMXBean If true, the {@code mbeanInterface} parameter
   140      * names an MXBean interface and the resultant MBean is an MXBean.
   136      * names an MXBean interface and the resultant MBean is an MXBean.
   141      * @param emitter the object that will handle notifications.  If null,
   137      * @param emitter the object that will handle notifications.
   142      * a new {@code NotificationEmitter} will be constructed that also
       
   143      * implements {@link SendNotification}.
       
   144      *
   138      *
   145      * @throws IllegalArgumentException if the {@code mbeanInterface}
   139      * @throws IllegalArgumentException if the {@code mbeanInterface}
   146      *    does not follow JMX design patterns for Management Interfaces, or
   140      *    does not follow JMX design patterns for Management Interfaces, or
   147      *    if the given {@code implementation} does not implement the
   141      *    if the given {@code implementation} does not implement the
   148      *    specified interface.
   142      *    specified interface, or if {@code emitter} is null.
   149      */
   143      */
   150     public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
   144     public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
   151                                     boolean isMXBean,
   145                                     boolean isMXBean,
   152                                     NotificationEmitter emitter) {
   146                                     NotificationEmitter emitter) {
   153         this(implementation, mbeanInterface,
   147         super(implementation, mbeanInterface, isMXBean);
   154                 isMXBean ? MBeanOptions.MXBEAN : null, emitter);
   148         if (emitter == null)
   155     }
   149             throw new IllegalArgumentException("Null emitter");
   156 
   150         this.emitter = emitter;
   157     /**
   151         this.notificationInfo = emitter.getNotificationInfo();
   158      * <p>Make an MBean whose management interface is specified by {@code
       
   159      * mbeanInterface}, with the given implementation and options, and where
       
   160      * notifications are handled by the given {@code NotificationEmitter}.
       
   161      * Options select whether to make a Standard MBean or an MXBean, and
       
   162      * whether the result of {@link #getWrappedObject()} is the {@code
       
   163      * StandardEmitterMBean} object or the given implementation. The resultant
       
   164      * MBean implements the {@code NotificationEmitter} interface by forwarding
       
   165      * its methods to {@code emitter}. It is legal and useful for {@code
       
   166      * implementation} and {@code emitter} to be the same object.</p>
       
   167      *
       
   168      * <p>If {@code emitter} is an instance of {@code
       
   169      * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
       
   170      * then the MBean's {@link #sendNotification
       
   171      * sendNotification} method will call {@code emitter.}{@link
       
   172      * SendNotification#sendNotification sendNotification}.</p>
       
   173      *
       
   174      * <p>The array returned by {@link #getNotificationInfo()} on the
       
   175      * new MBean is a copy of the array returned by
       
   176      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
       
   177      * getNotificationInfo()} at the time of construction.  If the array
       
   178      * returned by {@code emitter.getNotificationInfo()} later changes,
       
   179      * that will have no effect on this object's
       
   180      * {@code getNotificationInfo()}.</p>
       
   181      *
       
   182      * @param implementation the implementation of the MBean interface.
       
   183      * @param mbeanInterface a Standard MBean interface.
       
   184      * @param options MBeanOptions that control the operation of the resulting
       
   185      * MBean.
       
   186      * @param emitter the object that will handle notifications.  If null,
       
   187      * a new {@code NotificationEmitter} will be constructed that also
       
   188      * implements {@link SendNotification}.
       
   189      *
       
   190      * @throws IllegalArgumentException if the {@code mbeanInterface}
       
   191      *    does not follow JMX design patterns for Management Interfaces, or
       
   192      *    if the given {@code implementation} does not implement the
       
   193      *    specified interface.
       
   194      */
       
   195     public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
       
   196                                     MBeanOptions options,
       
   197                                     NotificationEmitter emitter) {
       
   198         super(implementation, mbeanInterface, options);
       
   199         MBeanNotificationInfo[] defaultMBNIs = defaultMBNIs(implementation);
       
   200         if (emitter == null)
       
   201             emitter = defaultEmitter(defaultMBNIs);
       
   202         this.emitter = emitter;
       
   203         this.notificationInfo =
       
   204                 firstNonEmpty(emitter.getNotificationInfo(), defaultMBNIs);
       
   205         injectEmitter();
       
   206     }
   152     }
   207 
   153 
   208     /**
   154     /**
   209      * <p>Make an MBean whose management interface is specified by
   155      * <p>Make an MBean whose management interface is specified by
   210      * {@code mbeanInterface}, and
   156      * {@code mbeanInterface}, and
   211      * where notifications are handled by the given {@code NotificationEmitter}.
   157      * where notifications are handled by the given {@code NotificationEmitter}.
   212      * The resultant MBean implements the {@code NotificationEmitter} interface
   158      * The resultant MBean implements the {@code NotificationEmitter} interface
   213      * by forwarding its methods to {@code emitter}.</p>
   159      * by forwarding its methods to {@code emitter}.</p>
   214      *
   160      *
   215      * <p>If {@code emitter} is an instance of {@code
   161      * <p>If {@code emitter} is an instance of {@code
   216      * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
   162      * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
   217      * then the MBean's {@link #sendNotification
   163      * sendNotification} method will call {@code emitter.}{@link
   218      * sendNotification} method will call {@code emitter.}{@link
   164      * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
   219      * SendNotification#sendNotification sendNotification}.</p>
       
   220      *
   165      *
   221      * <p>The array returned by {@link #getNotificationInfo()} on the
   166      * <p>The array returned by {@link #getNotificationInfo()} on the
   222      * new MBean is a copy of the array returned by
   167      * new MBean is a copy of the array returned by
   223      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
   168      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
   224      * getNotificationInfo()} at the time of construction.  If the array
   169      * getNotificationInfo()} at the time of construction.  If the array
   228      *
   173      *
   229      * <p>This constructor must be called from a subclass that implements
   174      * <p>This constructor must be called from a subclass that implements
   230      * the given {@code mbeanInterface}.</p>
   175      * the given {@code mbeanInterface}.</p>
   231      *
   176      *
   232      * @param mbeanInterface a StandardMBean interface.
   177      * @param mbeanInterface a StandardMBean interface.
   233      * @param emitter the object that will handle notifications.  If null,
   178      * @param emitter the object that will handle notifications.
   234      * a new {@code NotificationEmitter} will be constructed that also
   179      *
   235      * implements {@link SendNotification}.
   180      * @throws IllegalArgumentException if the {@code mbeanInterface}
   236      *
   181      *    does not follow JMX design patterns for Management Interfaces, or
   237      * @throws IllegalArgumentException if the {@code mbeanInterface}
   182      *    if {@code this} does not implement the specified interface, or
   238      *    does not follow JMX design patterns for Management Interfaces, or
   183      *    if {@code emitter} is null.
   239      *    if {@code this} does not implement the specified interface.
       
   240      */
   184      */
   241     protected StandardEmitterMBean(Class<?> mbeanInterface,
   185     protected StandardEmitterMBean(Class<?> mbeanInterface,
   242                                    NotificationEmitter emitter) {
   186                                    NotificationEmitter emitter) {
   243         this(mbeanInterface, false, emitter);
   187         super(mbeanInterface, false);
       
   188         if (emitter == null)
       
   189             throw new IllegalArgumentException("Null emitter");
       
   190         this.emitter = emitter;
       
   191         this.notificationInfo = emitter.getNotificationInfo();
   244     }
   192     }
   245 
   193 
   246     /**
   194     /**
   247      * <p>Make an MBean whose management interface is specified by
   195      * <p>Make an MBean whose management interface is specified by
   248      * {@code mbeanInterface}, and where notifications are handled by
   196      * {@code mbeanInterface}, and where notifications are handled by
   250      * used to make either Standard MBeans or MXBeans.  The resultant
   198      * used to make either Standard MBeans or MXBeans.  The resultant
   251      * MBean implements the {@code NotificationEmitter} interface by
   199      * MBean implements the {@code NotificationEmitter} interface by
   252      * forwarding its methods to {@code emitter}.</p>
   200      * forwarding its methods to {@code emitter}.</p>
   253      *
   201      *
   254      * <p>If {@code emitter} is an instance of {@code
   202      * <p>If {@code emitter} is an instance of {@code
   255      * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
   203      * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
   256      * then the MBean's {@link #sendNotification
   204      * sendNotification} method will call {@code emitter.}{@link
   257      * sendNotification} method will call {@code emitter.}{@link
   205      * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
   258      * SendNotification#sendNotification sendNotification}.</p>
       
   259      *
   206      *
   260      * <p>The array returned by {@link #getNotificationInfo()} on the
   207      * <p>The array returned by {@link #getNotificationInfo()} on the
   261      * new MBean is a copy of the array returned by
   208      * new MBean is a copy of the array returned by
   262      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
   209      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
   263      * getNotificationInfo()} at the time of construction.  If the array
   210      * getNotificationInfo()} at the time of construction.  If the array
   269      * the given {@code mbeanInterface}.</p>
   216      * the given {@code mbeanInterface}.</p>
   270      *
   217      *
   271      * @param mbeanInterface a StandardMBean interface.
   218      * @param mbeanInterface a StandardMBean interface.
   272      * @param isMXBean If true, the {@code mbeanInterface} parameter
   219      * @param isMXBean If true, the {@code mbeanInterface} parameter
   273      * names an MXBean interface and the resultant MBean is an MXBean.
   220      * names an MXBean interface and the resultant MBean is an MXBean.
   274      * @param emitter the object that will handle notifications.  If null,
   221      * @param emitter the object that will handle notifications.
   275      * a new {@code NotificationEmitter} will be constructed that also
   222      *
   276      * implements {@link SendNotification}.
   223      * @throws IllegalArgumentException if the {@code mbeanInterface}
   277      *
   224      *    does not follow JMX design patterns for Management Interfaces, or
   278      * @throws IllegalArgumentException if the {@code mbeanInterface}
   225      *    if {@code this} does not implement the specified interface, or
   279      *    does not follow JMX design patterns for Management Interfaces, or
   226      *    if {@code emitter} is null.
   280      *    if {@code this} does not implement the specified interface.
       
   281      */
   227      */
   282     protected StandardEmitterMBean(Class<?> mbeanInterface, boolean isMXBean,
   228     protected StandardEmitterMBean(Class<?> mbeanInterface, boolean isMXBean,
   283                                    NotificationEmitter emitter) {
   229                                    NotificationEmitter emitter) {
   284         this(mbeanInterface, isMXBean ? MBeanOptions.MXBEAN : null, emitter);
   230         super(mbeanInterface, isMXBean);
   285     }
   231         if (emitter == null)
   286 
   232             throw new IllegalArgumentException("Null emitter");
   287     /**
   233         this.emitter = emitter;
   288      * <p>Make an MBean whose management interface is specified by {@code
   234         this.notificationInfo = emitter.getNotificationInfo();
   289      * mbeanInterface}, with the given options, and where notifications are
       
   290      * handled by the given {@code NotificationEmitter}. This constructor can
       
   291      * be used to make either Standard MBeans or MXBeans. The resultant MBean
       
   292      * implements the {@code NotificationEmitter} interface by forwarding its
       
   293      * methods to {@code emitter}.</p>
       
   294      *
       
   295      * <p>If {@code emitter} is an instance of {@code
       
   296      * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
       
   297      * then the MBean's {@link #sendNotification
       
   298      * sendNotification} method will call {@code emitter.}{@link
       
   299      * SendNotification#sendNotification sendNotification}.</p>
       
   300      *
       
   301      * <p>The array returned by {@link #getNotificationInfo()} on the
       
   302      * new MBean is a copy of the array returned by
       
   303      * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
       
   304      * getNotificationInfo()} at the time of construction.  If the array
       
   305      * returned by {@code emitter.getNotificationInfo()} later changes,
       
   306      * that will have no effect on this object's
       
   307      * {@code getNotificationInfo()}.</p>
       
   308      *
       
   309      * <p>This constructor must be called from a subclass that implements
       
   310      * the given {@code mbeanInterface}.</p>
       
   311      *
       
   312      * @param mbeanInterface a StandardMBean interface.
       
   313      * @param options MBeanOptions that control the operation of the resulting
       
   314      * MBean.
       
   315      * @param emitter the object that will handle notifications.  If null,
       
   316      * a new {@code NotificationEmitter} will be constructed that also
       
   317      * implements {@link SendNotification}.
       
   318      *
       
   319      * @throws IllegalArgumentException if the {@code mbeanInterface}
       
   320      *    does not follow JMX design patterns for Management Interfaces, or
       
   321      *    if {@code this} does not implement the specified interface.
       
   322      */
       
   323     protected StandardEmitterMBean(Class<?> mbeanInterface, MBeanOptions options,
       
   324                                    NotificationEmitter emitter) {
       
   325         super(mbeanInterface, options);
       
   326         MBeanNotificationInfo[] defaultMBNIs = defaultMBNIs(this);
       
   327         if (emitter == null)
       
   328             emitter = defaultEmitter(defaultMBNIs);
       
   329         this.emitter = emitter;
       
   330         this.notificationInfo =
       
   331                 firstNonEmpty(emitter.getNotificationInfo(), defaultMBNIs);
       
   332         injectEmitter();
       
   333     }
       
   334 
       
   335     private static MBeanNotificationInfo[] defaultMBNIs(Object mbean) {
       
   336         return MBeanIntrospector.findNotificationsFromAnnotations(
       
   337                 mbean.getClass());
       
   338     }
       
   339 
       
   340     private NotificationEmitter defaultEmitter(MBeanNotificationInfo[] defaultMBNIs) {
       
   341         MBeanNotificationInfo[] mbnis =
       
   342                 firstNonEmpty(getNotificationInfo(), defaultMBNIs);
       
   343         // Will be null unless getNotificationInfo() is overridden,
       
   344         // since the notificationInfo field has not been set at this point.
       
   345         if (mbnis == null)
       
   346             mbnis = getMBeanInfo().getNotifications();
       
   347         return new NotificationBroadcasterSupport(mbnis);
       
   348     }
       
   349 
       
   350     private static <T> T[] firstNonEmpty(T[]... items) {
       
   351         for (T[] t : items) {
       
   352             if (t != null && t.length != 0)
       
   353                 return t;
       
   354         }
       
   355         return null;
       
   356     }
       
   357 
       
   358     private void injectEmitter() {
       
   359         if (emitter instanceof SendNotification) {
       
   360             try {
       
   361                 Object resource = getImplementation();
       
   362                 SendNotification send = (SendNotification) emitter;
       
   363                 MBeanInjector.injectSendNotification(resource, send);
       
   364             } catch (RuntimeException e) {
       
   365                 throw e;
       
   366             } catch (Exception e) {
       
   367                 throw new IllegalArgumentException(e);
       
   368             }
       
   369         }
       
   370     }
   235     }
   371 
   236 
   372     public void removeNotificationListener(NotificationListener listener)
   237     public void removeNotificationListener(NotificationListener listener)
   373             throws ListenerNotFoundException {
   238             throws ListenerNotFoundException {
   374         emitter.removeNotificationListener(listener);
   239         emitter.removeNotificationListener(listener);
   392     }
   257     }
   393 
   258 
   394     /**
   259     /**
   395      * <p>Sends a notification.</p>
   260      * <p>Sends a notification.</p>
   396      *
   261      *
   397      * <p>If the {@code emitter} parameter to the constructor was
   262      * <p>If the {@code emitter} parameter to the constructor was an
   398      * an instance of {@link SendNotification}, such as {@link
   263      * instance of {@code NotificationBroadcasterSupport} then this
   399      * NotificationBroadcasterSupport}, then this method will call {@code
   264      * method will call {@code emitter.}{@link
   400      * emitter.}{@link SendNotification#sendNotification
   265      * NotificationBroadcasterSupport#sendNotification
   401      * sendNotification}.</p>
   266      * sendNotification}.</p>
   402      *
   267      *
   403      * @param n the notification to send.
   268      * @param n the notification to send.
   404      *
   269      *
   405      * @throws ClassCastException if the {@code emitter} parameter to the
   270      * @throws ClassCastException if the {@code emitter} parameter to the
   406      * constructor was not a {@code NotificationBroadcasterSupport}.
   271      * constructor was not a {@code NotificationBroadcasterSupport}.
   407      */
   272      */
   408     public void sendNotification(Notification n) {
   273     public void sendNotification(Notification n) {
   409         if (emitter instanceof SendNotification)
   274         if (emitter instanceof NotificationBroadcasterSupport)
   410             ((SendNotification) emitter).sendNotification(n);
   275             ((NotificationBroadcasterSupport) emitter).sendNotification(n);
   411         else {
   276         else {
   412             final String msg =
   277             final String msg =
   413                 "Cannot sendNotification when emitter is not an " +
   278                 "Cannot sendNotification when emitter is not an " +
   414                 "instance of SendNotification: " + emitter.getClass().getName();
   279                 "instance of NotificationBroadcasterSupport: " +
       
   280                 emitter.getClass().getName();
   415             throw new ClassCastException(msg);
   281             throw new ClassCastException(msg);
   416         }
   282         }
   417     }
   283     }
   418 
   284 
   419     /**
   285     /**