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     */
022    package org.granite.jmx;
023    
024    import java.lang.management.ManagementFactory;
025    
026    import javax.management.InstanceAlreadyExistsException;
027    import javax.management.InstanceNotFoundException;
028    import javax.management.MBeanRegistrationException;
029    import javax.management.MBeanServer;
030    import javax.management.MBeanServerFactory;
031    import javax.management.NotCompliantMBeanException;
032    import 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     */
040    public 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    }