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