package org.jboss.mx.remote;
import org.jboss.mx.server.registry.MBeanEntry;
import org.jboss.mx.remote.connector.ConnectorFactory;
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.QueryExp;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* JMXUtil is a set of utility functions for dealing with JMX servers and
* MBeans
*
* @author <a href="jhaynie@vocalocity.net">Jeff Haynie</a>
* @version $Revision: 1.4 $
*/
public class JMXUtil
{
private static ObjectName mbeanserver;
/**
* get the ObjectName of the MBeanServer
*
* @return object name of the mbean server delegate
* @throws Exception
*/
public static final ObjectName getMBeanServerObjectName()
throws Exception
{
if (mbeanserver == null)
{
mbeanserver = new ObjectName("JMImplementation:type=MBeanServerDelegate");
}
return mbeanserver;
}
/**
* get the MBeanServerId attribute from the server
*
* @param server
* @return mbean server id
* @throws Exception
*/
public static final String getServerId(MBeanServer server)
throws Exception
{
if (server == null)
{
throw new NullPointerException("MBeanServer is null");
}
if (mbeanserver == null)
{
mbeanserver = new ObjectName("JMImplementation:type=MBeanServerDelegate");
}
return (String) server.getAttribute(mbeanserver, "MBeanServerId");
}
/**
* query the server for query constraining the results to only MBeans on the local
* server
*
* @param server
* @param query
* @param exp
* @return query set
* @throws Exception
*/
public static final Set queryLocalMBeans(MBeanServer server, ObjectName query, QueryExp exp)
throws Exception
{
ObjectName on = query;
Set set = server.queryMBeans(on, exp);
Set newSet = new HashSet(set.size());
Iterator i = set.iterator();
String localid = getServerId(server);
while (i.hasNext())
{
// filter out local mbeans
ObjectInstance instance = (ObjectInstance) i.next();
ObjectName obj = instance.getObjectName();
///System.out.println("_>"+instance+", obj="+obj);
String id = obj.getKeyProperty("MBeanServerId");
if (id == null || id.equals(localid))
{
newSet.add(instance);
}
}
return newSet;
}
/**
* query the server for query constraining the results to only MBeans that are not local to
* server (remote)
*
* @param server
* @param query
* @param exp
* @return query set
* @throws Exception
*/
public static final Set queryRemoteMBeans(MBeanServer server, ObjectName query, QueryExp exp)
throws Exception
{
ObjectName on = query;
String localid = getServerId(server);
Set set = server.queryMBeans(query, exp);
Set newSet = new HashSet(set.size());
Iterator i = set.iterator();
while (i.hasNext())
{
// filter out local mbeans
ObjectInstance instance = (ObjectInstance) i.next();
ObjectName obj = instance.getObjectName();
String id = obj.getKeyProperty("MBeanServerId");
if (id != null && id.equals(localid) == false)
{
newSet.add(instance);
}
}
return newSet;
}
/**
* using the <tt>JMImplementation:type=MBeanRegistry</tt> MBean implementation, if exists, try
* and return the appropriate ObjectName classloader. returns null if not found
*
* @param server
* @param obj
* @return classloader
*/
public static ClassLoader getObjectNameClassLoader (MBeanServer server,ObjectName obj)
{
try
{
ObjectName objName=new ObjectName("JMImplementation:type=MBeanRegistry");
MBeanEntry me=(MBeanEntry)server.invoke(objName,"get",new Object[]{obj},new String[]{ObjectName.class.getName()});
if (me!=null)
{
return me.getClassLoader();
}
}
catch (Exception ex)
{
}
return null;
}
/**
*
* @param localMBeanServer
* @param objName
* @param opName
* @param args
* @param sig
* @return invocation return value
* @throws Exception
*/
public static Object invoke (MBeanServer localMBeanServer, ObjectName objName, String opName, Object args[], String sig[])
throws Exception
{
String remoteId = objName.getKeyProperty("MBeanServerId");
if (remoteId==null)
{
return localMBeanServer.invoke(objName,opName,args,sig);
}
String localId = getServerId(localMBeanServer);
if (localId.equals(remoteId))
{
return localMBeanServer.invoke(objName,opName,args,sig);
}
else
{
MBeanServer remote=ConnectorFactory.getMBeanServerForServerId(remoteId);
if (remote==null)
{
throw new IllegalArgumentException("Couldn't find a Connector to remote MBeanServer: "+remoteId);
}
else
{
ObjectName localName = JMXRemotingObjectName.toLocal(objName);
return remote.invoke(localName,opName,args,sig);
}
}
}
}