001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jmx.export.notification; 018 019import javax.management.AttributeChangeNotification; 020import javax.management.MBeanException; 021import javax.management.Notification; 022import javax.management.ObjectName; 023import javax.management.modelmbean.ModelMBean; 024import javax.management.modelmbean.ModelMBeanNotificationBroadcaster; 025 026import org.springframework.util.Assert; 027 028/** 029 * {@link NotificationPublisher} implementation that uses the infrastructure 030 * provided by the {@link ModelMBean} interface to track 031 * {@link javax.management.NotificationListener javax.management.NotificationListeners} 032 * and send {@link Notification Notifications} to those listeners. 033 * 034 * @author Rob Harrop 035 * @author Juergen Hoeller 036 * @author Rick Evans 037 * @since 2.0 038 * @see javax.management.modelmbean.ModelMBeanNotificationBroadcaster 039 * @see NotificationPublisherAware 040 */ 041public class ModelMBeanNotificationPublisher implements NotificationPublisher { 042 043 /** 044 * The {@link ModelMBean} instance wrapping the managed resource into which this 045 * {@code NotificationPublisher} will be injected. 046 */ 047 private final ModelMBeanNotificationBroadcaster modelMBean; 048 049 /** 050 * The {@link ObjectName} associated with the {@link ModelMBean modelMBean}. 051 */ 052 private final ObjectName objectName; 053 054 /** 055 * The managed resource associated with the {@link ModelMBean modelMBean}. 056 */ 057 private final Object managedResource; 058 059 060 /** 061 * Create a new instance of the {@link ModelMBeanNotificationPublisher} class 062 * that will publish all {@link javax.management.Notification Notifications} 063 * to the supplied {@link ModelMBean}. 064 * @param modelMBean the target {@link ModelMBean}; must not be {@code null} 065 * @param objectName the {@link ObjectName} of the source {@link ModelMBean} 066 * @param managedResource the managed resource exposed by the supplied {@link ModelMBean} 067 * @throws IllegalArgumentException if any of the parameters is {@code null} 068 */ 069 public ModelMBeanNotificationPublisher( 070 ModelMBeanNotificationBroadcaster modelMBean, ObjectName objectName, Object managedResource) { 071 072 Assert.notNull(modelMBean, "'modelMBean' must not be null"); 073 Assert.notNull(objectName, "'objectName' must not be null"); 074 Assert.notNull(managedResource, "'managedResource' must not be null"); 075 this.modelMBean = modelMBean; 076 this.objectName = objectName; 077 this.managedResource = managedResource; 078 } 079 080 081 /** 082 * Send the supplied {@link Notification} using the wrapped 083 * {@link ModelMBean} instance. 084 * @param notification the {@link Notification} to be sent 085 * @throws IllegalArgumentException if the supplied {@code notification} is {@code null} 086 * @throws UnableToSendNotificationException if the supplied {@code notification} could not be sent 087 */ 088 @Override 089 public void sendNotification(Notification notification) { 090 Assert.notNull(notification, "Notification must not be null"); 091 replaceNotificationSourceIfNecessary(notification); 092 try { 093 if (notification instanceof AttributeChangeNotification) { 094 this.modelMBean.sendAttributeChangeNotification((AttributeChangeNotification) notification); 095 } 096 else { 097 this.modelMBean.sendNotification(notification); 098 } 099 } 100 catch (MBeanException ex) { 101 throw new UnableToSendNotificationException("Unable to send notification [" + notification + "]", ex); 102 } 103 } 104 105 /** 106 * From the {@link Notification javadoc}: 107 * <p><i>"It is strongly recommended that notification senders use the object name 108 * rather than a reference to the MBean object as the source."</i> 109 * @param notification the {@link Notification} whose 110 * {@link javax.management.Notification#getSource()} might need massaging 111 */ 112 private void replaceNotificationSourceIfNecessary(Notification notification) { 113 if (notification.getSource() == null || notification.getSource().equals(this.managedResource)) { 114 notification.setSource(this.objectName); 115 } 116 } 117 118}