| /* | |
| * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. Oracle designates this | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| 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 <T> the implementation type of the MBean | |
| * @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 <T> the implementation type of the MBean | |
| * @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(); | |
| } | |
| } |