/* */ package org.jboss.mx.mxbean;
/* */
/* */ import java.io.Serializable;
/* */ import java.lang.reflect.InvocationHandler;
/* */ import java.lang.reflect.Method;
/* */ import java.lang.reflect.Proxy;
/* */ import java.lang.reflect.Type;
/* */ import java.util.HashMap;
/* */ import java.util.Map;
/* */ import javax.management.Attribute;
/* */ import javax.management.MBeanAttributeInfo;
/* */ import javax.management.MBeanInfo;
/* */ import javax.management.MBeanOperationInfo;
/* */ import javax.management.MBeanParameterInfo;
/* */ import javax.management.MBeanServerConnection;
/* */ import javax.management.NotificationBroadcaster;
/* */ import javax.management.NotificationEmitter;
/* */ import javax.management.NotificationFilter;
/* */ import javax.management.NotificationListener;
/* */ import javax.management.ObjectName;
/* */ import javax.management.openmbean.OpenMBeanAttributeInfo;
/* */ import javax.management.openmbean.OpenMBeanInfo;
/* */ import javax.management.openmbean.OpenMBeanOperationInfo;
/* */ import javax.management.openmbean.OpenMBeanParameterInfo;
/* */ import javax.management.openmbean.OpenType;
/* */ import org.jboss.mx.util.JMXExceptionDecoder;
/* */
/* */ public class MXBeanInvocationHandler
/* */ implements InvocationHandler, Serializable
/* */ {
/* */ private static final long serialVersionUID = -2872014223541692039L;
/* 61 */ private static final Class[] LISTENER = { NotificationListener.class };
/* 62 */ private static final Class[] TRIPLET = { NotificationListener.class, NotificationFilter.class, Object.class };
/* */ private static final Method EQUALS;
/* */ private static final Method HASH_CODE;
/* */ private static final Method TO_STRING;
/* */ private static final Method ADD_NOTIFICATION_LISTENER;
/* */ private static final Method GET_NOTIFICATION_INFO;
/* */ private static final Method REMOVE_NOTIFICATION_LISTENER;
/* */ private static final Method REMOVE_NOTIFICATION_LISTENER_TRIPLET;
/* */ private MBeanServerConnection mbeanServerConnection;
/* */ private Class<?> mxbeanInterface;
/* */ private ObjectName objectName;
/* */ private transient Map<Method, Action> mappings;
/* */ private transient OpenMBeanInfo mbeanInfo;
/* */
/* */ public MXBeanInvocationHandler(MBeanServerConnection mbeanServerConnection, Class<?> mxbeanInterface, ObjectName objectName)
/* */ {
/* 115 */ if (mbeanServerConnection == null)
/* 116 */ throw new IllegalArgumentException("Null mbeanServerConnection");
/* 117 */ if (mxbeanInterface == null)
/* 118 */ throw new IllegalArgumentException("Null mxmbeanInterface");
/* 119 */ if (objectName == null) {
/* 120 */ throw new IllegalArgumentException("Null objectName");
/* */ }
/* 122 */ this.mbeanServerConnection = mbeanServerConnection;
/* 123 */ this.mxbeanInterface = mxbeanInterface;
/* 124 */ this.objectName = objectName;
/* */ }
/* */
/* */ public MBeanServerConnection getMBeanServerConnection()
/* */ {
/* 134 */ return this.mbeanServerConnection;
/* */ }
/* */
/* */ public Class<?> getMXBeanInterface()
/* */ {
/* 144 */ return this.mxbeanInterface;
/* */ }
/* */
/* */ public ObjectName getObjectName()
/* */ {
/* 154 */ return this.objectName;
/* */ }
/* */
/* */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
/* */ {
/* */ try
/* */ {
/* 161 */ return getAction(proxy, method).perform(args);
/* */ }
/* */ catch (Throwable t) {
/* */ }
/* 165 */ throw JMXExceptionDecoder.decode(t);
/* */ }
/* */
/* */ private Action getAction(Object proxy, Method method)
/* */ throws Throwable
/* */ {
/* 180 */ if (this.mappings == null) {
/* 181 */ this.mappings = getMappings(proxy);
/* */ }
/* */
/* 184 */ Action result = (Action)this.mappings.get(method);
/* 185 */ if (result == null) {
/* 186 */ throw new UnsupportedOperationException("Unknown method: " + method);
/* */ }
/* */
/* 189 */ return result;
/* */ }
/* */
/* */ private Map<Method, Action> getMappings(Object proxy)
/* */ throws Throwable
/* */ {
/* 201 */ this.mbeanInfo = ((OpenMBeanInfo)this.mbeanServerConnection.getMBeanInfo(this.objectName));
/* 202 */ Map attributesMap = new HashMap();
/* 203 */ MBeanAttributeInfo[] attributes = this.mbeanInfo.getAttributes();
/* 204 */ for (int i = 0; i < attributes.length; i++)
/* */ {
/* 206 */ OpenMBeanAttributeInfo openAttribute = (OpenMBeanAttributeInfo)attributes[i];
/* 207 */ attributesMap.put(openAttribute.getName(), openAttribute);
/* */ }
/* 209 */ MBeanOperationInfo[] operations = this.mbeanInfo.getOperations();
/* */
/* 211 */ Map result = new HashMap();
/* */
/* 213 */ Class[] interfaces = proxy.getClass().getInterfaces();
/* 214 */ for (int i = 0; i < interfaces.length; i++)
/* */ {
/* 216 */ if (NotificationBroadcaster.class.isAssignableFrom(interfaces[i]))
/* */ {
/* 218 */ result.put(ADD_NOTIFICATION_LISTENER, new AddNotificationListenerAction(null));
/* 219 */ result.put(GET_NOTIFICATION_INFO, new GetNotificationInfoAction(null));
/* 220 */ result.put(REMOVE_NOTIFICATION_LISTENER, new RemoveNotificationListenerAction(null));
/* 221 */ result.put(REMOVE_NOTIFICATION_LISTENER_TRIPLET, new RemoveNotificationListenerTripletAction(null));
/* */ }
/* */ else
/* */ {
/* 225 */ Method[] methods = interfaces[i].getMethods();
/* 226 */ for (Method method : methods)
/* */ {
/* 228 */ String methodName = method.getName();
/* 229 */ Class returnType = method.getReturnType();
/* 230 */ Class[] parameterTypes = method.getParameterTypes();
/* */
/* 233 */ if ((methodName.startsWith("get")) && (methodName.length() > 3) && (!Void.TYPE.equals(returnType)) && (parameterTypes.length == 0))
/* */ {
/* 238 */ String name = methodName.substring(3);
/* 239 */ OpenMBeanAttributeInfo attribute = (OpenMBeanAttributeInfo)attributesMap.get(name);
/* 240 */ if (attribute != null)
/* */ {
/* 242 */ Type type = method.getGenericReturnType();
/* 243 */ result.put(method, new GetAction(attribute, type));
/* 244 */ continue;
/* */ }
/* */
/* */ }
/* 248 */ else if ((methodName.startsWith("is")) && (methodName.length() > 2) && (Boolean.TYPE.equals(returnType)) && (parameterTypes.length == 0))
/* */ {
/* 253 */ String name = methodName.substring(2);
/* 254 */ OpenMBeanAttributeInfo attribute = (OpenMBeanAttributeInfo)attributesMap.get(name);
/* 255 */ if (attribute != null)
/* */ {
/* 257 */ Type type = method.getGenericReturnType();
/* 258 */ result.put(method, new GetAction(attribute, type));
/* 259 */ continue;
/* */ }
/* */
/* */ }
/* 263 */ else if ((methodName.startsWith("set")) && (methodName.length() > 3) && (Void.TYPE.equals(returnType)) && (parameterTypes.length == 1))
/* */ {
/* 268 */ String name = methodName.substring(3);
/* 269 */ OpenMBeanAttributeInfo attribute = (OpenMBeanAttributeInfo)attributesMap.get(name);
/* 270 */ if (attribute != null)
/* */ {
/* 272 */ result.put(method, new SetAction(attribute));
/* 273 */ continue;
/* */ }
/* */ }
/* */
/* 277 */ OpenMBeanOperationInfo operation = findOperation(methodName, method.getGenericParameterTypes(), operations);
/* 278 */ if (operation != null)
/* */ {
/* 280 */ String[] signature = getSignature(method);
/* 281 */ Type type = method.getGenericReturnType();
/* 282 */ result.put(method, new InvokeAction(operation, signature, type));
/* */ }
/* */ else
/* */ {
/* 286 */ result.put(method, new InvalidAction(method));
/* */ }
/* */ }
/* */ }
/* */
/* */ }
/* */
/* 293 */ result.put(EQUALS, new EqualsAction(null));
/* 294 */ result.put(HASH_CODE, new HashCodeAction(null));
/* 295 */ result.put(TO_STRING, new ToStringAction(null));
/* */
/* 297 */ return result;
/* */ }
/* */
/* */ private static OpenMBeanOperationInfo findOperation(String name, Type[] parameterTypes, MBeanOperationInfo[] operations)
/* */ {
/* 302 */ OpenType[] signature = getSignature(parameterTypes);
/* 303 */ for (int i = 0; i < operations.length; i++)
/* */ {
/* 305 */ if (!operations[i].getName().equals(name))
/* */ continue;
/* 307 */ MBeanParameterInfo[] parameters = operations[i].getSignature();
/* 308 */ boolean match = true;
/* 309 */ for (int p = 0; (p < parameters.length) && (match); p++)
/* */ {
/* 311 */ OpenMBeanParameterInfo openMBeanParameterInfo = (OpenMBeanParameterInfo)parameters[p];
/* 312 */ if (!signature[p].equals(openMBeanParameterInfo.getOpenType()))
/* 313 */ match = false;
/* */ }
/* 315 */ if (match)
/* 316 */ return (OpenMBeanOperationInfo)operations[i];
/* */ }
/* 318 */ return null;
/* */ }
/* */
/* */ private static String[] getSignature(Method method)
/* */ {
/* 323 */ Class[] parameterTypes = method.getParameterTypes();
/* 324 */ String[] signature = new String[parameterTypes.length];
/* 325 */ for (int p = 0; p < parameterTypes.length; p++)
/* 326 */ signature[p] = parameterTypes[p].getName();
/* 327 */ return signature;
/* */ }
/* */
/* */ private static OpenType[] getSignature(Type[] parameterTypes)
/* */ {
/* 332 */ OpenType[] signature = new OpenType[parameterTypes.length];
/* 333 */ for (int p = 0; p < parameterTypes.length; p++)
/* 334 */ signature[p] = MXBeanUtils.getOpenType(parameterTypes[p]);
/* 335 */ return signature;
/* */ }
/* */
/* */ static
/* */ {
/* */ try
/* */ {
/* 92 */ ADD_NOTIFICATION_LISTENER = NotificationBroadcaster.class.getDeclaredMethod("addNotificationListener", TRIPLET);
/* 93 */ GET_NOTIFICATION_INFO = NotificationBroadcaster.class.getDeclaredMethod("getNotificationInfo", new Class[0]);
/* 94 */ REMOVE_NOTIFICATION_LISTENER = NotificationBroadcaster.class.getDeclaredMethod("removeNotificationListener", LISTENER);
/* 95 */ REMOVE_NOTIFICATION_LISTENER_TRIPLET = NotificationEmitter.class.getDeclaredMethod("removeNotificationListener", TRIPLET);
/* 96 */ EQUALS = Object.class.getDeclaredMethod("equals", new Class[] { Object.class });
/* 97 */ HASH_CODE = Object.class.getDeclaredMethod("hashCode", new Class[0]);
/* 98 */ TO_STRING = Object.class.getDeclaredMethod("toString", new Class[0]);
/* */ }
/* */ catch (Exception e)
/* */ {
/* 102 */ throw new RuntimeException(e);
/* */ }
/* */ }
/* */
/* */ private class RemoveNotificationListenerTripletAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private RemoveNotificationListenerTripletAction()
/* */ {
/* */ }
/* */
/* */ public Object perform(Object[] args)
/* */ throws Throwable
/* */ {
/* 490 */ NotificationListener listener = (NotificationListener)args[0];
/* 491 */ NotificationFilter filter = (NotificationFilter)args[1];
/* 492 */ Object handback = args[2];
/* 493 */ MXBeanInvocationHandler.this.mbeanServerConnection.removeNotificationListener(MXBeanInvocationHandler.this.objectName, listener, filter, handback);
/* 494 */ return null;
/* */ }
/* */ }
/* */
/* */ private class RemoveNotificationListenerAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private RemoveNotificationListenerAction()
/* */ {
/* */ }
/* */
/* */ public Object perform(Object[] args)
/* */ throws Throwable
/* */ {
/* 480 */ NotificationListener listener = (NotificationListener)args[0];
/* 481 */ MXBeanInvocationHandler.this.mbeanServerConnection.removeNotificationListener(MXBeanInvocationHandler.this.objectName, listener);
/* 482 */ return null;
/* */ }
/* */ }
/* */
/* */ private class GetNotificationInfoAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private GetNotificationInfoAction()
/* */ {
/* */ }
/* */
/* */ public Object perform(Object[] args)
/* */ throws Throwable
/* */ {
/* 472 */ return MXBeanInvocationHandler.this.mbeanServerConnection.getMBeanInfo(MXBeanInvocationHandler.this.objectName).getNotifications();
/* */ }
/* */ }
/* */
/* */ private class AddNotificationListenerAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private AddNotificationListenerAction()
/* */ {
/* */ }
/* */
/* */ public Object perform(Object[] args)
/* */ throws Throwable
/* */ {
/* 460 */ NotificationListener listener = (NotificationListener)args[0];
/* 461 */ NotificationFilter filter = (NotificationFilter)args[1];
/* 462 */ Object handback = args[2];
/* 463 */ MXBeanInvocationHandler.this.mbeanServerConnection.addNotificationListener(MXBeanInvocationHandler.this.objectName, listener, filter, handback);
/* 464 */ return null;
/* */ }
/* */ }
/* */
/* */ private class ToStringAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private ToStringAction()
/* */ {
/* */ }
/* */
/* */ public Object perform(Object[] args)
/* */ throws Throwable
/* */ {
/* 452 */ return "MXBeanInvocationHandler(" + MXBeanInvocationHandler.this.objectName + ")";
/* */ }
/* */ }
/* */
/* */ private class HashCodeAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private HashCodeAction()
/* */ {
/* */ }
/* */
/* */ public Object perform(Object[] args)
/* */ throws Throwable
/* */ {
/* 444 */ return Integer.valueOf(MXBeanInvocationHandler.this.objectName.hashCode());
/* */ }
/* */ }
/* */
/* */ private class EqualsAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private EqualsAction()
/* */ {
/* */ }
/* */
/* */ public Object perform(Object[] args)
/* */ throws Throwable
/* */ {
/* 429 */ Object object = args[0];
/* 430 */ if ((object == null) || (!(object instanceof Proxy)))
/* 431 */ return Boolean.valueOf(false);
/* 432 */ InvocationHandler handler = Proxy.getInvocationHandler(object);
/* 433 */ if (!(handler instanceof MXBeanInvocationHandler))
/* 434 */ return Boolean.valueOf(false);
/* 435 */ MXBeanInvocationHandler other = (MXBeanInvocationHandler)handler;
/* 436 */ return Boolean.valueOf((MXBeanInvocationHandler.this.mbeanServerConnection.equals(other.mbeanServerConnection)) && (MXBeanInvocationHandler.this.objectName.equals(other.objectName)));
/* */ }
/* */ }
/* */
/* */ private class InvalidAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private Method method;
/* */
/* */ public InvalidAction(Method method)
/* */ {
/* 416 */ this.method = method;
/* */ }
/* */
/* */ public Object perform(Object[] args) throws Throwable
/* */ {
/* 421 */ throw new UnsupportedOperationException(this.method + " is not mapped to the MBeanInfo operations for " + MXBeanInvocationHandler.this.objectName);
/* */ }
/* */ }
/* */
/* */ private class InvokeAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private OpenMBeanOperationInfo operation;
/* */ private String[] signature;
/* */ private Type type;
/* */
/* */ public InvokeAction(OpenMBeanOperationInfo operation, String[] signature, Type type)
/* */ {
/* 389 */ this.operation = operation;
/* 390 */ this.signature = signature;
/* 391 */ this.type = type;
/* */ }
/* */
/* */ public Object perform(Object[] args) throws Throwable
/* */ {
/* 396 */ MBeanParameterInfo[] parameters = this.operation.getSignature();
/* 397 */ Object[] arguments = new Object[args.length];
/* 398 */ for (int i = 0; i < parameters.length; i++)
/* */ {
/* 400 */ OpenMBeanParameterInfo parameter = (OpenMBeanParameterInfo)parameters[i];
/* 401 */ arguments[i] = MXBeanUtils.construct(parameter.getOpenType(), args[i], this.operation.getName());
/* */ }
/* */
/* 404 */ Object result = MXBeanInvocationHandler.this.mbeanServerConnection.invoke(MXBeanInvocationHandler.this.objectName, this.operation.getName(), arguments, this.signature);
/* */
/* 406 */ return MXBeanUtils.reconstruct(this.operation.getReturnOpenType(), this.type, result, this.operation.getName());
/* */ }
/* */ }
/* */
/* */ private class SetAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private OpenMBeanAttributeInfo attribute;
/* */
/* */ public SetAction(OpenMBeanAttributeInfo attribute)
/* */ {
/* 368 */ this.attribute = attribute;
/* */ }
/* */
/* */ public Object perform(Object[] args) throws Throwable
/* */ {
/* 373 */ Object value = MXBeanUtils.construct(this.attribute.getOpenType(), args[0], "Set attribute: " + this.attribute.getName());
/* */
/* 375 */ Attribute attr = new Attribute(this.attribute.getName(), value);
/* 376 */ MXBeanInvocationHandler.this.mbeanServerConnection.setAttribute(MXBeanInvocationHandler.this.objectName, attr);
/* 377 */ return null;
/* */ }
/* */ }
/* */
/* */ private class GetAction
/* */ implements MXBeanInvocationHandler.Action
/* */ {
/* */ private OpenMBeanAttributeInfo attribute;
/* */ private Type type;
/* */
/* */ public GetAction(OpenMBeanAttributeInfo attribute, Type type)
/* */ {
/* 350 */ this.attribute = attribute;
/* 351 */ this.type = type;
/* */ }
/* */
/* */ public Object perform(Object[] args) throws Throwable
/* */ {
/* 356 */ Object result = MXBeanInvocationHandler.this.mbeanServerConnection.getAttribute(MXBeanInvocationHandler.this.objectName, this.attribute.getName());
/* */
/* 358 */ return MXBeanUtils.reconstruct(this.attribute.getOpenType(), this.type, result, "Get attribute: " + this.attribute.getName());
/* */ }
/* */ }
/* */
/* */ private static abstract interface Action
/* */ {
/* */ public abstract Object perform(Object[] paramArrayOfObject)
/* */ throws Throwable;
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.mx.mxbean.MXBeanInvocationHandler
* JD-Core Version: 0.6.0
*/