    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.MBeanServer;
    014
    015    import org.picocontainer.ComponentAdapter;
    016    import org.picocontainer.gems.GemsCharacteristics;
    017    import org.picocontainer.Parameter;
    018    import org.picocontainer.PicoCompositionException;
    019    import org.picocontainer.ComponentMonitor;
    020    import org.picocontainer.LifecycleStrategy;
    021    import org.picocontainer.behaviors.AbstractBehaviorFactory;
    022
    023    import java.lang.management.ManagementFactory;
    024    import java.util.Properties;
    025
    026
    027    /**
    028     * {@link org.picocontainer.ComponentFactory} that instantiates {@link JMXExposed} instances.
    029     * @author J&ouml;rg Schaible
    030     */
    031    @SuppressWarnings("serial")
    032    public class JMXExposing extends AbstractBehaviorFactory {
    033
    034
    035            private final MBeanServer mBeanServer;
    036        private final DynamicMBeanProvider[] providers;
    037
    038        /**
    039         * Constructs a JMXExposingComponentFactory that uses the system default MBean Server.
    040         * @since PicoContainer-Gems 2.4
    041         */
    042        public JMXExposing() {
    043            this(ManagementFactory.getPlatformMBeanServer());
    044        }
    045
    046
    047        /**
    048         * Construct a JMXExposingComponentFactory.
    049         * @param mBeanServer The {@link MBeanServer} used for registering the MBean.
    050         * @param providers An array with providers for converting the component instance into a
    051         *            {@link javax.management.DynamicMBean}.
    052         * @throws NullPointerException Thrown if the {@link MBeanServer} or the array with the {@link DynamicMBeanProvider}
    053         *             instances is null.
    054         */
    055        public JMXExposing(
    056                final MBeanServer mBeanServer,
    057                final DynamicMBeanProvider[] providers) throws NullPointerException {
    058            if (mBeanServer == null || providers == null) {
    059                throw new NullPointerException();
    060            }
    061            this.mBeanServer = mBeanServer;
    062            this.providers = providers;
    063        }
    064
    065        /**
    066         * Construct a JMXExposingComponentFactory. This instance uses a {@link DynamicMBeanComponentProvider} as
    067         * default to register any component instance in the {@link MBeanServer}, that is already a
    068         * {@link javax.management.DynamicMBean}.
    069         * @param mBeanServer The {@link MBeanServer} used for registering the MBean.
    070         * @throws NullPointerException Thrown if the {@link MBeanServer} or the array with the {@link DynamicMBeanProvider}
    071         *             instances is null.
    072         */
    073        public JMXExposing(final MBeanServer mBeanServer)
    074                throws NullPointerException {
    075            this(mBeanServer, new DynamicMBeanProvider[]{new DynamicMBeanComponentProvider()});
    076        }
    077
    078
    079        /**
    080         * Retrieve a {@link ComponentAdapter}. Wrap the instance retrieved by the delegate with an instance of a
    081         * {@link JMXExposed}.
    082         * @see org.picocontainer.ComponentFactory#createComponentAdapter(ComponentMonitor,LifecycleStrategy,Properties,Object,Class,Parameter...)
    083         */
    084        @Override
    085            public <T> ComponentAdapter<T> createComponentAdapter(
    086                final ComponentMonitor componentMonitor, final LifecycleStrategy lifecycleStrategy, final Properties componentProperties, final Object componentKey, final Class<T> componentImplementation, final Parameter... parameters)
    087                throws PicoCompositionException {
    088            final ComponentAdapter<T> delegateAdapter = super.createComponentAdapter(
    089                    componentMonitor, lifecycleStrategy,
    090                    componentProperties, componentKey, componentImplementation, parameters);
    091            if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, GemsCharacteristics.NO_JMX)) {
    092                return delegateAdapter;
    093            } else {
    094                    AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, GemsCharacteristics.JMX);
    095                return componentMonitor.newBehavior(new JMXExposed<T>(delegateAdapter, mBeanServer, providers));
    096            }
    097        }
    098
    099
    100        @Override
    101            public <T> ComponentAdapter<T> addComponentAdapter(final ComponentMonitor componentMonitor,
    102                                                    final LifecycleStrategy lifecycleStrategy,
    103                                                    final Properties componentProperties,
    104                                                    final ComponentAdapter<T> adapter) {
    105            if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, GemsCharacteristics.NO_JMX)) {
    106                return super.addComponentAdapter(componentMonitor,
    107                                                 lifecycleStrategy,
    108                                                 componentProperties,
    109                                                 adapter);
    110            } else {
    111                return componentMonitor.newBehavior(new JMXExposed<T>(super.addComponentAdapter(componentMonitor,
    112                                                                         lifecycleStrategy,
    113                                                                         componentProperties,
    114                                                                         adapter), mBeanServer, providers));
    115            }
    116
    117        }
    118    }