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}