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    
011    package org.picocontainer.gems.jmx;
012    
013    import 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     */
025    public 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    }