1 9 package org.jboss.mx.remoting; 10 11 import java.io.IOException ; 12 import java.io.Serializable ; 13 import java.lang.reflect.InvocationHandler ; 14 import java.lang.reflect.Method ; 15 import java.lang.reflect.Proxy ; 16 import java.util.HashMap ; 17 import java.util.Map ; 18 import java.util.WeakHashMap ; 19 import javax.management.Attribute ; 20 import javax.management.InstanceNotFoundException ; 21 import javax.management.MBeanException ; 22 import javax.management.ReflectionException ; 23 import org.jboss.remoting.loading.ClassUtil; 24 25 56 public class MoveableMBean implements InvocationHandler , Serializable 57 { 58 static final long serialVersionUID = -7506487379354274551L; 59 60 private transient static Map methodArgs = new WeakHashMap (); 61 62 private static transient Method hashCodeMethod; 64 private static transient Method equalsMethod; 65 private static transient Method toStringMethod; 66 private static transient Method notifyAllMethod; 67 private static transient Method notifyMethod; 68 private static transient Method wait0Method; 69 private static transient Method wait1Method; 70 private static transient Method wait2Method; 71 72 protected MBeanLocator locator; 73 protected Integer hashCode; 74 protected Map staticAttributes; 75 76 static 77 { 78 try 79 { 80 hashCodeMethod = Object .class.getMethod("hashCode", null); 82 equalsMethod = Object .class.getMethod("equals", new Class []{Object .class}); 83 toStringMethod = Object .class.getMethod("toString", null); 84 notifyMethod = Object .class.getMethod("notify", null); 85 notifyAllMethod = Object .class.getMethod("notifyAll", null); 86 notifyMethod = Object .class.getMethod("notify", null); 87 wait0Method = Object .class.getMethod("wait", null); 88 wait1Method = Object .class.getMethod("wait", new Class []{Long.TYPE}); 89 wait2Method = Object .class.getMethod("wait", new Class []{Long.TYPE, Integer.TYPE}); 90 } 91 catch(NoSuchMethodException e) 92 { 93 throw new InternalError (e.getMessage()); 94 } 95 } 96 97 98 protected MoveableMBean(MBeanLocator locator, Map staticAttributes) 99 { 100 this.locator = locator; 101 this.staticAttributes = staticAttributes; 102 this.hashCode = new Integer (System.identityHashCode(locator)); 103 } 104 105 110 public final MBeanLocator getMBeanLocator() 111 { 112 return locator; 113 } 114 115 public static Object create(MBeanLocator locator, ClassLoader loader, Class interfaceClass) 116 { 117 Class classes[] = ClassUtil.getInterfacesFor(interfaceClass); 118 return create(locator, loader, classes, null); 119 } 120 121 public static Object create(MBeanLocator locator, ClassLoader loader, Class interfaceClass, Map staticAttributes) 122 { 123 Class classes[] = ClassUtil.getInterfacesFor(interfaceClass); 124 return create(locator, loader, classes, staticAttributes); 125 } 126 127 public static Object create(MBeanLocator locater, Class interfaceClass) 128 { 129 Class classes[] = ClassUtil.getInterfacesFor(interfaceClass); 130 return create(locater, classes); 131 } 132 133 public static Object create(MBeanLocator locator, Class interfaces[]) 134 { 135 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 136 if(loader == null) 137 { 138 loader = interfaces[0].getClassLoader(); 139 } 140 return create(locator, loader, interfaces, null); 141 } 142 143 public static Object create(MBeanLocator locator, ClassLoader loader, Class interfaces[], Map staticAttributes) 144 { 145 Class _inf[] = interfaces; 146 boolean found = false; 147 for(int c = 0; c < interfaces.length; c++) 148 { 149 if(interfaces[c] == LocationAware.class) 150 { 151 found = true; 152 break; 153 } 154 } 155 if(found == false) 156 { 157 _inf = new Class [interfaces.length + 1]; 158 System.arraycopy(interfaces, 0, _inf, 0, interfaces.length); 159 _inf[interfaces.length] = LocationAware.class; 161 } 162 return Proxy.newProxyInstance(loader, _inf, new MoveableMBean(locator, staticAttributes)); 163 } 164 165 171 public void addStaticAttributes(Map values) 172 { 173 if(staticAttributes == null) 174 { 175 staticAttributes = values; 176 } 177 else 178 { 179 staticAttributes.putAll(values); 180 } 181 } 182 183 189 public void addStaticAttribute(String name, Object value) 190 { 191 if(staticAttributes == null) 192 { 193 staticAttributes = new HashMap (1); 194 } 195 staticAttributes.put(name, value); 196 } 197 198 protected Object handleLocationMethods(Object proxy, Method method, Object [] args) 199 throws Throwable 200 { 201 return locator; 202 } 203 204 249 public Object invoke(Object proxy, Method method, Object [] args) 250 throws Throwable 251 { 252 if(method.getDeclaringClass() == Object .class) 253 { 254 return handleObjectMethods(proxy, method, args); 255 } 256 if(method.getDeclaringClass() == LocationAware.class) 257 { 258 return handleLocationMethods(proxy, method, args); 259 } 260 try 261 { 262 String name = method.getName(); 263 if(name.startsWith("get") && name.length() > 3 && (args == null || args.length <= 0)) 264 { 265 String attributeName = method.getName().substring(3); 268 if(staticAttributes != null) 269 { 270 if(staticAttributes.containsKey(attributeName)) 274 { 275 return staticAttributes.get(attributeName); 276 } 277 } 278 return locator.getMBeanServer().getAttribute(locator.getObjectName(), attributeName); 279 } 280 else if(name.startsWith("set") && name.length() > 3) 281 { 282 String attributeName = method.getName().substring(3); 284 285 locator.getMBeanServer().setAttribute(locator.getObjectName(), new Attribute (attributeName, (args == null ? null : args[0]))); 287 288 if(staticAttributes != null) 290 { 291 if(staticAttributes.containsKey(attributeName)) 295 { 296 return staticAttributes.put(attributeName, (args == null ? null : args[0])); 297 } 298 } 299 return null; 300 } 301 else 302 { 303 return locator.getMBeanServer().invoke(locator.getObjectName(), method.getName(), args, makeArgSignature(method, args)); 304 } 305 } 306 catch(InstanceNotFoundException inf) 307 { 308 throw inf; 309 } 310 catch(MBeanException mbe) 311 { 312 throw mbe.getTargetException(); 313 } 314 catch(ReflectionException re) 315 { 316 throw re.getTargetException(); 317 } 318 } 319 320 protected Boolean proxyEquals(Object proxy, Object other) 321 { 322 return (proxy == other ? Boolean.TRUE : Boolean.FALSE); 323 } 324 325 protected String proxyToString(Object proxy) 326 { 327 return (locator == null ? ("MoveableMBean [Proxy" + "@" + proxy.hashCode() + "]") : locator.toString()); 328 } 329 330 protected Integer proxyHashCode(Object proxy) 331 { 332 return hashCode; 333 } 334 335 protected Object handleObjectMethods(Object proxy, Method method, Object args[]) 336 throws Exception 337 { 338 if(method.equals(hashCodeMethod)) 339 { 340 return proxyHashCode(proxy); 341 } 342 else if(method.equals(equalsMethod)) 343 { 344 return proxyEquals(proxy, args[0]); 345 } 346 else if(method.equals(toStringMethod)) 347 { 348 return proxyToString(proxy); 349 } 350 else if(method.equals(notifyAllMethod)) 351 { 352 notifyAll(); 353 return null; 354 } 355 else if(method.equals(notifyMethod)) 356 { 357 notify(); 358 return null; 359 } 360 else if(method.equals(wait0Method)) 361 { 362 wait(); 363 return null; 364 } 365 else if(method.equals(wait1Method)) 366 { 367 wait(((Long ) args[0]).longValue()); 368 return null; 369 } 370 else if(method.equals(wait2Method)) 371 { 372 wait(((Long ) args[0]).longValue(), ((Integer ) args[1]).intValue()); 373 return null; 374 } 375 376 else 377 { 378 throw new InternalError ("unexpected Object method dispatched: " + method); 379 } 380 } 381 382 389 protected synchronized String [] makeArgSignature(Method method, Object args[]) 390 { 391 if(methodArgs.containsKey(method)) 392 { 393 return (String []) methodArgs.get(method); 394 } 395 Class pt[] = method.getParameterTypes(); 396 if(pt == null || pt.length <= 0) 397 { 398 return null; 399 } 400 String sig[] = new String [args.length]; 401 for(int c = 0; c < pt.length; c++) 402 { 403 sig[c] = pt[c].getName(); 404 } 405 methodArgs.put(method, sig); 406 return sig; 407 } 408 409 417 protected Class resolveProxyClass(String [] interfaces) 418 throws IOException , ClassNotFoundException 419 { 420 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 421 if(cl == null) 422 { 423 cl = MoveableMBean.class.getClassLoader(); 424 } 425 Class inf[] = new Class [interfaces.length]; 426 for(int c = 0; c < interfaces.length; c++) 427 { 428 inf[c] = cl.loadClass(interfaces[c]); 429 } 430 return java.lang.reflect.Proxy.getProxyClass(cl, inf); 431 } 432 433 } 434 | Popular Tags |