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