001/*****************************************************************************
002 * Copyright (C) NanoContainer Organization. All rights reserved.            *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD      *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file.                                                     *
007 *                                                                           *
008 * Original code by Joerg Schaible                                           *
009 *****************************************************************************/
010
011package org.picocontainer.gems.jmx;
012
013import javax.management.MBeanInfo;
014
015
016/**
017 * A DynamicMBeanProvider that constructs StandardMBean instances that follow the JMX naming conventions. The name of
018 * the management interface must follow the naming conventions with an <em>MBean</em> appended to the MBean's type.
019 * The implementation will use the registered MBeanInfoProvider instances of type
020 * {@link ComponentKeyConventionMBeanInfoProvider} and {@link ComponentTypeConventionMBeanInfoProvider} to provide a
021 * {@link MBeanInfo} for the component's MBean. If a {@link MBeanInfo} was found, the MBean's type is used from the
022 * MBeanInfo otherwise the type is the implementation class of the component.
023 * @author J&ouml;rg Schaible
024 */
025public class NamingConventionConstructingProvider extends AbstractConstructingProvider {
026
027    private final ObjectNameFactory objectNameFactory;
028    private final MBeanInfoProvider[] mBeanProviders;
029    private final StandardMBeanFactory mBeanFactory;
030
031    /**
032     * Construct a NamingConventionConstructingProvider. Following {@link MBeanInfoProvider} instances are registered
033     * with this constructor:
034     * <ul>
035     * <li>{@link ComponentKeyConventionMBeanInfoProvider}</li>
036     * <li>{@link ComponentTypeConventionMBeanInfoProvider}</li>
037     * </ul>
038     * @param factory The ObjectNameFactory used to name the created MBeans.
039     */
040    public NamingConventionConstructingProvider(final ObjectNameFactory factory) {
041        if (factory == null) {
042            throw new NullPointerException("ObjectNameFactory is null");
043        }
044        mBeanFactory = new StandardMBeanFactory();
045        objectNameFactory = factory;
046        mBeanProviders = new MBeanInfoProvider[]{
047                new ComponentKeyConventionMBeanInfoProvider(), new ComponentTypeConventionMBeanInfoProvider()};
048    }
049
050    /**
051     * Return a {@link StandardMBeanFactory}.
052     * @see org.picocontainer.gems.jmx.AbstractConstructingProvider#getMBeanFactory()
053     */
054    @Override
055        protected DynamicMBeanFactory getMBeanFactory() {
056        return mBeanFactory;
057    }
058
059    /**
060     * @see org.picocontainer.gems.jmx.AbstractConstructingProvider#getObjectNameFactory()
061     */
062    @Override
063        public ObjectNameFactory getObjectNameFactory() {
064        return objectNameFactory;
065    }
066
067    /**
068     * Return an array with an instance of type {@link ComponentKeyConventionMBeanInfoProvider} and
069     * {@link ComponentTypeConventionMBeanInfoProvider}.
070     * @see org.picocontainer.gems.jmx.AbstractConstructingProvider#getMBeanInfoProviders()
071     */
072    @Override
073        public MBeanInfoProvider[] getMBeanInfoProviders() {
074        return mBeanProviders;
075    }
076
077    /**
078     * Determin the default management interface using naming convetions of the JMX specification.
079     * @param implementation The type of the component's implementation.
080     * @param mBeanInfo The {@link MBeanInfo} to expose the component. May be <code>null</code>.
081     * @return Returns the management interface.
082     * @throws ClassNotFoundException Thrown if no interface can be determined.
083     */
084    @Override
085        protected Class getManagementInterface(final Class implementation, final MBeanInfo mBeanInfo)
086            throws ClassNotFoundException {
087        return mBeanFactory.getDefaultManagementInterface(implementation, mBeanInfo);
088    }
089}