/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.aries.jmx.whiteboard; import java.util.IdentityHashMap; import java.util.Map; import java.util.Map.Entry; import javax.management.DynamicMBean; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.NotCompliantMBeanException; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.StandardMBean; import org.apache.aries.jmx.util.shared.RegistrableStandardEmitterMBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; final class MBeanHolder { /** default log */ private final Logger log = LoggerFactory.getLogger(getClass()); private final Object mbean; private final ObjectName requestedObjectName; private final Map<MBeanServer, ObjectName> registrations; static <T> MBeanHolder create(final T mbean, final ObjectName requestedObjectName) { if (mbean instanceof DynamicMBean) { return new MBeanHolder(mbean, requestedObjectName); } else if (mbean == null) { return null; } Class<?> mbeanClass = mbean.getClass(); @SuppressWarnings("unchecked") // This is all in aid of getting new StandardMBean to work. Class<T> mbeanInterface = (Class<T>) getMBeanInterface(mbeanClass); if (mbeanInterface == null) { return null; } if (mbeanInterface.getName().equals( mbeanClass.getName().concat("MBean")) || mbeanInterface.getName().equals(mbeanClass.getName().concat("MXBean")) ) { return new MBeanHolder(mbean, requestedObjectName); } try { StandardMBean stdMbean = new RegistrableStandardEmitterMBean(mbean, mbeanInterface); return new MBeanHolder(stdMbean, requestedObjectName); } catch (NotCompliantMBeanException e) { LoggerFactory.getLogger(MBeanHolder.class).error( "create: Cannot create StandardMBean for " + mbean + " of type " + mbeanClass + " for interface " + mbeanInterface, e); return null; } } private static Class<?> getMBeanInterface(final Class<?> mbeanClass) { if (mbeanClass == null) { return null; } for (Class<?> i : mbeanClass.getInterfaces()) { if (i.getName().endsWith("MBean") || i.getName().endsWith("MXBean")) { return i; } Class<?> mbeanInterface = getMBeanInterface(i); if (mbeanInterface != null) { return mbeanInterface; } } if (mbeanClass.getSuperclass() != null) { return getMBeanInterface(mbeanClass.getSuperclass()); } return null; } private MBeanHolder(final Object mbean, final ObjectName requestedObjectName) { this.mbean = mbean; this.requestedObjectName = requestedObjectName; this.registrations = new IdentityHashMap<MBeanServer, ObjectName>(); } void register(final MBeanServer server) { ObjectInstance instance; try { instance = server.registerMBean(mbean, requestedObjectName); registrations.put(server, instance.getObjectName()); } catch (InstanceAlreadyExistsException e) { log.error("register: Failure registering MBean " + mbean, e); } catch (MBeanRegistrationException e) { log.error("register: Failure registering MBean " + mbean, e); } catch (NotCompliantMBeanException e) { log.error("register: Failure registering MBean " + mbean, e); } } void unregister(final MBeanServer server) { final ObjectName registeredName = registrations.remove(server); if (registeredName != null) { unregister(server, registeredName); } } void unregister() { for (Entry<MBeanServer, ObjectName> entry : registrations.entrySet()) { unregister(entry.getKey(), entry.getValue()); } registrations.clear(); } private void unregister(final MBeanServer server, final ObjectName name) { try { server.unregisterMBean(name); } catch (MBeanRegistrationException e) { log.error("unregister: preDeregister of " + name + " threw an exception", e); } catch (InstanceNotFoundException e) { // not really expected ! log.error("unregister: Unexpected unregistration problem of MBean " + name, e); } } }