package org.oddjob.jmx.handlers;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.ReflectionException;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaClass;
import org.apache.commons.beanutils.PropertyUtils;
import org.oddjob.framework.WrapDynaClass;
import org.oddjob.jmx.RemoteOperation;
import org.oddjob.jmx.client.ClientHandlerResolver;
import org.oddjob.jmx.client.HandlerVersion;
import org.oddjob.jmx.client.VanillaHandlerResolver;
import org.oddjob.jmx.server.JMXOperationPlus;
import org.oddjob.jmx.server.ServerInterfaceHandler;
import org.oddjob.jmx.server.ServerInterfaceHandlerFactory;
import org.oddjob.jmx.server.ServerSideToolkit;
/**
*/
public class DynaBeanHandlerFactory
implements ServerInterfaceHandlerFactory<Object, DynaBean> {
public static final HandlerVersion VERSION = new HandlerVersion(1, 0);
private static final JMXOperationPlus<Boolean> CONTAINS =
new JMXOperationPlus<Boolean>(
"contains",
"Contains the mapped property.",
Boolean.TYPE,
MBeanOperationInfo.INFO
).addParam(
"property", String.class, "The property name.").addParam(
"key", String.class, "The key.");
private static final JMXOperationPlus<Object> GET_SIMPLE =
new JMXOperationPlus<Object>(
"get",
"Get a simple property.",
Object.class,
MBeanOperationInfo.INFO)
.addParam("property", String.class, "The property name.");
private static final JMXOperationPlus<Object> GET_INDEXED =
new JMXOperationPlus<Object>(
"get",
"Get an indexed property.",
Object.class,
MBeanOperationInfo.INFO)
.addParam("property", String.class, "The property name.")
.addParam("index", Integer.TYPE, "The index.");
private static final JMXOperationPlus<Object> GET_MAPPED =
new JMXOperationPlus<Object>(
"get",
"Get a mapped property.",
Object.class,
MBeanOperationInfo.INFO)
.addParam("property", String.class, "The property name.")
.addParam("key", String.class, "The key.");
private static final JMXOperationPlus<DynaClass> GET_DYNACLASS =
new JMXOperationPlus<DynaClass>(
"getDynaClass",
"Get the DynaClass.",
DynaClass.class,
MBeanOperationInfo.INFO);
private static final JMXOperationPlus<Void> REMOVE =
new JMXOperationPlus<Void>(
"remove",
"Remove a mapped property.",
Void.TYPE,
MBeanOperationInfo.ACTION)
.addParam("property", String.class, "The property name.")
.addParam("key", String.class, "The key.");
private static final JMXOperationPlus<Void> SET_SIMPLE =
new JMXOperationPlus<Void>(
"set",
"Set a simple property.",
Void.TYPE,
MBeanOperationInfo.ACTION)
.addParam("property", String.class, "The property name.")
.addParam("value ", Object.class, "The value.");
private static final JMXOperationPlus<Void> SET_INDEXED =
new JMXOperationPlus<Void>(
"set",
"Set an indexed property.",
Void.TYPE,
MBeanOperationInfo.ACTION)
.addParam("property", String.class, "The property name.")
.addParam("index", Integer.TYPE, "The index.")
.addParam("value ", Object.class, "The value.");
private static final JMXOperationPlus<Void> SET_MAPPED =
new JMXOperationPlus<Void>(
"set",
"Set a mapped property.",
Void.TYPE,
MBeanOperationInfo.ACTION)
.addParam("property", String.class, "The property name.")
.addParam("key", String.class, "The key.")
.addParam("value ", Object.class, "The value.");
public Class<Object> interfaceClass() {
return Object.class;
}
public MBeanAttributeInfo[] getMBeanAttributeInfo() {
return new MBeanAttributeInfo[0];
}
public MBeanOperationInfo[] getMBeanOperationInfo() {
return new MBeanOperationInfo[] {
CONTAINS.getOpInfo(),
GET_SIMPLE.getOpInfo(),
GET_INDEXED.getOpInfo(),
SET_MAPPED.getOpInfo(),
GET_DYNACLASS.getOpInfo(),
REMOVE.getOpInfo(),
SET_SIMPLE.getOpInfo(),
SET_INDEXED.getOpInfo(),
SET_MAPPED.getOpInfo(),
};
}
public MBeanNotificationInfo[] getMBeanNotificationInfo() {
return new MBeanNotificationInfo[0];
}
public ServerInterfaceHandler createServerHandler(Object target,
ServerSideToolkit serverSideToolkit) {
return new DynaBeanServerHandler(target);
}
public ClientHandlerResolver<DynaBean> clientHandlerFactory() {
return new VanillaHandlerResolver<DynaBean>(DynaBean.class.getName());
}
class DynaBeanServerHandler implements ServerInterfaceHandler {
private final Object bean;
DynaBeanServerHandler(Object bean) {
this.bean = bean;
}
public Object invoke(RemoteOperation<?> operation, Object[] params)
throws MBeanException, ReflectionException {
if (CONTAINS.equals(operation)) {
try {
return Boolean.valueOf(!
(PropertyUtils.getMappedProperty(bean, (String) params[0],
(String ) params[1]) == null));
} catch (Exception e) {
throw new MBeanException(e);
}
}
else if (GET_SIMPLE.equals(operation)) {
String property = (String) params[0];
try {
return PropertyUtils.getProperty(bean, property);
} catch (Exception e) {
throw new MBeanException(e);
}
}
else if (GET_INDEXED.equals(operation)) {
try {
return PropertyUtils.getIndexedProperty(bean, (String) params[0],
((Integer) params[1]).intValue());
} catch (Exception e) {
throw new MBeanException(e);
}
}
else if (GET_MAPPED.equals(operation)) {
try {
return PropertyUtils.getMappedProperty(bean, (String) params[0],
(String) params[1]);
} catch (Exception e) {
throw new MBeanException(e);
}
}
else if (GET_DYNACLASS.equals(operation)) {
if (bean instanceof DynaBean) {
return ((DynaBean) bean).getDynaClass();
}
else {
return WrapDynaClass.createDynaClass(bean.getClass());
}
}
else if (REMOVE.equals(operation)) {
try {
PropertyUtils.setMappedProperty(bean, (String) params[0],
(String) params[1], null);
} catch (Exception e) {
throw new MBeanException(e);
}
return Void.TYPE;
}
else if (SET_INDEXED.equals(operation)) {
try {
PropertyUtils.setIndexedProperty(bean, (String) params[0],
((Integer) params[1]).intValue(), params[2]);
} catch (Exception e) {
throw new MBeanException(e);
}
return Void.TYPE;
}
else if (SET_SIMPLE.equals(operation)) {
try {
PropertyUtils.setProperty(bean, (String) params[0],
params[1]);
} catch (Exception e) {
throw new MBeanException(e);
}
return Void.TYPE;
}
else if (SET_MAPPED.equals(operation)) {
try {
PropertyUtils.setMappedProperty(bean, (String) params[0],
(String) params[1], params[2]);
} catch (Exception e) {
throw new MBeanException(e);
}
return Void.TYPE;
}
else {
throw new ReflectionException(
new IllegalStateException("invoked for an unknown method."),
operation.toString());
}
}
public void destroy() {
}
}
}