001/*
002 * Copyright 2002-2017 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.support;
018
019import java.util.Arrays;
020import java.util.LinkedHashSet;
021import java.util.Set;
022import javax.management.MalformedObjectNameException;
023import javax.management.NotificationFilter;
024import javax.management.NotificationListener;
025import javax.management.ObjectName;
026
027import org.springframework.util.ObjectUtils;
028
029/**
030 * Helper class that aggregates a {@link javax.management.NotificationListener},
031 * a {@link javax.management.NotificationFilter}, and an arbitrary handback
032 * object, as well as the names of MBeans from which the listener wishes
033 * to receive {@link javax.management.Notification Notifications}.
034 *
035 * @author Juergen Hoeller
036 * @since 2.5.2
037 * @see org.springframework.jmx.export.NotificationListenerBean
038 * @see org.springframework.jmx.access.NotificationListenerRegistrar
039 */
040public class NotificationListenerHolder {
041
042        private NotificationListener notificationListener;
043
044        private NotificationFilter notificationFilter;
045
046        private Object handback;
047
048        protected Set<Object> mappedObjectNames;
049
050
051        /**
052         * Set the {@link javax.management.NotificationListener}.
053         */
054        public void setNotificationListener(NotificationListener notificationListener) {
055                this.notificationListener = notificationListener;
056        }
057
058        /**
059         * Get the {@link javax.management.NotificationListener}.
060         */
061        public NotificationListener getNotificationListener() {
062                return this.notificationListener;
063        }
064
065        /**
066         * Set the {@link javax.management.NotificationFilter} associated
067         * with the encapsulated {@link #getNotificationFilter() NotificationFilter}.
068         * <p>May be {@code null}.
069         */
070        public void setNotificationFilter(NotificationFilter notificationFilter) {
071                this.notificationFilter = notificationFilter;
072        }
073
074        /**
075         * Return the {@link javax.management.NotificationFilter} associated
076         * with the encapsulated {@link #getNotificationListener() NotificationListener}.
077         * <p>May be {@code null}.
078         */
079        public NotificationFilter getNotificationFilter() {
080                return this.notificationFilter;
081        }
082
083        /**
084         * Set the (arbitrary) object that will be 'handed back' as-is by an
085         * {@link javax.management.NotificationBroadcaster} when notifying
086         * any {@link javax.management.NotificationListener}.
087         * @param handback the handback object (can be {@code null})
088         * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, Object)
089         */
090        public void setHandback(Object handback) {
091                this.handback = handback;
092        }
093
094        /**
095         * Return the (arbitrary) object that will be 'handed back' as-is by an
096         * {@link javax.management.NotificationBroadcaster} when notifying
097         * any {@link javax.management.NotificationListener}.
098         * @return the handback object (may be {@code null})
099         * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, Object)
100         */
101        public Object getHandback() {
102                return this.handback;
103        }
104
105        /**
106         * Set the {@link javax.management.ObjectName}-style name of the single MBean
107         * that the encapsulated {@link #getNotificationFilter() NotificationFilter}
108         * will be registered with to listen for {@link javax.management.Notification Notifications}.
109         * Can be specified as {@code ObjectName} instance or as {@code String}.
110         * @see #setMappedObjectNames
111         */
112        public void setMappedObjectName(Object mappedObjectName) {
113                setMappedObjectNames(mappedObjectName != null ? new Object[] {mappedObjectName} : null);
114        }
115
116        /**
117         * Set an array of {@link javax.management.ObjectName}-style names of the MBeans
118         * that the encapsulated {@link #getNotificationFilter() NotificationFilter}
119         * will be registered with to listen for {@link javax.management.Notification Notifications}.
120         * Can be specified as {@code ObjectName} instances or as {@code String}s.
121         * @see #setMappedObjectName
122         */
123        public void setMappedObjectNames(Object[] mappedObjectNames) {
124                this.mappedObjectNames = (mappedObjectNames != null ?
125                                new LinkedHashSet<Object>(Arrays.asList(mappedObjectNames)) : null);
126        }
127
128        /**
129         * Return the list of {@link javax.management.ObjectName} String representations for
130         * which the encapsulated {@link #getNotificationFilter() NotificationFilter} will
131         * be registered as a listener for {@link javax.management.Notification Notifications}.
132         * @throws MalformedObjectNameException if an {@code ObjectName} is malformed
133         */
134        public ObjectName[] getResolvedObjectNames() throws MalformedObjectNameException {
135                if (this.mappedObjectNames == null) {
136                        return null;
137                }
138                ObjectName[] resolved = new ObjectName[this.mappedObjectNames.size()];
139                int i = 0;
140                for (Object objectName : this.mappedObjectNames) {
141                        resolved[i] = ObjectNameManager.getInstance(objectName);
142                        i++;
143                }
144                return resolved;
145        }
146
147
148        @Override
149        public boolean equals(Object other) {
150                if (this == other) {
151                        return true;
152                }
153                if (!(other instanceof NotificationListenerHolder)) {
154                        return false;
155                }
156                NotificationListenerHolder otherNlh = (NotificationListenerHolder) other;
157                return (ObjectUtils.nullSafeEquals(this.notificationListener, otherNlh.notificationListener) &&
158                                ObjectUtils.nullSafeEquals(this.notificationFilter, otherNlh.notificationFilter) &&
159                                ObjectUtils.nullSafeEquals(this.handback, otherNlh.handback) &&
160                                ObjectUtils.nullSafeEquals(this.mappedObjectNames, otherNlh.mappedObjectNames));
161        }
162
163        @Override
164        public int hashCode() {
165                int hashCode = ObjectUtils.nullSafeHashCode(this.notificationListener);
166                hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.notificationFilter);
167                hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.handback);
168                hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.mappedObjectNames);
169                return hashCode;
170        }
171
172}