1 22 package org.jboss.mx.util; 23 24 import java.io.Serializable ; 25 26 import java.lang.reflect.InvocationHandler ; 27 import java.lang.reflect.Method ; 28 import java.lang.reflect.Proxy ; 29 30 import java.util.HashMap ; 31 32 import javax.management.Attribute ; 33 import javax.management.AttributeList ; 34 import javax.management.AttributeNotFoundException ; 35 import javax.management.DynamicMBean ; 36 import javax.management.InstanceNotFoundException ; 37 import javax.management.IntrospectionException ; 38 import javax.management.InvalidAttributeValueException ; 39 import javax.management.MBeanAttributeInfo ; 40 import javax.management.MBeanException ; 41 import javax.management.MBeanInfo ; 42 import javax.management.MBeanOperationInfo ; 43 import javax.management.MBeanServer ; 44 import javax.management.ObjectName ; 45 import javax.management.ReflectionException ; 46 import javax.management.RuntimeErrorException ; 47 import javax.management.RuntimeMBeanException ; 48 import javax.management.RuntimeOperationsException ; 49 50 57 public class JMXInvocationHandler 58 implements ProxyContext, InvocationHandler , Serializable 59 { 60 private static final long serialVersionUID = 3714728148040623702L; 61 62 64 67 protected MBeanServer server = null; 68 69 72 protected ObjectName objectName = null; 73 74 77 private ProxyExceptionHandler handler = new DefaultExceptionHandler(); 78 79 82 private HashMap attributeMap = new HashMap (); 83 84 88 private boolean delegateToStringToResource = false; 89 90 94 private boolean delegateEqualsToResource = false; 95 96 100 private boolean delegateHashCodeToResource = false; 101 102 103 105 114 public JMXInvocationHandler(MBeanServer server, ObjectName name) 115 throws MBeanProxyCreationException 116 { 117 try 118 { 119 if (server == null) 120 throw new MBeanProxyCreationException("null agent reference"); 121 122 this.server = server; 123 this.objectName = name; 124 125 MBeanInfo info = server.getMBeanInfo(objectName); 126 MBeanAttributeInfo [] attributes = info.getAttributes(); 127 MBeanOperationInfo [] operations = info.getOperations(); 128 129 for (int i = 0; i < attributes.length; ++i) 131 attributeMap.put(attributes[i].getName(), attributes[i]); 132 133 for (int i = 0; i < operations.length; ++i) 137 { 138 if (operations[i].getName().equals("toString") && 139 operations[i].getReturnType().equals("java.lang.String") && 140 operations[i].getSignature().length == 0) 141 { 142 delegateToStringToResource = true; 143 } 144 145 else if (operations[i].getName().equals("equals") && 146 operations[i].getReturnType().equals(Boolean.TYPE.getName()) && 147 operations[i].getSignature().length == 1 && 148 operations[i].getSignature() [0].getType().equals("java.lang.Object")) 149 { 150 delegateEqualsToResource = true; 151 } 152 153 else if (operations[i].getName().equals("hashCode") && 154 operations[i].getReturnType().equals(Integer.TYPE.getName()) && 155 operations[i].getSignature().length == 0) 156 { 157 delegateHashCodeToResource = true; 158 } 159 } 160 } 161 catch (InstanceNotFoundException e) 162 { 163 throw new MBeanProxyCreationException("Object name " + name + " not found: " + e.toString()); 164 } 165 catch (IntrospectionException e) 166 { 167 throw new MBeanProxyCreationException(e.toString()); 168 } 169 catch (ReflectionException e) 170 { 171 throw new MBeanProxyCreationException(e.toString()); 172 } 173 } 174 175 176 178 public Object invoke(Object proxy, Method method, Object [] args) 179 throws Exception 180 { 181 Class declaringClass = method.getDeclaringClass(); 182 183 if (declaringClass == Object .class) 188 return handleObjectMethods(method, args); 189 190 if (declaringClass == ProxyContext.class) 193 return method.invoke(this, args); 194 195 if (declaringClass == DynamicMBean .class) 199 return handleDynamicMBeanInvocation(method, args); 200 201 try 202 { 203 String methodName = method.getName(); 204 205 211 if (methodName.startsWith("get") && args == null) 213 { 214 String attrName = methodName.substring(3, methodName.length()); 215 216 MBeanAttributeInfo info = (MBeanAttributeInfo )attributeMap.get(attrName); 218 if (info != null) 219 { 220 String retType = method.getReturnType().getName(); 221 222 if (retType.equals(info.getType())) 224 { 225 return server.getAttribute(objectName, attrName); 226 } 227 } 228 } 229 230 else if (methodName.startsWith("is") && args == null) 232 { 233 String attrName = methodName.substring(2, methodName.length()); 234 235 MBeanAttributeInfo info = (MBeanAttributeInfo )attributeMap.get(attrName); 237 if (info != null && info.isIs()) 238 { 239 Class retType = method.getReturnType(); 240 241 if (retType.equals(Boolean .class) || retType.equals(Boolean.TYPE)) 243 { 244 return server.getAttribute(objectName, attrName); 245 } 246 } 247 } 248 249 else if (methodName.startsWith("set") && args != null && args.length == 1) 251 { 252 String attrName = methodName.substring(3, methodName.length()); 253 254 MBeanAttributeInfo info = (MBeanAttributeInfo )attributeMap.get(attrName); 256 if (info != null && method.getReturnType().equals(Void.TYPE)) 257 { 258 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 259 260 Class signatureClass = null; 261 String classType = info.getType(); 262 263 if (isPrimitive(classType)) 264 signatureClass = getPrimitiveClass(classType); 265 else 266 signatureClass = cl.loadClass(info.getType()); 267 268 if (signatureClass.isAssignableFrom(args[0].getClass())) 269 { 270 server.setAttribute(objectName, new Attribute (attrName, args[0])); 271 return null; 272 } 273 } 274 } 275 276 String [] signature = null; 277 278 if (args != null) 279 { 280 signature = new String [args.length]; 281 Class [] sign = method.getParameterTypes(); 282 283 for (int i = 0; i < sign.length; ++i) 284 signature[i] = sign[i].getName(); 285 } 286 287 return server.invoke(objectName, methodName, args, signature); 288 } 289 catch (InstanceNotFoundException e) 290 { 291 return getExceptionHandler().handleInstanceNotFound(this, e, method, args); 292 } 293 catch (AttributeNotFoundException e) 294 { 295 return getExceptionHandler().handleAttributeNotFound(this, e, method, args); 296 } 297 catch (InvalidAttributeValueException e) 298 { 299 return getExceptionHandler().handleInvalidAttributeValue(this, e, method, args); 300 } 301 catch (MBeanException e) 302 { 303 return getExceptionHandler().handleMBeanException(this, e, method, args); 304 } 305 catch (ReflectionException e) 306 { 307 return getExceptionHandler().handleReflectionException(this, e, method, args); 308 } 309 catch (RuntimeOperationsException e) 310 { 311 return getExceptionHandler().handleRuntimeOperationsException(this, e, method, args); 312 } 313 catch (RuntimeMBeanException e) 314 { 315 return getExceptionHandler().handleRuntimeMBeanException(this, e, method, args); 316 } 317 catch (RuntimeErrorException e) 318 { 319 return getExceptionHandler().handleRuntimeError(this, e, method, args); 320 } 321 } 322 323 public ProxyExceptionHandler getExceptionHandler() 324 { 325 return handler; 326 } 327 328 329 331 336 public void setExceptionHandler(ProxyExceptionHandler handler) 337 { 338 this.handler = handler; 339 } 340 341 public MBeanServer getMBeanServer() 342 { 343 return server; 344 } 345 346 public ObjectName getObjectName() 347 { 348 return objectName; 349 } 350 351 352 354 public String toString() 355 { 356 return "MBeanProxy for " + objectName + " (Agent ID: " + AgentID.get(server) + ")"; 357 } 358 359 360 362 private Object handleObjectMethods(Method method, Object [] args) 363 throws InstanceNotFoundException , ReflectionException , 364 IntrospectionException , MBeanException 365 { 366 if (method.getName().equals("toString")) 367 { 368 if (delegateToStringToResource) 369 return server.invoke(objectName, "toString", null, null); 370 else 371 return toString(); 372 } 373 374 else if (method.getName().equals("equals")) 375 { 376 if (delegateEqualsToResource) 377 { 378 return server.invoke(objectName, "equals", 379 new Object [] { args[0] }, 380 new String [] { "java.lang.Object" } 381 ); 382 } 383 else if (Proxy.isProxyClass(args[0].getClass())) 384 { 385 Proxy prxy = (Proxy )args[0]; 386 return new Boolean (this.equals(Proxy.getInvocationHandler(prxy))); 387 } 388 else 389 { 390 return new Boolean (this.equals(args[0])); 391 } 392 } 393 394 else if (method.getName().equals("hashCode")) 395 { 396 if (delegateHashCodeToResource) 397 return server.invoke(objectName, "hashCode", null, null); 398 else 399 return new Integer (this.hashCode()); 400 } 401 402 else throw new Error ("Unexpected method invocation!"); 403 } 404 405 private Object handleDynamicMBeanInvocation(Method method, Object [] args) 406 throws InstanceNotFoundException , ReflectionException , 407 IntrospectionException , MBeanException , AttributeNotFoundException , 408 InvalidAttributeValueException 409 { 410 String methodName = method.getName(); 411 412 if (methodName.equals("setAttribute")) 413 { 414 server.setAttribute(objectName, (Attribute )args[0]); 415 return null; 416 } 417 else if (methodName.equals("setAttributes")) 418 return server.setAttributes(objectName, (AttributeList )args[0]); 419 else if (methodName.equals("getAttribute")) 420 return server.getAttribute(objectName, (String )args[0]); 421 else if (methodName.equals("getAttributes")) 422 return server.getAttributes(objectName, (String [])args[0]); 423 else if (methodName.equals("invoke")) 424 return server.invoke(objectName, (String )args[0], (Object [])args[1], (String [])args[2]); 425 else if (methodName.equals("getMBeanInfo")) 426 return server.getMBeanInfo(objectName); 427 428 else throw new Error ("Unexpected method invocation!"); 429 } 430 431 private boolean isPrimitive(String type) 432 { 433 if (type.equals(Integer.TYPE.getName())) return true; 434 if (type.equals(Long.TYPE.getName())) return true; 435 if (type.equals(Boolean.TYPE.getName())) return true; 436 if (type.equals(Byte.TYPE.getName())) return true; 437 if (type.equals(Character.TYPE.getName())) return true; 438 if (type.equals(Short.TYPE.getName())) return true; 439 if (type.equals(Float.TYPE.getName())) return true; 440 if (type.equals(Double.TYPE.getName())) return true; 441 if (type.equals(Void.TYPE.getName())) return true; 442 443 return false; 444 } 445 446 private Class getPrimitiveClass(String type) 447 { 448 if (type.equals(Integer.TYPE.getName())) return Integer.TYPE; 449 if (type.equals(Long.TYPE.getName())) return Long.TYPE; 450 if (type.equals(Boolean.TYPE.getName())) return Boolean.TYPE; 451 if (type.equals(Byte.TYPE.getName())) return Byte.TYPE; 452 if (type.equals(Character.TYPE.getName()))return Character.TYPE; 453 if (type.equals(Short.TYPE.getName())) return Short.TYPE; 454 if (type.equals(Float.TYPE.getName())) return Float.TYPE; 455 if (type.equals(Double.TYPE.getName())) return Double.TYPE; 456 if (type.equals(Void.TYPE.getName())) return Void.TYPE; 457 458 return null; 459 } 460 461 } 462 463 464 465 | Popular Tags |