package org.oddjob.jmx.handlers;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.Notification;
import javax.management.ReflectionException;
import org.oddjob.jmx.RemoteOperation;
import org.oddjob.jmx.client.ClientHandlerResolver;
import org.oddjob.jmx.client.ClientInterfaceHandlerFactory;
import org.oddjob.jmx.client.ClientSideToolkit;
import org.oddjob.jmx.client.HandlerVersion;
import org.oddjob.jmx.client.SimpleHandlerResolver;
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 ObjectInterfaceHandlerFactory
implements ServerInterfaceHandlerFactory<Object, Object> {
public static final HandlerVersion VERSION = new HandlerVersion(1, 0);
private static final JMXOperationPlus<String> TO_STRING =
new JMXOperationPlus<String>(
"toString",
"toString.",
String.class,
MBeanOperationInfo.INFO);
public Class<Object> interfaceClass() {
return Object.class;
}
public MBeanAttributeInfo[] getMBeanAttributeInfo() {
return new MBeanAttributeInfo[0];
}
public MBeanOperationInfo[] getMBeanOperationInfo() {
return new MBeanOperationInfo[] {
TO_STRING.getOpInfo() };
}
public MBeanNotificationInfo[] getMBeanNotificationInfo() {
return new MBeanNotificationInfo[0];
}
public ServerInterfaceHandler createServerHandler(Object target, ServerSideToolkit ojmb) {
return new ServerObjectHandler(target);
}
public ClientHandlerResolver<Object> clientHandlerFactory() {
return new SimpleHandlerResolver<Object>(
ClientObjectHandlerFactory.class.getName(),
VERSION);
}
public static class ClientObjectHandlerFactory implements ClientInterfaceHandlerFactory<Object> {
public Class<Object> interfaceClass() {
return Object.class;
}
public HandlerVersion getVersion() {
return VERSION;
};
public Object createClientHandler(Object proxy, ClientSideToolkit toolkit) {
return new ClientObjectHandler(proxy, toolkit);
}
}
static class ClientObjectHandler {
private final ClientSideToolkit toolkit;
private final Object proxy;
/** Save the remote toString value */
private String toString;
ClientObjectHandler(Object proxy, ClientSideToolkit toolkit) {
this.proxy = proxy;
this.toolkit = toolkit;
}
public String toString() {
if (toString == null) {
try {
toString = toolkit.invoke(TO_STRING);
} catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
if (toString == null) {
toString = "null";
}
}
return toString;
}
public boolean equals(Object other) {
return (other == proxy);
}
@Override
public int hashCode() {
return Proxy.getInvocationHandler(proxy).hashCode();
}
}
class ServerObjectHandler implements ServerInterfaceHandler {
private final Object object;
ServerObjectHandler(Object object) {
this.object = object;
}
public Object invoke(RemoteOperation<?> operation, Object[] params)
throws MBeanException, ReflectionException {
if (TO_STRING.equals(operation)) {
return object.toString();
}
else {
throw new ReflectionException(
new IllegalStateException("invoked for an unknown method."),
operation.toString());
}
}
public Notification[] getLastNotifications() {
return null;
}
public void destroy() {
}
}
}