/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.management;
/**
* <p>An MBean whose management interface is determined by reflection
* on a Java interface, and that emits notifications.</p>
*
* <p>The following example shows how to use the public constructor
* {@link #StandardEmitterMBean(Object, Class, NotificationEmitter)
* StandardEmitterMBean(implementation, mbeanInterface, emitter)} to
* create an MBean emitting notifications with any
* implementation class name <i>Impl</i>, with a management
* interface defined (as for current Standard MBeans) by any interface
* <i>Intf</i>, and with any implementation of the interface
* {@link NotificationEmitter}. The example uses the class
* {@link NotificationBroadcasterSupport} as an implementation
* of the interface {@link NotificationEmitter}.</p>
*
* <pre>
* MBeanServer mbs;
* ...
* final String[] types = new String[] {"sun.disc.space","sun.disc.alarm"};
* final MBeanNotificationInfo info = new MBeanNotificationInfo(
* types,
* Notification.class.getName(),
* "Notification about disc info.");
* final NotificationEmitter emitter =
* new NotificationBroadcasterSupport(info);
*
* final Intf impl = new Impl(...);
* final Object mbean = new StandardEmitterMBean(
* impl, Intf.class, emitter);
* mbs.registerMBean(mbean, objectName);
* </pre>
*
* @see StandardMBean
*
* @since 1.6
*/
public class
StandardEmitterMBean extends
StandardMBean
implements
NotificationEmitter {
private static final
MBeanNotificationInfo[]
NO_NOTIFICATION_INFO =
new
MBeanNotificationInfo[0];
private final
NotificationEmitter emitter;
private final
MBeanNotificationInfo[]
notificationInfo;
/**
* <p>Make an MBean whose management interface is specified by
* {@code mbeanInterface}, with the given implementation and
* where notifications are handled by the given {@code NotificationEmitter}.
* The resultant MBean implements the {@code NotificationEmitter} interface
* by forwarding its methods to {@code emitter}. It is legal and useful
* for {@code implementation} and {@code emitter} to be the same object.</p>
*
* <p>If {@code emitter} is an instance of {@code
* NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
* NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
* {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
* getNotificationInfo()} at the time of construction. If the array
* returned by {@code emitter.getNotificationInfo()} later changes,
* that will have no effect on this object's
* {@code getNotificationInfo()}.</p>
*
* @param implementation the implementation of the MBean interface.
* @param mbeanInterface a Standard MBean interface.
* @param emitter the object that will handle notifications.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
* specified interface, or if {@code emitter} is null.
*/
public <T>
StandardEmitterMBean(T
implementation,
Class<T>
mbeanInterface,
NotificationEmitter emitter) {
this(
implementation,
mbeanInterface, false,
emitter);
}
/**
* <p>Make an MBean whose management interface is specified by
* {@code mbeanInterface}, with the given implementation and where
* notifications are handled by the given {@code
* NotificationEmitter}. This constructor can be used to make
* either Standard MBeans or MXBeans. The resultant MBean
* implements the {@code NotificationEmitter} interface by
* forwarding its methods to {@code emitter}. It is legal and
* useful for {@code implementation} and {@code emitter} to be the
* same object.</p>
*
* <p>If {@code emitter} is an instance of {@code
* NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
* NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
* {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
* getNotificationInfo()} at the time of construction. If the array
* returned by {@code emitter.getNotificationInfo()} later changes,
* that will have no effect on this object's
* {@code getNotificationInfo()}.</p>
*
* @param implementation the implementation of the MBean interface.
* @param mbeanInterface a Standard MBean interface.
* @param isMXBean If true, the {@code mbeanInterface} parameter
* names an MXBean interface and the resultant MBean is an MXBean.
* @param emitter the object that will handle notifications.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
* specified interface, or if {@code emitter} is null.
*/
public <T>
StandardEmitterMBean(T
implementation,
Class<T>
mbeanInterface,
boolean
isMXBean,
NotificationEmitter emitter) {
super(
implementation,
mbeanInterface,
isMXBean);
if (
emitter == null)
throw new
IllegalArgumentException("Null emitter");
this.
emitter =
emitter;
MBeanNotificationInfo[]
infos =
emitter.
getNotificationInfo();
if (
infos == null ||
infos.length == 0) {
this.
notificationInfo =
NO_NOTIFICATION_INFO;
} else {
this.
notificationInfo =
infos.
clone();
}
}
/**
* <p>Make an MBean whose management interface is specified by
* {@code mbeanInterface}, and
* where notifications are handled by the given {@code NotificationEmitter}.
* The resultant MBean implements the {@code NotificationEmitter} interface
* by forwarding its methods to {@code emitter}.</p>
*
* <p>If {@code emitter} is an instance of {@code
* NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
* NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
* {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
* getNotificationInfo()} at the time of construction. If the array
* returned by {@code emitter.getNotificationInfo()} later changes,
* that will have no effect on this object's
* {@code getNotificationInfo()}.</p>
*
* <p>This constructor must be called from a subclass that implements
* the given {@code mbeanInterface}.</p>
*
* @param mbeanInterface a StandardMBean interface.
* @param emitter the object that will handle notifications.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if {@code this} does not implement the specified interface, or
* if {@code emitter} is null.
*/
protected
StandardEmitterMBean(
Class<?>
mbeanInterface,
NotificationEmitter emitter) {
this(
mbeanInterface, false,
emitter);
}
/**
* <p>Make an MBean whose management interface is specified by
* {@code mbeanInterface}, and where notifications are handled by
* the given {@code NotificationEmitter}. This constructor can be
* used to make either Standard MBeans or MXBeans. The resultant
* MBean implements the {@code NotificationEmitter} interface by
* forwarding its methods to {@code emitter}.</p>
*
* <p>If {@code emitter} is an instance of {@code
* NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
* NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
* {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
* getNotificationInfo()} at the time of construction. If the array
* returned by {@code emitter.getNotificationInfo()} later changes,
* that will have no effect on this object's
* {@code getNotificationInfo()}.</p>
*
* <p>This constructor must be called from a subclass that implements
* the given {@code mbeanInterface}.</p>
*
* @param mbeanInterface a StandardMBean interface.
* @param isMXBean If true, the {@code mbeanInterface} parameter
* names an MXBean interface and the resultant MBean is an MXBean.
* @param emitter the object that will handle notifications.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if {@code this} does not implement the specified interface, or
* if {@code emitter} is null.
*/
protected
StandardEmitterMBean(
Class<?>
mbeanInterface, boolean
isMXBean,
NotificationEmitter emitter) {
super(
mbeanInterface,
isMXBean);
if (
emitter == null)
throw new
IllegalArgumentException("Null emitter");
this.
emitter =
emitter;
MBeanNotificationInfo[]
infos =
emitter.
getNotificationInfo();
if (
infos == null ||
infos.length == 0) {
this.
notificationInfo =
NO_NOTIFICATION_INFO;
} else {
this.
notificationInfo =
infos.
clone();
}
}
public void
removeNotificationListener(
NotificationListener listener)
throws
ListenerNotFoundException {
emitter.
removeNotificationListener(
listener);
}
public void
removeNotificationListener(
NotificationListener listener,
NotificationFilter filter,
Object handback)
throws
ListenerNotFoundException {
emitter.
removeNotificationListener(
listener,
filter,
handback);
}
public void
addNotificationListener(
NotificationListener listener,
NotificationFilter filter,
Object handback) {
emitter.
addNotificationListener(
listener,
filter,
handback);
}
public
MBeanNotificationInfo[]
getNotificationInfo() {
// this getter might get called from the super constructor
// when the notificationInfo has not been properly set yet
if (
notificationInfo == null) {
return
NO_NOTIFICATION_INFO;
}
if (
notificationInfo.length == 0) {
return
notificationInfo;
} else {
return
notificationInfo.
clone();
}
}
/**
* <p>Sends a notification.</p>
*
* <p>If the {@code emitter} parameter to the constructor was an
* instance of {@code NotificationBroadcasterSupport} then this
* method will call {@code emitter.}{@link
* NotificationBroadcasterSupport#sendNotification
* sendNotification}.</p>
*
* @param n the notification to send.
*
* @throws ClassCastException if the {@code emitter} parameter to the
* constructor was not a {@code NotificationBroadcasterSupport}.
*/
public void
sendNotification(
Notification n) {
if (
emitter instanceof
NotificationBroadcasterSupport)
((
NotificationBroadcasterSupport)
emitter).
sendNotification(
n);
else {
final
String msg =
"Cannot sendNotification when emitter is not an " +
"instance of NotificationBroadcasterSupport: " +
emitter.
getClass().
getName();
throw new
ClassCastException(
msg);
}
}
/**
* <p>Get the MBeanNotificationInfo[] that will be used in the
* MBeanInfo returned by this MBean.</p>
*
* <p>The default implementation of this method returns
* {@link #getNotificationInfo()}.</p>
*
* @param info The default MBeanInfo derived by reflection.
* @return the MBeanNotificationInfo[] for the new MBeanInfo.
*/
@
Override
MBeanNotificationInfo[]
getNotifications(
MBeanInfo info) {
return
getNotificationInfo();
}
}