/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.managed.plugins.jmx;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryManagerMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.AnnotatedElement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
import org.jboss.managed.api.ManagedObject;
import org.jboss.managed.api.factory.ManagedObjectFactory;
import org.jboss.metadata.plugins.loader.reflection.AnnotatedElementMetaDataLoader;
import org.jboss.metadata.spi.MetaData;
import org.jboss.metadata.spi.retrieval.MetaDataRetrievalToMetaDataBridge;
import org.jboss.metatype.api.types.ArrayMetaType;
import org.jboss.metatype.api.types.CompositeMetaType;
import org.jboss.metatype.api.types.EnumMetaType;
import org.jboss.metatype.api.types.ImmutableCompositeMetaType;
import org.jboss.metatype.api.types.MetaType;
import org.jboss.metatype.api.types.SimpleMetaType;
import org.jboss.metatype.api.values.ArrayValue;
import org.jboss.metatype.api.values.CompositeValue;
import org.jboss.metatype.api.values.EnumValue;
import org.jboss.metatype.api.values.MetaValue;
import org.jboss.metatype.api.values.SimpleValue;
/**
* A utility class that created ManagedObjects for the jmx platform mbeans
* returned by {@link java.lang.management.ManagementFactory}
*
* @author Scott.Stark@jboss.org
* @version $Revision:$
*/
public class ManagementFactoryUtils
{
/**
* Return a Map of the platform mbean ManagedObjects. This does not include
* the MemoryManagerMXBeans, GarbageCollectorMXBeans or MemoryPoolMXBeans
* lists of ManagedObjects.
* @param mof - the ManagedObjectFactory to use
* @return Map of ManagedObjects for the platform mbeans keyed by the ManagedObject names
*/
public static Map<String, ManagedObject> getPlatformMBeanMOs(ManagedObjectFactory mof)
{
HashMap<String, ManagedObject> mos = new HashMap<String, ManagedObject>();
ManagedObject classLoadingMO = getClassLoadingMO(mof);
mos.put(classLoadingMO.getName(), classLoadingMO);
ManagedObject memoryMXBean = getMemoryMXBean(mof);
mos.put(memoryMXBean.getName(), memoryMXBean);
ManagedObject operatingSystemMXBean = getOperatingSystemMXBean(mof);
mos.put(operatingSystemMXBean.getName(), operatingSystemMXBean);
ManagedObject threadMXBean = getThreadMXBean(mof);
mos.put(threadMXBean.getName(), threadMXBean);
ManagedObject runtimeMXBean = getRuntimeMXBean(mof);
mos.put(runtimeMXBean.getName(), runtimeMXBean);
return mos;
}
/**
* Build a ManagedObject for the ClassLoadingMXBean mean
* @param mof - the ManagedObjectFactory to use
* @return
*/
public static ManagedObject getClassLoadingMO(ManagedObjectFactory mof)
{
ClassLoadingMXBean mbean = ManagementFactory.getClassLoadingMXBean();
ManagedObject mo = getMO(mbean, ClassLoadingMXBeanMO.class, mof);
return mo;
}
/**
* Build a ManagedObject for the MemoryMXBean mean
* @param mof - the ManagedObjectFactory to use
* @return
*/
public static ManagedObject getMemoryMXBean(ManagedObjectFactory mof)
{
MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
ManagedObject mo = getMO(mbean, MemoryMXBeanMO.class, mof);
return mo;
}
/**
* Build a ManagedObject for the OperatingSystemMXBean mean
* @param mof - the ManagedObjectFactory to use
* @return
*/
public static ManagedObject getOperatingSystemMXBean(ManagedObjectFactory mof)
{
OperatingSystemMXBean mbean = ManagementFactory.getOperatingSystemMXBean();
ManagedObject mo = getMO(mbean, OperatingSystemMXBeanMO.class, mof);
return mo;
}
/**
* Build a ManagedObject for the ThreadMXBean mean
* @param mof - the ManagedObjectFactory to use
* @return
*/
public static ManagedObject getThreadMXBean(ManagedObjectFactory mof)
{
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
ManagedObject mo = getMO(mbean, ThreadMXBeanMO.class, mof);
return mo;
}
/**
* Build a ManagedObject for the RuntimeMXBean mean
* @param mof - the ManagedObjectFactory to use
* @return
*/
public static ManagedObject getRuntimeMXBean(ManagedObjectFactory mof)
{
RuntimeMXBean mbean = ManagementFactory.getRuntimeMXBean();
ManagedObject mo = getMO(mbean, RuntimeMXBeanMO.class, mof);
return mo;
}
/**
* Build a list of ManagedObject for the MemoryManagerMXBean means
* @param mof - the ManagedObjectFactory to use
* @return
*/
public static List<ManagedObject> getMemoryManagerMXBeans(ManagedObjectFactory mof)
{
List<MemoryManagerMXBean> mbeans = ManagementFactory.getMemoryManagerMXBeans();
ArrayList<ManagedObject> mos = new ArrayList<ManagedObject>();
for(MemoryManagerMXBean mbean : mbeans)
{
ManagedObject mo = getMO(mbean, MemoryManagerMXBeanMO.class, mof);
mos.add(mo);
}
return mos;
}
/**
* Build a list of ManagedObject for the GarbageCollectorMXBean means
* @param mof - the ManagedObjectFactory to use
* @return
*/
public static List<ManagedObject> getGarbageCollectorMXBeans(ManagedObjectFactory mof)
{
List<GarbageCollectorMXBean> mbeans = ManagementFactory.getGarbageCollectorMXBeans();
ArrayList<ManagedObject> mos = new ArrayList<ManagedObject>();
for(GarbageCollectorMXBean mbean : mbeans)
{
ManagedObject mo = getMO(mbean, GarbageCollectorMXBeanMO.class, mof);
mos.add(mo);
}
return mos;
}
/**
* Build a list of ManagedObject for the MemoryPoolMXBean means
* @param mof - the ManagedObjectFactory to use
* @return
*/
public static List<ManagedObject> getMemoryPoolMXBeans(ManagedObjectFactory mof)
{
List<MemoryPoolMXBean> mbeans = ManagementFactory.getMemoryPoolMXBeans();
ArrayList<ManagedObject> mos = new ArrayList<ManagedObject>();
for(MemoryPoolMXBean mbean : mbeans)
{
ManagedObject mo = getMO(mbean, MemoryPoolMXBeanMO.class, mof);
mos.add(mo);
}
return mos;
}
/**
* Unwrap a CompositeValue for a MemoryUsage instance into the MemoryUsage.
*
* @param mv - the CompositeValue meta value
* @return the corresponding MemoryUsage instance
*/
public static MemoryUsage unwrapMemoryUsage(CompositeValue mv)
{
SimpleValue committedSV = SimpleValue.class.cast(mv.get("committed"));
SimpleValue initSV = SimpleValue.class.cast(mv.get("init"));
SimpleValue maxSV = SimpleValue.class.cast(mv.get("max"));
SimpleValue usedSV = SimpleValue.class.cast(mv.get("used"));
long committed = (Long) committedSV.getValue();
long init = (Long) initSV.getValue();
long max = (Long) maxSV.getValue();
long used = (Long) usedSV.getValue();
MemoryUsage mu = new MemoryUsage(init, used, committed, max);
return mu;
}
public static <I> ManagedObject getMO(I mbean, final Class<? extends I> c, ManagedObjectFactory mof)
{
AnnotatedElement mbeanClass = c;
AnnotatedElementMetaDataLoader retrieval = new AnnotatedElementMetaDataLoader(mbeanClass);
MetaData metaData = new MetaDataRetrievalToMetaDataBridge(retrieval);
ManagedObject mo = mof.initManagedObject(mbean, c, metaData, null, null);
return mo;
}
public static ThreadInfo unwrapThreadInfo(CompositeValue mv)
throws OpenDataException, ClassNotFoundException
{
CompositeData cd = (CompositeData) getOpenValue(mv);
ThreadInfo ti = ThreadInfo.from(cd);
return ti;
}
static OpenType getOpenType(MetaType type) throws OpenDataException
{
OpenType openType = null;
if(type instanceof SimpleMetaType)
openType = getOpenType(SimpleMetaType.class.cast(type));
else if(type instanceof CompositeMetaType)
openType = getOpenType(CompositeMetaType.class.cast(type));
else if(type instanceof ArrayMetaType)
openType = getOpenType(ArrayMetaType.class.cast(type));
else if(type instanceof EnumMetaType)
openType = SimpleType.STRING;
else
throw new OpenDataException("Unhandled MetaType: "+type);
return openType;
}
static OpenType getOpenType(SimpleMetaType type)
{
OpenType openType = null;
if(type.equalsIgnorePrimitive(SimpleMetaType.BOOLEAN))
openType = SimpleType.BOOLEAN;
else if(type.equalsIgnorePrimitive(SimpleMetaType.BYTE))
openType = SimpleType.BYTE;
else if(type.equalsIgnorePrimitive(SimpleMetaType.CHARACTER))
openType = SimpleType.CHARACTER;
else if(type.equalsIgnorePrimitive(SimpleMetaType.LONG))
openType = SimpleType.LONG;
else if(type.equalsIgnorePrimitive(SimpleMetaType.INTEGER))
openType = SimpleType.INTEGER;
else if(type.equalsIgnorePrimitive(SimpleMetaType.SHORT))
openType = SimpleType.SHORT;
else if(type.equalsIgnorePrimitive(SimpleMetaType.STRING))
openType = SimpleType.STRING;
return openType;
}
static ArrayType getOpenType(ArrayMetaType type) throws OpenDataException
{
int dimension = type.getDimension();
OpenType elementType = getOpenType(type.getElementType());
ArrayType openType = new ArrayType(dimension, elementType);
return openType;
}
static CompositeType getOpenType(CompositeMetaType type)
throws OpenDataException
{
String[] items = new String[type.itemSet().size()];
type.itemSet().toArray(items);
String[] descriptions = new String[type.itemSet().size()];
OpenType[] itemTypes = new OpenType[items.length];
for(int n = 0; n < items.length; n ++)
{
String item = items[n];
descriptions[n] = type.getDescription(item);
MetaType mt = type.getType(item);
itemTypes[n] = getOpenType(mt);
}
CompositeType ct = new CompositeType(type.getTypeName(),
type.getDescription(), items, descriptions, itemTypes);
return ct;
}
static Object getOpenValue(MetaValue mv) throws OpenDataException
{
Object openValue = null;
if(mv instanceof SimpleValue)
{
SimpleValue sv = SimpleValue.class.cast(mv);
openValue = sv.getValue();
}
else if(mv instanceof CompositeValue)
{
CompositeValue cv = CompositeValue.class.cast(mv);
HashMap<String, Object> itemsMap = new HashMap<String, Object>();
CompositeMetaType cmt = cv.getMetaType();
String[] items = new String[cmt.itemSet().size()];
Object[] itemValues = new Object[items.length];
cmt.itemSet().toArray(items);
for(int n = 0; n < items.length; n ++)
{
String item = items[n];
MetaValue itemMV = cv.get(item);
Object itemValue = null;
if(itemMV != null )
itemValue = getOpenValue(itemMV);
itemValues[n] = itemValue;
}
CompositeType ct = getOpenType(cmt);
CompositeDataSupport cd = new CompositeDataSupport(ct, items, itemValues);
openValue = cd;
}
else if(mv instanceof ArrayValue)
{
ArrayValue av = ArrayValue.class.cast(mv);
if(av.getMetaType().isPrimitiveArray() || av.getMetaType().isSimple())
openValue = av.getValue();
else if(av.getMetaType().getElementType().isComposite())
{
CompositeData[] cd = new CompositeData[av.getLength()];
for(int n = 0; n < av.getLength(); n ++)
{
cd[n] = (CompositeData) getOpenValue(CompositeValue.class.cast(av.getValue(n)));
}
openValue = cd;
}
}
else if(mv instanceof EnumValue)
{
EnumValue ev = EnumValue.class.cast(mv);
openValue = ev.getValue();
}
else
{
throw new OpenDataException("Unhandled MetaValue: "+mv);
}
return openValue;
}
static MetaType getMetaType(OpenType type)
throws Exception
{
MetaType metaType = null;
if(type instanceof SimpleType)
metaType = getMetaType(SimpleType.class.cast(type));
else if(type instanceof CompositeType)
metaType = getMetaType(CompositeType.class.cast(type));
else if(type instanceof ArrayType)
metaType = getMetaType(ArrayType.class.cast(type));
else
throw new Exception("Unhandled OpenType: "+type);
return metaType;
}
static SimpleMetaType getMetaType(SimpleType type)
{
SimpleMetaType metaType = null;
if(type == SimpleType.BOOLEAN)
metaType = SimpleMetaType.BOOLEAN;
else if(type == SimpleType.BYTE)
metaType = SimpleMetaType.BYTE;
else if(type == SimpleType.CHARACTER)
metaType = SimpleMetaType.CHARACTER;
else if(type == SimpleType.LONG)
metaType = SimpleMetaType.LONG;
else if(type == SimpleType.INTEGER)
metaType = SimpleMetaType.INTEGER;
else if(type == SimpleType.SHORT)
metaType = SimpleMetaType.SHORT;
else if(type == SimpleType.STRING)
metaType = SimpleMetaType.STRING;
return metaType;
}
static ArrayMetaType getMetaType(ArrayType type)
throws Exception
{
int dimension = type.getDimension();
OpenType elementType = type.getElementOpenType();
MetaType elementMetaType = getMetaType(elementType);
ArrayMetaType metaType = new ArrayMetaType(dimension, elementMetaType);
return metaType;
}
static CompositeMetaType getMetaType(CompositeType type)
throws Exception
{
String[] itemNames = new String[type.keySet().size()];
String[] itemDescriptions = new String[itemNames.length];
MetaType[] itemTypes = new MetaType[itemNames.length];
type.keySet().toArray(itemNames);
for(int n = 0; n < itemNames.length; n ++)
{
String itemName = itemNames[n];
itemDescriptions[n] = type.getDescription(itemName);
OpenType ot = type.getType(itemName);
itemTypes[n] = getMetaType(ot);
}
String typeName = type.getTypeName();
String description = type.getDescription();
CompositeMetaType cmt = new ImmutableCompositeMetaType(typeName, description, itemNames, itemDescriptions, itemTypes);
return cmt;
}
}