001/* 002 * Copyright 2002-2018 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.assembler; 018 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import javax.management.modelmbean.ModelMBeanNotificationInfo; 026 027import org.springframework.jmx.export.metadata.JmxMetadataUtils; 028import org.springframework.jmx.export.metadata.ManagedNotification; 029import org.springframework.lang.Nullable; 030import org.springframework.util.StringUtils; 031 032/** 033 * Base class for MBeanInfoAssemblers that support configurable 034 * JMX notification behavior. 035 * 036 * @author Rob Harrop 037 * @author Juergen Hoeller 038 * @since 2.0 039 */ 040public abstract class AbstractConfigurableMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssembler { 041 042 @Nullable 043 private ModelMBeanNotificationInfo[] notificationInfos; 044 045 private final Map<String, ModelMBeanNotificationInfo[]> notificationInfoMappings = new HashMap<>(); 046 047 048 public void setNotificationInfos(ManagedNotification[] notificationInfos) { 049 ModelMBeanNotificationInfo[] infos = new ModelMBeanNotificationInfo[notificationInfos.length]; 050 for (int i = 0; i < notificationInfos.length; i++) { 051 ManagedNotification notificationInfo = notificationInfos[i]; 052 infos[i] = JmxMetadataUtils.convertToModelMBeanNotificationInfo(notificationInfo); 053 } 054 this.notificationInfos = infos; 055 } 056 057 public void setNotificationInfoMappings(Map<String, Object> notificationInfoMappings) { 058 notificationInfoMappings.forEach((beanKey, result) -> 059 this.notificationInfoMappings.put(beanKey, extractNotificationMetadata(result))); 060 } 061 062 063 @Override 064 protected ModelMBeanNotificationInfo[] getNotificationInfo(Object managedBean, String beanKey) { 065 ModelMBeanNotificationInfo[] result = null; 066 if (StringUtils.hasText(beanKey)) { 067 result = this.notificationInfoMappings.get(beanKey); 068 } 069 if (result == null) { 070 result = this.notificationInfos; 071 } 072 return (result != null ? result : new ModelMBeanNotificationInfo[0]); 073 } 074 075 private ModelMBeanNotificationInfo[] extractNotificationMetadata(Object mapValue) { 076 if (mapValue instanceof ManagedNotification) { 077 ManagedNotification mn = (ManagedNotification) mapValue; 078 return new ModelMBeanNotificationInfo[] {JmxMetadataUtils.convertToModelMBeanNotificationInfo(mn)}; 079 } 080 else if (mapValue instanceof Collection) { 081 Collection<?> col = (Collection<?>) mapValue; 082 List<ModelMBeanNotificationInfo> result = new ArrayList<>(); 083 for (Object colValue : col) { 084 if (!(colValue instanceof ManagedNotification)) { 085 throw new IllegalArgumentException( 086 "Property 'notificationInfoMappings' only accepts ManagedNotifications for Map values"); 087 } 088 ManagedNotification mn = (ManagedNotification) colValue; 089 result.add(JmxMetadataUtils.convertToModelMBeanNotificationInfo(mn)); 090 } 091 return result.toArray(new ModelMBeanNotificationInfo[0]); 092 } 093 else { 094 throw new IllegalArgumentException( 095 "Property 'notificationInfoMappings' only accepts ManagedNotifications for Map values"); 096 } 097 } 098 099}