DefaultRegistration.java

package com.ziesemer.utils.jmx.mBeans;

import java.lang.management.ManagementFactory;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.StandardMBean;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ziesemer.utils.jmx.server.StandardMBeanInfoCombiner6;

/**
 * @author Mark A. Ziesemer
 * 	<a href="http://www.ziesemer.com.">&lt;www.ziesemer.com&gt;</a>
 */
public class DefaultRegistration{
	
	protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultRegistration.class);
	
	public static final String MBEANS_DOMAIN;
	public static final String DEFAULT_DOMAIN;
	
	protected static final Set<ObjectName> SUCCESSFUL_REGS = new HashSet<ObjectName>();
	protected static final Set<ObjectName> SUCCESSFUL_REGS_RO
		= Collections.unmodifiableSet(SUCCESSFUL_REGS);
	
	static{
		// Because Class.getPackage() isn't always available.
		final String cn = DefaultRegistration.class.getName();
		
		int pkgPos = cn.lastIndexOf(".");
		MBEANS_DOMAIN = cn.substring(0, pkgPos);
		
		pkgPos = cn.lastIndexOf(".", pkgPos - 1);
		DEFAULT_DOMAIN = cn.substring(0, pkgPos);
	}
	
	public static String createMXBeanName(final Class<?> c){
		return createMXBeanName(c.getName());
	}
	
	public static String createMXBeanName(final String cn){
		final int pkgPos = cn.lastIndexOf('.');
		String d = cn.substring(0, pkgPos);
		String n = cn.substring(pkgPos + 1);
		
		if(d.startsWith(MBEANS_DOMAIN)){
			d = DEFAULT_DOMAIN + d.substring(MBEANS_DOMAIN.length());
		}
		if(n.endsWith("MXBean")){
			n = n.substring(0, n.length() - 6);
		}
		
		return d + ":name=" + n;
	}
	
	public static <T> ObjectName register(final T impl, final Class<T> intf) throws JMException{
		final ObjectName on = ObjectName.getInstance(createMXBeanName(intf));
		final StandardMBean smb = new StandardMBeanInfoCombiner6(impl, intf, true);
		final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
		if(!mbs.isRegistered(on)){
			mbs.registerMBean(smb, on);
			return on;
		}
		LOGGER.warn("Name already registered: {}", on);
		return null;
	}
	
	protected static <T> boolean registerInternal(final T impl, final Class<T> intf){
		boolean result = false;
		try{
			final ObjectName on = register(impl, intf);
			if(on != null){
				SUCCESSFUL_REGS.add(on);
				result = true;
			}
		}catch(final JMException jme){
			LOGGER.warn(jme.toString(), jme);
		}
		return result;
	}
	
	/**
	 * @return <code>true</code> if all registrations completed normally and as expected.
	 */
	public static synchronized boolean register(){
		boolean result = true;
		result &= registerInternal(new CharsetMXBeanImpl(), CharsetMXBean.class);
		result &= registerInternal(new SecurityMXBeanImpl(), SecurityMXBean.class);
		result &= registerInternal(new SystemMXBeanImpl(), SystemMXBean.class);
		return result;
	}
	
	/**
	 * @return <code>true</code> if all registrations were unregistered normally and as expected.
	 */
	public static synchronized boolean unregister(){
		final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
		boolean result = true;
		for(final Iterator<ObjectName> oni = SUCCESSFUL_REGS.iterator(); oni.hasNext();){
			try{
				mbs.unregisterMBean(oni.next());
			}catch(final JMException jme){
				result = false;
				LOGGER.warn(jme.toString(), jme);
			}
			oni.remove();
		}
		return result;
	}
	
	/**
	 * @return A read-only view of the current default successful registrations.
	 */
	public static Set<ObjectName> getSuccessfulRegistrations(){
		return SUCCESSFUL_REGS_RO;
	}
	
}