1 29 30 package com.caucho.jmx; 31 32 import javax.management.Attribute ; 33 import javax.management.MBeanServer ; 34 import javax.management.NotificationEmitter ; 35 import javax.management.NotificationFilter ; 36 import javax.management.NotificationListener ; 37 import javax.management.ObjectName ; 38 import java.lang.reflect.Array ; 39 import java.lang.reflect.InvocationHandler ; 40 import java.lang.reflect.Method ; 41 import java.lang.reflect.Proxy ; 42 43 46 public class JmxInvocationHandler implements InvocationHandler { 47 private MBeanServer _server; 48 private ClassLoader _loader; 49 private ObjectName _name; 50 51 54 public JmxInvocationHandler(MBeanServer mbeanServer, 55 ClassLoader loader, 56 ObjectName objectName) 57 { 58 _server = mbeanServer; 59 _loader = loader; 60 _name = objectName; 61 } 62 63 66 public static Object newProxyInstance(MBeanServer server, 67 ClassLoader loader, 68 ObjectName objectName, 69 Class interfaceClass, 70 boolean notificationBroadcaster) 71 { 72 Class []interfaces; 73 74 if (notificationBroadcaster) 75 interfaces = new Class [] { interfaceClass, NotificationEmitter .class }; 76 else 77 interfaces = new Class [] { interfaceClass }; 78 79 JmxInvocationHandler handler; 80 81 handler = new JmxInvocationHandler(server, loader, objectName); 82 83 return Proxy.newProxyInstance(interfaceClass.getClassLoader(), 84 interfaces, 85 handler); 86 } 87 88 95 public Object invoke(Object proxy, Method method, Object []args) 96 throws Throwable 97 { 98 String methodName = method.getName(); 99 Class []params = method.getParameterTypes(); 100 101 if (methodName.equals("equals") && 103 params.length == 1 && params[0].equals(Object .class)) { 104 Object value = args[0]; 105 if (value == null || ! Proxy.isProxyClass(value.getClass())) 106 return Boolean.FALSE; 107 108 JmxInvocationHandler handler; 109 110 handler = (JmxInvocationHandler) Proxy.getInvocationHandler(value); 111 112 return new Boolean (_name.equals(handler._name)); 113 } 114 else if (methodName.equals("hashCode") && params.length == 0) 115 return new Integer (_name.hashCode()); 116 117 int len = methodName.length(); 118 String attrName; 119 120 Class returnType = method.getReturnType(); 121 122 if (params.length == 0 && methodName.startsWith("get") && len > 3) { 123 attrName = methodName.substring(3); 124 125 return marshall(_server.getAttribute(_name, attrName), returnType); 126 } 127 else if (params.length == 1 && returnType.equals(void.class) && 128 methodName.startsWith("set") && len > 3) { 129 attrName = methodName.substring(3); 130 131 Attribute attr = new Attribute (attrName, args[0]); 132 133 _server.setAttribute(_name, attr); 134 135 return null; 136 } 137 else if (methodName.equals("addNotificationListener")) { 138 if (args.length != 3) { 139 } 140 else if (args[0] instanceof NotificationListener ) { 141 _server.addNotificationListener(_name, 142 (NotificationListener ) args[0], 143 (NotificationFilter ) args[1], 144 args[2]); 145 return null; 146 } 147 else if (args[0] instanceof ObjectName ) { 148 _server.addNotificationListener(_name, 149 (ObjectName ) args[0], 150 (NotificationFilter ) args[1], 151 args[2]); 152 return null; 153 } 154 } 155 else if (methodName.equals("removeNotificationListener")) { 156 if (args.length == 3) { 157 if (args[0] instanceof NotificationListener ) { 158 _server.removeNotificationListener(_name, 159 (NotificationListener ) args[0], 160 (NotificationFilter ) args[1], 161 args[2]); 162 return null; 163 } 164 else if (args[0] instanceof ObjectName ) { 165 _server.removeNotificationListener(_name, 166 (ObjectName ) args[0], 167 (NotificationFilter ) args[1], 168 args[2]); 169 return null; 170 } 171 } 172 else if (args.length == 1) { 173 if (args[0] instanceof NotificationListener ) { 174 _server.removeNotificationListener(_name, 175 (NotificationListener ) args[0]); 176 return null; 177 } 178 else if (args[0] instanceof ObjectName ) { 179 _server.removeNotificationListener(_name, (ObjectName ) args[0]); 180 181 return null; 182 } 183 } 184 } 185 186 String []sig = new String [params.length]; 187 188 for (int i = 0; i < sig.length; i++) 189 sig[i] = params[i].getName(); 190 191 Object value = _server.invoke(_name, methodName, args, sig); 192 193 return marshall(value, returnType); 194 } 195 196 private Object marshall(Object value, Class retType) 197 { 198 if (retType == null || value == null || 199 retType.isAssignableFrom(value.getClass())) 200 return value; 201 202 if (value instanceof ObjectName ) { 203 ObjectName name = (ObjectName ) value; 204 205 Object proxy = Jmx.find(name, _loader, _server); 206 207 if (retType.isInstance(proxy)) 208 return proxy; 209 else 210 return value; 211 } 212 else if (value instanceof ObjectName [] && retType.isArray()) { 213 Class type = retType.getComponentType(); 214 ObjectName []names = (ObjectName []) value; 215 216 Object proxies = Array.newInstance(type, names.length); 217 218 for (int i = 0; i < names.length; i++) { 219 Object proxy = Jmx.find(names[i], _loader, _server); 220 221 if (proxy == null) { 222 Array.set(proxies, i, null); 223 continue; 224 } 225 226 if (! type.isInstance(proxy)) 227 return value; 228 229 Array.set(proxies, i, Jmx.find(names[i], _loader, _server)); 230 } 231 232 return proxies; 233 } 234 235 return value; 236 } 237 } 238 | Popular Tags |