001: /*
002: * Copyright 2002-2006 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: * http://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:
017: package org.springframework.jmx.export.notification;
018:
019: import javax.management.AttributeChangeNotification;
020: import javax.management.MBeanException;
021: import javax.management.Notification;
022: import javax.management.ObjectName;
023: import javax.management.modelmbean.ModelMBean;
024:
025: import org.springframework.util.Assert;
026:
027: /**
028: * {@link NotificationPublisher} implementation that uses the infrastructure
029: * provided by the {@link ModelMBean} interface to track
030: * {@link javax.management.NotificationListener javax.management.NotificationListeners}
031: * and send {@link Notification Notifications} to those listeners.
032: *
033: * @author Rob Harrop
034: * @author Rick Evans
035: * @since 2.0
036: * @see ModelMBean
037: * @see NotificationPublisherAware
038: */
039: public class ModelMBeanNotificationPublisher implements
040: NotificationPublisher {
041:
042: /**
043: * The {@link ModelMBean} instance wrapping the managed resource into which this
044: * <code>NotificationPublisher</code> will be injected.
045: */
046: private final ModelMBean modelMBean;
047:
048: /**
049: * The {@link ObjectName} associated with the {@link ModelMBean modelMBean}.
050: */
051: private final ObjectName objectName;
052:
053: /**
054: * The managed resource associated with the {@link ModelMBean modelMBean}.
055: */
056: private final Object managedResource;
057:
058: /**
059: * Creates a new instance of the {@link ModelMBeanNotificationPublisher} class
060: * that will publish all {@link javax.management.Notification Notifications}
061: * to the supplied {@link ModelMBean}.
062: * @param modelMBean the target {@link ModelMBean}; must not be <code>null</code>
063: * @param objectName the {@link ObjectName} of the source {@link ModelMBean}
064: * @param managedResource the managed resource exposed by the supplied {@link ModelMBean}
065: * @throws IllegalArgumentException if any of the parameters is <code>null</code>
066: */
067: public ModelMBeanNotificationPublisher(ModelMBean modelMBean,
068: ObjectName objectName, Object managedResource) {
069: Assert.notNull(modelMBean,
070: "The 'modelMBean' parameter must not be null.");
071: Assert.notNull(objectName,
072: "The 'objectName' parameter must not be null.");
073: Assert.notNull(managedResource,
074: "The 'managedResource' parameter must not be null.");
075: this .modelMBean = modelMBean;
076: this .objectName = objectName;
077: this .managedResource = managedResource;
078: }
079:
080: /**
081: * Sends the supplied {@link Notification} using the wrapped
082: * {@link ModelMBean} instance.
083: * @param notification the {@link Notification} to be sent
084: * @throws IllegalArgumentException if the supplied <code>notification</code> is <code>null</code>
085: * @throws UnableToSendNotificationException if the supplied <code>notification</code> could not be sent
086: */
087: public void sendNotification(Notification notification) {
088: Assert.notNull(notification, "Notification must not be null");
089: replaceNotificationSourceIfNecessary(notification);
090: try {
091: if (notification instanceof AttributeChangeNotification) {
092: this .modelMBean
093: .sendAttributeChangeNotification((AttributeChangeNotification) notification);
094: } else {
095: this .modelMBean.sendNotification(notification);
096: }
097: } catch (MBeanException ex) {
098: throw new UnableToSendNotificationException(
099: "Unable to send notification [" + notification
100: + "]", ex);
101: }
102: }
103:
104: /**
105: * From the {@link Notification class level Javadoc}:
106: * <p><i>'It is strongly recommended that notification senders use the object name
107: * rather than a reference to the MBean object as the source.'</i>
108: *
109: * @param notification the {@link Notification} whose {@link javax.management.Notification#getSource()} might need massaging
110: */
111: private void replaceNotificationSourceIfNecessary(
112: Notification notification) {
113: if (notification.getSource() == null
114: || notification.getSource()
115: .equals(this.managedResource)) {
116: notification.setSource(this.objectName);
117: }
118: }
119:
120: }
|