/* * (c) Rob Gordon 2005. */ package org.oddjob.jmx.server; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import javax.management.JMException; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.apache.log4j.Logger; import org.oddjob.arooa.ArooaSession; /** * A factory for producing OddjobMBeans. The MBean names are just sequential formatted numbers. * The root name is created with the 0 number. * */ public class OddjobMBeanFactory implements ServerSession { private static final Logger logger = Logger.getLogger(OddjobMBeanFactory.class); /** The server */ private final MBeanServer server; private final ArooaSession session; /** Give each bean a serial number. */ private final AtomicInteger serial = new AtomicInteger(); /** Keep track of MBeans by ObjectName so that we can destroy them * when they're finished. */ private final Map<ObjectName, OddjobMBean> mBeans = new HashMap<ObjectName, OddjobMBean>(); private final Map<Object, ObjectName> names = new HashMap<Object, ObjectName>(); /** * Constructor. * * @param server The server to register newly created beans with. */ public OddjobMBeanFactory(MBeanServer server, ArooaSession session) { this.server = server; this.session = session; } /** * Create an MBean and register with the server using the generated name. * * @param object The object the MBean is wrapping. * @return context The server context for the object. * * @throws JMException If the MBean fails to register. */ public ObjectName createMBeanFor(Object object, ServerContext context) throws JMException { ObjectName objName = objectName(serial.getAndIncrement()); OddjobMBean ojmb = new OddjobMBean(object, objName, this, context); server.registerMBean(ojmb, objName); synchronized (this) { names.put(object, objName); mBeans.put(objName, ojmb); } logger.debug("Created and registered [" + object + "] as OddjobMBean [" + objName.toString() + "]"); return objName; } /** * Remove a bean from the server. * * @param objName The bean. * @throws JMException */ public void destroy(ObjectName objName) throws JMException { if (objName == null) { throw new NullPointerException("No Object Name."); } OddjobMBean ojmb = null; synchronized (this) { ojmb = mBeans.remove(objName); if (ojmb == null) { throw new IllegalStateException("No MBean named " + objName); } names.remove(ojmb.getNode()); } ojmb.destroy(); server.unregisterMBean(objName); logger.debug("Unregistered and destroyed [" + ojmb + "]"); } /** * Helper function to build the object name from the sequence number. * * @param sequence The object sequence number. * @return A JMX object name. */ public static ObjectName objectName(int sequence) { try { NumberFormat f = new DecimalFormat("00000000"); String uid = f.format(sequence); return new ObjectName("oddjob", "uid", uid); } catch (MalformedObjectNameException ex) { throw new RuntimeException(ex); } } public ObjectName nameFor(Object object) { synchronized (this) { return names.get(object); } } public Object objectFor(ObjectName objectName) { OddjobMBean mBean = null; synchronized (this) { mBean = mBeans.get(objectName); if (mBean == null) { return null; } } return mBean.getNode(); } @Override public ArooaSession getArooaSession() { return session; } }