001/**
002 *   GRANITE DATA SERVICES
003 *   Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004 *
005 *   This file is part of the Granite Data Services Platform.
006 *
007 *   Granite Data Services is free software; you can redistribute it and/or
008 *   modify it under the terms of the GNU Lesser General Public
009 *   License as published by the Free Software Foundation; either
010 *   version 2.1 of the License, or (at your option) any later version.
011 *
012 *   Granite Data Services is distributed in the hope that it will be useful,
013 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
015 *   General Public License for more details.
016 *
017 *   You should have received a copy of the GNU Lesser General Public
018 *   License along with this library; if not, write to the Free Software
019 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
020 *   USA, or see <http://www.gnu.org/licenses/>.
021 */
022package org.granite.jmx;
023
024import java.lang.management.ManagementFactory;
025
026import javax.management.InstanceAlreadyExistsException;
027import javax.management.InstanceNotFoundException;
028import javax.management.MBeanRegistrationException;
029import javax.management.MBeanServer;
030import javax.management.MBeanServerFactory;
031import javax.management.NotCompliantMBeanException;
032import javax.management.ObjectName;
033
034/**
035 * Utility class for MBean server lookup (with a specific support for the
036 * JBoss JMX console) and MBeans registration. 
037 * 
038 * @author Franck WOLFF
039 */
040public class MBeanServerLocator {
041
042        private static MBeanServerLocator instance = null;
043        
044        private final MBeanServer server;
045        
046        private MBeanServerLocator() {
047                this.server = findMBeanServer();
048        }
049        
050        private static MBeanServer findMBeanServer() {
051                
052                // Initialize with default platform MBeanServer: must be called first
053                // otherwise jconsole don't work...
054                MBeanServer server = ManagementFactory.getPlatformMBeanServer();
055
056                // Try to find main JBoss MBeanServer.
057                for (Object found : MBeanServerFactory.findMBeanServer(null)) {
058                        if (found instanceof MBeanServer && "jboss".equals(((MBeanServer)found).getDefaultDomain())) {
059                                server = (MBeanServer)found;
060                                break;
061                        }
062                }
063                
064                return server;
065        }
066        
067        /**
068         * Returns a singleton instance of the <tt>MBeanServerLocator</tt> class. The first call
069         * to this method performs an initial lookup of a {@link MBeanServer}.
070         * 
071         * @return a singleton instance of the MBeanServerLocator class.
072         */
073        public static synchronized MBeanServerLocator getInstance() {
074                if (instance == null)
075                        instance = new MBeanServerLocator();
076                return instance;
077        }
078        
079        /**
080         * Returns the {@link MBeanServer} wrapped by this <tt>MBeanServerLocator</tt> instance.
081         * 
082         * @return the wrapped {@link MBeanServer}.
083         */
084        public MBeanServer getMBeanServer() {
085                return server;
086        }
087        
088        /**
089         * Register the <tt>mbean</tt> object with the supplied <tt>name</tt>. Calling this method is
090         * equivalent to calling {@link #register(Object, ObjectName, boolean)} with its
091         * last parameter set to <tt>false</tt>.
092         * 
093         * @param mbean the mbean to register.
094         * @param name the name used for registration.
095         * @throws MBeanRegistrationException rethrown from the wrapped {@link MBeanServer}
096         * @throws InstanceNotFoundException rethrown from the wrapped {@link MBeanServer}
097         * @throws InstanceAlreadyExistsException rethrown from the wrapped {@link MBeanServer}
098         * @throws NotCompliantMBeanException rethrown from the wrapped {@link MBeanServer}
099         */
100        public void register(Object mbean, ObjectName name)
101                throws MBeanRegistrationException, InstanceNotFoundException,
102                       InstanceAlreadyExistsException, NotCompliantMBeanException {
103                
104                register(mbean, name, false);
105        }
106        
107        /**
108         * Register the <tt>mbean</tt> object with the supplied <tt>name</tt>. If the
109         * <tt>replace</tt> parameter is set to true and if a MBean is already registered
110         * under the same name, it is first unregistered.
111         * 
112         * @param mbean the mbean to register.
113         * @param name the name used for registration.
114         * @param replace if true, a mbean registered under the same name will be first
115         *              unregistered.
116         * @throws MBeanRegistrationException rethrown from the wrapped {@link MBeanServer}
117         * @throws InstanceNotFoundException rethrown from the wrapped {@link MBeanServer}
118         * @throws InstanceAlreadyExistsException rethrown from the wrapped {@link MBeanServer}
119         * @throws NotCompliantMBeanException rethrown from the wrapped {@link MBeanServer}
120         */
121        public void register(Object mbean, ObjectName name, boolean replace)
122                throws MBeanRegistrationException, InstanceNotFoundException,
123                           InstanceAlreadyExistsException, NotCompliantMBeanException {
124                
125                if (server != null) {
126            if (replace && server.isRegistered(name))
127                server.unregisterMBean(name);
128                        server.registerMBean(mbean, name);
129                }
130        }
131        
132        /**
133         * Returns <tt>true</tt> if a MBean is registered under the supplied <tt>name</tt>.
134         * 
135         * @param name the name to test for registration.
136         * @return true if a mbean is registered, false otherwise.
137         */
138        public boolean isRegistered(ObjectName name) {
139                return server != null && server.isRegistered(name);
140        }
141        
142        /**
143         * Unregister any mbean registered under the supplied <tt>name</tt>.
144         * 
145         * @param name the name of mbean to unregister.
146         * @throws InstanceNotFoundException rethrown from the wrapped {@link MBeanServer}
147         * @throws MBeanRegistrationException rethrown from the wrapped {@link MBeanServer}
148         */
149        public void unregister(ObjectName name)
150                throws InstanceNotFoundException, MBeanRegistrationException {
151                
152                if (server != null)
153                        server.unregisterMBean(name);
154        }
155}