package fr.ippon.groovy.util; import groovy.lang.GroovyRuntimeException; import groovy.util.GroovyMBean; import java.io.IOException; import java.lang.reflect.Array; import javax.management.JMException; import javax.management.MBeanException; import javax.management.MBeanServerConnection; import javax.management.ObjectName; /** * Extension de {@link GroovyMBean} qui convertit les ObjectName reçu du serveur JMX * en GroovierMBean et les GroovierMBean envoyé au serveur en ObjectName. * * @author Fabien Arrault */ public class GroovierMBean extends GroovyMBean { // TODO : quel doit être la valeur par défaut ? public static boolean EXPAND_OBJECTNAME_COLLECTION = true; public GroovierMBean(MBeanServerConnection server, ObjectName name) throws JMException, IOException { super(server, name); } public GroovierMBean(MBeanServerConnection server, String name) throws JMException, IOException { super(server, name); } public GroovierMBean mbean(String objectName) throws NullPointerException, JMException, IOException { return mbean(new ObjectName(objectName)); } public GroovierMBean mbean(ObjectName objectName) throws JMException, IOException { return new GroovierMBean(server(), objectName); } @Override public Object getProperty(String property) { Object result = super.getProperty(property); result = convertObjectNameToMBean(result); return result; } @Override public void setProperty(String property, Object value) { value = convertMBeanToObjectName(value); super.setProperty(property, value); } @Override public Object invokeMethod(String method, Object arguments) { if (arguments instanceof Object[]) { Object[] argArray = (Object[]) arguments; for (int i = 0; i < argArray.length; i++) { argArray[i] = convertMBeanToObjectName(argArray[i]); } } else { arguments = convertMBeanToObjectName(arguments); } Object result = super.invokeMethod(method, arguments); result = convertObjectNameToMBean(result); return result; } private Object convertMBeanToObjectName(Object value) { if (value instanceof GroovyMBean) { value = ((GroovyMBean) value).name(); } return value; } private Object convertObjectNameToMBean(Object result) { try { if (result instanceof ObjectName) { result = mbean((ObjectName) result); } else if (result != null && EXPAND_OBJECTNAME_COLLECTION) { if (result.getClass().isArray()) { Class componentType = result.getClass().getComponentType(); if (ObjectName.class.isAssignableFrom(componentType)) { // TODO il faudrait aussi vérifier que la dimension est bien 1 ... // conversion : int len = Array.getLength(result); Object newArray = Array.newInstance(GroovierMBean.class, len); for (int i = 0; i < len; i++) { ObjectName objectName = (ObjectName) Array.get(result, i); Array.set(newArray, i, mbean(objectName)); } result = newArray; } } // TODO : gérer Collection aussi ? } } catch (MBeanException e) { throwExceptionWithTarget("Converting ObjectName result : " + result + " to WebLoMbean", e); } catch (Exception e) { throwException("Converting ObjectName result : " + result + " to WebLoMbean", e); } return result; } private void throwException(String m, Exception e) { throw new GroovyRuntimeException(m + e, e); } private void throwExceptionWithTarget(String m, MBeanException e) { throw new GroovyRuntimeException(m + e, e.getTargetException()); } }