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