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ö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    }