1 23 package com.sun.appserv.management.client.handler; 24 25 import java.io.IOException ; 26 import java.util.Map ; 27 import java.util.HashMap ; 28 import java.util.Set ; 29 import java.util.HashSet ; 30 import java.util.List ; 31 import java.util.ArrayList ; 32 import java.util.Iterator ; 33 import java.util.Collections ; 34 import java.util.logging.Logger ; 35 36 import javax.management.Attribute ; 37 import javax.management.AttributeList ; 38 import javax.management.MBeanInfo ; 39 import javax.management.MBeanAttributeInfo ; 40 import javax.management.MBeanServerConnection ; 41 import javax.management.NotificationListener ; 42 import javax.management.NotificationFilter ; 43 import javax.management.ListenerNotFoundException ; 44 import javax.management.ObjectName ; 45 import javax.management.NotificationBroadcaster ; 46 import javax.management.ReflectionException ; 47 import javax.management.IntrospectionException ; 48 import javax.management.JMException ; 49 import javax.management.InstanceNotFoundException ; 50 import javax.management.AttributeNotFoundException ; 51 import javax.management.ListenerNotFoundException ; 52 import javax.management.MBeanException ; 53 54 import java.lang.reflect.Proxy ; 55 import java.lang.reflect.Method ; 56 57 import com.sun.appserv.management.base.AMX; 58 import com.sun.appserv.management.base.AMXDebug; 59 import com.sun.appserv.management.base.AMXAttributes; 60 import com.sun.appserv.management.base.Extra; 61 import com.sun.appserv.management.base.AMXClientLogger; 62 import com.sun.appserv.management.base.Util; 63 import com.sun.appserv.management.client.ConnectionSource; 64 import com.sun.appserv.management.util.jmx.MBeanProxyHandler; 65 import com.sun.appserv.management.util.jmx.JMXUtil; 66 import com.sun.appserv.management.util.misc.ClassUtil; 67 import com.sun.appserv.management.util.misc.GSetUtil; 68 import com.sun.appserv.management.util.misc.TypeCast; 69 import com.sun.appserv.management.util.misc.StringUtil; 70 import com.sun.appserv.management.util.stringifier.SmartStringifier; 71 import com.sun.appserv.management.util.stringifier.ArrayStringifier; 72 import com.sun.appserv.management.DomainRoot; 73 import com.sun.appserv.management.base.Container; 74 import com.sun.appserv.management.client.ProxyFactory; 75 76 79 class AMXProxyHandler extends MBeanProxyHandler 80 implements Extra 81 { 82 protected final PerMBeanCache mCache; 83 private boolean mCheckedForInvariantMBeanInfo = false; 84 85 static protected final String DEBUG_ID = 86 "com.sun.appserv.management.util.jmx.AMXProxyHandler"; 87 88 89 protected String 90 getDebugID() 91 { 92 return DEBUG_ID; 93 } 94 95 101 protected 102 AMXProxyHandler( 103 final ConnectionSource connectionSource, 104 final ObjectName proxiedMBeanObjectName ) 105 throws IOException 106 { 107 super( connectionSource, proxiedMBeanObjectName ); 108 109 mDebug = AMXDebug.getInstance().getOutput( getDebugID() ); 110 111 mCache = new PerMBeanCache(); 112 113 setProxyLogger( AMXClientLogger.getInstance() ); 114 } 115 116 protected void 117 cacheAttribute( final Attribute attr ) 118 { 119 mCache.cacheAttribute( attr ); 120 } 121 122 126 protected Attribute 127 getCachedAttribute( final String attrName ) 128 throws IOException , InstanceNotFoundException , 129 MBeanException , AttributeNotFoundException , ReflectionException 130 { 131 Attribute attr = mCache.getCachedAttribute( attrName ); 132 133 if ( attr == null ) 134 { 135 final MBeanServerConnection conn = getConnection(); 136 137 final Object value = getConnection().getAttribute( getTargetObjectName(), attrName ); 138 attr = new Attribute ( attrName, value ); 139 mCache.cacheAttribute( attr ); 140 } 141 142 return( attr ); 143 } 144 145 protected Object 146 getCachedAttributeValue( final String attrName ) 147 throws IOException , JMException 148 { 149 final Attribute attr = getCachedAttribute( attrName ); 150 151 assert( attr != null ) : "getCachedAttributeValue: null for " + attrName; 152 return( attr == null ? null : attr.getValue() ); 153 } 154 155 161 private AMX 162 getCachedProxy( Object key ) 163 { 164 AMX proxy = null; 165 166 if ( key instanceof ObjectName ) 167 { 168 proxy = getProxyFactory().getProxy( (ObjectName )key, AMX.class ); 169 } 170 else 171 { 172 proxy = Util.asAMX(mCache.getCachedItem( key ) ); 173 } 174 175 if ( proxy != null ) 176 { 177 final AMXProxyHandler handler = (AMXProxyHandler)Proxy.getInvocationHandler( proxy ); 178 if ( ! handler.targetIsValid() ) 179 { 180 debug( "removing cached proxy for key: ", key ); 181 mCache.remove( key ); 182 proxy = null; 183 } 184 } 185 186 return( proxy ); 187 } 188 189 194 private void 195 cacheProxy( final String key, final AMX proxy) 196 { 197 mCache.cacheItem( key, proxy ); 198 } 199 200 201 private static final String CREATE = "create"; 202 private static final String GET = "get"; 203 204 private static final String MAP_SUFFIX = "Map"; 205 private static final String SET_SUFFIX = "Set"; 206 private static final String LIST_SUFFIX = "List"; 207 private static final String OBJECT_NAME_MAP_SUFFIX= "ObjectName" + MAP_SUFFIX; 208 private static final String OBJECT_NAME_SET_SUFFIX= "ObjectName" + SET_SUFFIX; 209 private static final String OBJECT_NAME_LIST_SUFFIX= "ObjectName" + LIST_SUFFIX; 210 211 private static final String OBJECT_NAME_SUFFIX = "ObjectName"; 212 213 private static final String CONTAINEE_J2EE_TYPES = Container.ATTR_CONTAINEE_J2EE_TYPES; 214 215 216 private static final String CONTAINER = "Container"; 217 private static final String DOMAIN_ROOT = "DomainRoot"; 218 private static final String MBEAN_INFO = "MBeanInfo"; 219 private static final String ATTRIBUTE_NAMES = "AttributeNames"; 220 private static final String J2EE_NAME = "Name"; 221 private static final String J2EE_TYPE = "J2EEType"; 222 223 public final static String ADD_NOTIFICATION_LISTENER = "addNotificationListener"; 224 public final static String REMOVE_NOTIFICATION_LISTENER = "removeNotificationListener"; 225 226 private final static String QUERY = "query"; 227 228 protected ObjectName 229 getContainerObjectName() 230 throws IOException , JMException 231 { 232 return( (ObjectName )getCachedAttributeValue( AMXAttributes.ATTR_CONTAINER_OBJECT_NAME ) ); 233 } 234 235 236 protected Class 237 getProxyInterface( final ObjectName objectName ) 238 throws IOException , JMException , ClassNotFoundException 239 { 240 final AMX proxy = getProxyFactory().getProxy( objectName, AMX.class ); 243 244 final Class proxyInterface = ClassUtil.getClassFromName( Util.getExtra( proxy ).getInterfaceName() ); 245 246 return( proxyInterface ); 247 } 248 249 private String 250 _getInterfaceName() 251 throws IOException , JMException 252 { 253 return( (String )getCachedAttributeValue( AMXAttributes.ATTR_INTERFACE_NAME ) ); 254 } 255 256 public String 257 getInterfaceName() 258 { 259 try 260 { 261 return( _getInterfaceName() ); 262 } 263 catch( Exception e ) 264 { 265 throw new RuntimeException ( e ); 266 } 267 } 268 269 public ProxyFactory 270 getProxyFactory() 271 { 272 return( ProxyFactory.getInstance( getConnectionSource() ) ); 273 } 274 275 278 synchronized Container 279 getContainer( final AMX myProxy ) 280 throws IOException , JMException , 281 ClassNotFoundException 282 { 283 Container containerProxy = null; 284 285 if ( ! ( myProxy instanceof DomainRoot ) ) 286 { 287 containerProxy = getProxyFactory().getProxy( getContainerObjectName(), Container.class ); 288 } 289 290 return( containerProxy ); 291 } 292 293 297 private final DomainRoot 298 getDomainRoot( ) 299 throws IOException 300 { 301 return( getProxyFactory().getDomainRoot( ) ); 302 } 303 304 private static final String STRING = String .class.getName(); 305 306 private static final String [] EMPTY_SIG = new String [ 0 ]; 307 private static final String [] STRING_SIG = new String [] { STRING } ; 308 private static final String [] STRING2_SIG = new String [] { STRING, STRING } ; 309 310 private static final String GET_SINGLETON_CONTAINEE = "getSingletonContainee"; 311 private static final String GET_CONTAINEE = "getContainee"; 312 private static final String GET_SINGLETON_CONTAINEE_OBJECT_NAME= 313 GET_SINGLETON_CONTAINEE + OBJECT_NAME_SUFFIX; 314 private static final String [] GET_SINGLETON_CONTAINEE_OBJECT_NAME_SIG1 = STRING_SIG; 315 private static final String [] GET_SINGLETON_CONTAINEE_OBJECT_NAME_SIG2 = STRING2_SIG; 316 317 private static final String [] GET_OBJECT_NAMES_SIG_EMPTY = EMPTY_SIG; 318 private static final String [] GET_OBJECT_NAMES_SIG_STRING = STRING_SIG; 319 320 321 protected synchronized AMX 322 createProxy( 323 final ObjectName objectName ) 324 { 325 return( getProxyFactory().getProxy( objectName, AMX.class ) ); 326 } 327 328 331 protected static boolean 332 isProxyMapGetter( 333 final Method method, 334 final int argCount ) 335 { 336 boolean isProxyMapGetter = false; 337 338 final String name = method.getName(); 339 if ( name.startsWith( GET ) && 340 name.endsWith( MAP_SUFFIX ) && 341 (! name.endsWith( OBJECT_NAME_MAP_SUFFIX )) && 342 argCount <= 1 && 343 Map .class.isAssignableFrom( method.getReturnType() ) ) 344 { 345 isProxyMapGetter = true; 346 } 347 348 return( isProxyMapGetter ); 349 } 350 351 354 protected static boolean 355 isProxyListGetter( 356 final Method method, 357 final int argCount ) 358 { 359 boolean isProxyListGetter = false; 360 361 final String name = method.getName(); 362 if ( ( name.startsWith( GET ) || name.startsWith( QUERY ) ) && 363 name.endsWith( LIST_SUFFIX ) && 364 (! name.endsWith( OBJECT_NAME_LIST_SUFFIX )) && 365 argCount <= 1 && 366 List .class.isAssignableFrom( method.getReturnType() ) ) 367 { 368 isProxyListGetter = true; 369 } 370 371 return( isProxyListGetter ); 372 } 373 374 378 protected static boolean 379 isSingleProxyGetter( final Method method, final int argCount ) 380 { 381 boolean isProxyGetter = false; 382 383 final String name = method.getName(); 384 if ( ( name.startsWith( GET ) || name.startsWith( QUERY ) ) && 385 argCount <= 2 && 386 AMX.class.isAssignableFrom( method.getReturnType() ) ) 387 { 388 isProxyGetter = true; 389 } 390 391 return( isProxyGetter ); 392 } 393 394 397 protected static boolean 398 isProxySetGetter( final Method method, final int argCount ) 399 { 400 boolean isProxySetGetter = false; 401 402 final String name = method.getName(); 403 if ( ( name.startsWith( GET ) || name.startsWith( QUERY ) ) && 404 name.endsWith( SET_SUFFIX ) && 405 !name.endsWith( OBJECT_NAME_SET_SUFFIX ) && 406 argCount <= 2 && 407 Set .class.isAssignableFrom( method.getReturnType() ) ) 408 { 409 isProxySetGetter = true; 410 } 411 412 return( isProxySetGetter ); 413 } 414 415 416 private static String 417 proxyGetterToObjectNameGetter( final String methodName ) 418 { 419 return( methodName + OBJECT_NAME_SUFFIX ); 420 } 421 422 private Object 423 invokeTarget( 424 final String methodName, 425 final Object [] args, 426 final String [] sig ) 427 throws IOException , ReflectionException , InstanceNotFoundException , MBeanException , 428 AttributeNotFoundException 429 { 430 final int numArgs = args == null ? 0 : args.length; 431 432 Object result = null; 433 434 if ( numArgs == 0 && 435 methodName.startsWith( GET ) ) 436 { 437 final String attributeName = StringUtil.stripPrefix( methodName, GET ); 438 result = getConnection().getAttribute( getTargetObjectName(), attributeName ); 439 } 440 else 441 { 442 result = getConnection().invoke( getTargetObjectName(), methodName, args, sig ); 443 } 444 445 return result; 446 } 447 448 private String 449 getJ2EEType( final Class c ) 450 { 451 return( (String )ClassUtil.getFieldValue( c, "J2EE_TYPE" ) ); 452 } 453 454 459 AMX 460 invokeSingleProxyGetter( 461 final Object myProxy, 462 final Method method, 463 final Object [] args ) 464 throws IOException , ReflectionException , InstanceNotFoundException , MBeanException , 465 AttributeNotFoundException 466 { 467 final String methodName = method.getName(); 469 final int numArgs = (args == null) ? 0 : args.length; 470 471 final String argString = args == null ? "" : ArrayStringifier.stringify( args, "_" ); 472 final String cacheKey = methodName + argString; 473 474 AMX proxy = getCachedProxy( cacheKey ); 475 476 if ( proxy == null ) 477 { 478 final Class returnClass = method.getReturnType(); 479 ObjectName objectName = null; 480 final String j2eeType = getJ2EEType( returnClass ); 481 482 if ( numArgs == 0 ) { 484 final String newMethodName = proxyGetterToObjectNameGetter( methodName ); 485 objectName = (ObjectName ) invokeTarget( newMethodName, null, EMPTY_SIG); 486 } 487 else if ( numArgs == 1 && args[ 0 ].getClass() == String .class ) 488 { 489 final String newMethodName = proxyGetterToObjectNameGetter( methodName ); 490 objectName = (ObjectName ) invokeTarget( newMethodName, args, STRING_SIG ); 491 } 492 else if ( (methodName.equals( GET_SINGLETON_CONTAINEE ) || 493 methodName.equals( GET_CONTAINEE )) && numArgs == 2 ) 494 { 495 final String newMethodName = proxyGetterToObjectNameGetter( methodName ); 497 498 objectName = (ObjectName ) 499 invokeTarget( newMethodName, args, GET_SINGLETON_CONTAINEE_OBJECT_NAME_SIG2 ); 500 } 501 else 502 { 503 getProxyLogger().warning( "Unknown form of proxy getter: " + method ); 504 assert( false ); 505 throw new IllegalArgumentException (); 506 } 507 508 if ( objectName != null ) 509 { 510 proxy = createProxy( objectName ); 511 } 512 513 if ( proxy != null ) 515 { 516 if ( cacheKey != null ) 517 { 518 cacheProxy( cacheKey, proxy ); 520 } 521 else 522 { 523 } 525 } 526 else 527 { 528 getProxyLogger().fine( "invokeSingleProxyGetter: NULL ObjectName for: " + 529 methodName + "()" ); 530 } 531 } 532 else 533 { 534 } 536 537 return( proxy ); 538 } 539 540 541 protected static boolean 542 isProxyCreator( final Method method ) 543 { 544 final String methodName = method.getName(); 545 546 return( methodName.startsWith( CREATE ) && 547 AMX.class.isAssignableFrom( method.getReturnType() ) ); 548 } 549 550 552 AMX 553 invokeProxyCreator( 554 final Method method, 555 final Object [] args ) 556 throws IOException , ReflectionException , InstanceNotFoundException , MBeanException , 557 AttributeNotFoundException 558 { 559 final String methodName = method.getName(); 560 561 final String [] stringSig = getStringSig( method ); 562 final ObjectName objectName = (ObjectName )invokeTarget( methodName, args, stringSig ); 563 assert( objectName != null ) : 564 "received null ObjectName from: " + methodName + " on target " + getTargetObjectName(); 565 566 final AMX proxy = createProxy( objectName ); 567 assert( getProxyFactory().getProxy( Util.getExtra( proxy ).getObjectName(),AMX.class, false ) == proxy ); 568 569 return( proxy ); 570 } 571 572 573 574 575 private static String 576 toString( Object o ) 577 { 578 String result = o == null ? "null" : SmartStringifier.toString( o ); 579 580 final int MAX_LENGTH = 256; 581 if ( result.length() > MAX_LENGTH ) 582 { 583 result = result.substring( 0, MAX_LENGTH - 1 ) + "..."; 584 } 585 586 return result; 587 } 588 589 private static String [] 590 getStringSig( final Method method ) 591 { 592 final Class [] sig = method.getParameterTypes(); 593 final String [] stringSig = ClassUtil.classnamesFromSignature( sig ); 594 return( stringSig ); 595 } 596 597 598 protected static String 599 convertMethodName( 600 final String srcName, 601 final String srcSuffix, 602 final String resultSuffix ) 603 { 604 if ( ! srcName.endsWith( srcSuffix ) ) 605 { 606 throw new IllegalArgumentException ( srcName + " does not end with " + srcSuffix ); 607 } 608 final String baseName = srcName.substring( 0, srcName.lastIndexOf( srcSuffix ) ); 609 610 return( baseName + resultSuffix ); 611 } 612 613 private static final Map <String ,AMX> EMPTY_String_AMX = Collections.emptyMap(); 614 615 private Map <String ,?> 616 invokeProxyMapGetter( 617 final Object myProxy, 618 final Method method, 619 final Object [] args ) 620 throws java.io.IOException , ReflectionException , InstanceNotFoundException , MBeanException , 621 ClassNotFoundException , AttributeNotFoundException , JMException 622 { 623 final int argCount = args == null ? 0 : args.length; 624 625 final String methodName = method.getName(); 627 final String getObjectNameMapName = 628 convertMethodName( methodName, MAP_SUFFIX, OBJECT_NAME_MAP_SUFFIX ); 629 630 final MBeanServerConnection conn = getConnection(); 631 632 final Map <String ,?> m = TypeCast.asMap( 633 invokeTarget( getObjectNameMapName, args, getStringSig( method ) ) ); 634 assert( m != null ) : 635 "mbean " + getTargetObjectName() + " returned null Map for " + getObjectNameMapName; 636 637 642 Map <String ,?> result = null; 643 if ( m.keySet().size() != 0 ) 644 { 645 final ProxyFactory proxyFactory = getProxyFactory(); 646 647 final Object firstValue = m.values().iterator().next(); 648 649 if ( firstValue instanceof ObjectName ) 650 { 651 final Map <String ,ObjectName > onm = TypeCast.asMap( m ); 653 final Map <String ,AMX> proxyMap = proxyFactory.toProxyMap( onm ); 654 result = proxyMap; 655 } 656 else if ( firstValue instanceof Map ) 657 { 658 final Map <String ,Map <String ,ObjectName >> objectNameMaps = TypeCast.asMap( m ); 659 final Map <String ,Map <String ,AMX>> proxyMaps = new HashMap <String ,Map <String ,AMX>>(); 660 661 for ( final String j2eeType : objectNameMaps.keySet() ) 662 { 663 final Map <String ,ObjectName > objectNameMap = objectNameMaps.get( j2eeType ); 664 final Map <String ,AMX> proxyMap = proxyFactory.toProxyMap( objectNameMap ); 665 proxyMaps.put( j2eeType, proxyMap ); 666 } 667 668 result = proxyMaps; 669 } 670 else 671 { 672 throw new IllegalArgumentException (); 673 } 674 } 675 else 676 { 677 result = EMPTY_String_AMX; 678 } 679 680 return( result ); 681 } 682 683 private List <AMX> 684 invokeProxyListGetter( 685 final Object myProxy, 686 final Method method, 687 final Object [] args ) 688 throws java.io.IOException , ReflectionException , InstanceNotFoundException , MBeanException , 689 ClassNotFoundException , AttributeNotFoundException , JMException 690 { 691 final String remoteNAME = 693 convertMethodName( method.getName(), LIST_SUFFIX, OBJECT_NAME_LIST_SUFFIX ); 694 final List <ObjectName > objectNames = TypeCast.asList( 695 invokeTarget( remoteNAME, args, getStringSig( method ) ) ); 696 697 final List <AMX> result = getProxyFactory().toProxyList( objectNames ); 698 699 return( result ); 700 } 701 702 707 private Set <AMX> 708 invokeProxySetGetter( 709 final Object myProxy, 710 final Method method, 711 final Object [] args ) 712 throws java.io.IOException , JMException , ClassNotFoundException 713 { 714 assert( Set .class.isAssignableFrom( method.getReturnType() ) ); 715 716 final String methodName = method.getName(); 717 718 final String getObjectNamesName = 719 convertMethodName( methodName, SET_SUFFIX, OBJECT_NAME_SET_SUFFIX ); 720 721 final MBeanServerConnection conn = getConnection(); 722 723 final String [] stringSig = getStringSig( method ); 724 final Set <ObjectName > objectNames = TypeCast.asSet( invokeTarget( getObjectNamesName, args, stringSig ) ); 726 727 final Set <AMX> proxies = getProxyFactory().toProxySet( objectNames ); 728 729 return( proxies ); 730 } 731 732 733 private final static Class [] NOTIFICATION_LISTENER_SIG1 = new Class [] 734 { 735 NotificationListener .class 736 }; 737 private final static Class [] NOTIFICATION_LISTENER_SIG2 = new Class [] 738 { 739 NotificationListener .class, 740 NotificationFilter .class, 741 Object .class 742 }; 743 744 745 746 private MBeanInfo 747 _getMBeanInfo() 748 throws IOException , 749 InstanceNotFoundException , ReflectionException , IntrospectionException 750 { 751 MBeanInfo mbeanInfo = null; 752 753 if ( ! mCheckedForInvariantMBeanInfo ) 754 { 755 mCheckedForInvariantMBeanInfo = true; 756 757 try 759 { 760 final Boolean cacheIt = (Boolean ) 761 getAttribute( AMXAttributes.ATTR_MBEAN_INFO_IS_INVARIANT ); 762 setMBeanInfoIsInvariant( cacheIt.booleanValue() ); 763 cacheMBeanInfo( cacheIt.booleanValue() ); 764 765 } 766 catch( Exception e ) 767 { 768 cacheMBeanInfo( false ); 770 setMBeanInfoIsInvariant( false ); 771 } 772 } 773 774 mbeanInfo = getMBeanInfo( getCacheMBeanInfo() ); 775 776 return( mbeanInfo ); 777 } 778 779 780 public MBeanInfo 781 getMBeanInfo() 782 { 783 try 784 { 785 return( _getMBeanInfo() ); 786 } 787 catch( Exception e ) 788 { 789 throw new RuntimeException ( e ); 790 } 791 } 792 793 public ObjectName 794 getObjectName() 795 { 796 return( getTargetObjectName() ); 797 } 798 799 public Map <String ,Object > 800 getAllAttributes( ) 801 { 802 Map <String ,Object > result = Collections.emptyMap(); 803 804 try 805 { 806 final String [] names = getAttributeNames(); 807 808 final AttributeList attrs = getAttributes(names ); 809 810 result = JMXUtil.attributeListToValueMap( attrs ); 811 } 812 catch( Exception e ) 813 { 814 throw new RuntimeException ( e ); 815 } 816 return( result ); 817 } 818 819 public String [] 820 getAttributeNames() 821 { 822 final String attrName = "AttributeNames"; 823 824 Attribute attr = null; 825 try 826 { 827 attr = getCachedAttribute( attrName ); 828 } 829 catch( AttributeNotFoundException e ) 830 { 831 attr = null; 833 } 834 catch( Exception e ) 835 { 836 throw new RuntimeException ( e ); 837 } 838 839 String [] names = null; 840 if ( attr == null ) 841 { 842 final MBeanInfo mbeanInfo = getMBeanInfo(); 843 844 names = JMXUtil.getAttributeNames( mbeanInfo.getAttributes() ); 845 if ( getMBeanInfoIsInvariant() ) 846 { 847 cacheAttribute( new Attribute ( attrName, names ) ); 849 } 850 } 851 else 852 { 853 names = (String [])attr.getValue(); 854 } 855 856 return( names ); 857 } 858 859 863 private static final Set <String > CACHED_ATTRIBUTE_NAMES = GSetUtil.newUnmodifiableStringSet( 864 AMXAttributes.ATTR_MBEAN_INFO_IS_INVARIANT, 865 AMXAttributes.ATTR_INTERFACE_NAME, 866 AMXAttributes.ATTR_GROUP, 867 AMXAttributes.ATTR_FULL_TYPE, 868 CONTAINEE_J2EE_TYPES ); 869 870 private static final String GET_MBEAN_INFO = GET + MBEAN_INFO; 871 private static final String GET_J2EE_TYPE = GET + J2EE_TYPE; 872 private static final String GET_J2EE_NAME = GET + J2EE_NAME; 873 private static final String GET_ATTRIBUTE_NAMES = GET + ATTRIBUTE_NAMES; 874 private static final String GET_CONTAINER = GET + CONTAINER; 875 private static final String GET_EXTRA = GET + "Extra"; 876 private static final String GET_ALL_ATTRIBUTES = GET + "AllAttributes"; 877 private static final String GET_DOMAIN_ROOT = GET + DOMAIN_ROOT; 878 private static final String GET_OBJECT_NAME = GET + AMXAttributes.ATTR_OBJECT_NAME; 879 880 884 private static final Set <String > SPECIAL_METHOD_NAMES = GSetUtil.newUnmodifiableStringSet( 885 GET_MBEAN_INFO, 886 GET_J2EE_TYPE, 887 GET_J2EE_NAME, 888 GET_ATTRIBUTE_NAMES, 889 GET_CONTAINER, 890 GET_DOMAIN_ROOT, 891 GET_OBJECT_NAME, 892 GET_EXTRA, 893 GET_ALL_ATTRIBUTES, 894 895 ADD_NOTIFICATION_LISTENER, 896 REMOVE_NOTIFICATION_LISTENER 897 ); 898 899 904 private Object 905 handleSpecialMethod( 906 final Object myProxy, 907 final Method method, 908 final Object [] args ) 909 throws ClassNotFoundException , JMException , IOException 910 { 911 final String methodName = method.getName(); 912 final int numArgs = args == null ? 0 : args.length; 913 Object result = null; 914 boolean handled = true; 915 916 if ( numArgs == 0 ) 917 { 918 if ( methodName.equals( GET_CONTAINER ) ) 919 { 920 result = getContainer( Util.asAMX(myProxy) ); 921 } 922 else if ( methodName.equals( GET_EXTRA ) ) 923 { 924 assert( this instanceof Extra ); 925 result = this; 926 } 927 else if ( methodName.equals( GET_OBJECT_NAME ) ) 928 { 929 result = getTargetObjectName(); 930 } 931 else if ( methodName.equals( GET_DOMAIN_ROOT ) ) 932 { 933 result = getDomainRoot( ); 934 } 935 else if ( methodName.equals( GET_ATTRIBUTE_NAMES ) ) 936 { 937 result = getAttributeNames(); 938 } 939 else if ( methodName.equals( GET_J2EE_TYPE ) ) 940 { 941 result = Util.getJ2EEType( getTargetObjectName() ); 942 } 943 else if ( methodName.equals( GET_J2EE_NAME ) ) 944 { 945 result = Util.getName( getTargetObjectName() ); 946 } 947 else if ( methodName.equals( GET_ALL_ATTRIBUTES ) ) 948 { 949 result = getAllAttributes(); 950 } 951 else 952 { 953 handled = false; 954 } 955 } 956 else if ( numArgs == 1 && methodName.equals( "equals" ) ) 957 { 958 return equals( args[ 0 ] ); 959 } 960 else 961 { 962 final Class [] signature = method.getParameterTypes(); 963 964 if ( methodName.equals( ADD_NOTIFICATION_LISTENER ) && 965 ( ClassUtil.sigsEqual( NOTIFICATION_LISTENER_SIG1, signature ) || 966 ClassUtil.sigsEqual( NOTIFICATION_LISTENER_SIG2, signature ) ) 967 ) 968 { 969 addNotificationListener( args ); 970 } 971 else if ( methodName.equals( REMOVE_NOTIFICATION_LISTENER ) && 972 ( ClassUtil.sigsEqual( NOTIFICATION_LISTENER_SIG1, signature ) || 973 ClassUtil.sigsEqual( NOTIFICATION_LISTENER_SIG2, signature ) ) 974 ) 975 { 976 removeNotificationListener( args ); 977 } 978 else 979 { 980 handled = false; 981 } 982 } 983 984 if ( ! handled ) 985 { 986 assert( false ); 987 throw new RuntimeException ( "unknown method: " + method ); 988 } 989 990 return( result ); 991 } 992 993 public final Object 994 invoke( 995 final Object myProxy, 996 final Method method, 997 final Object [] args ) 998 throws java.lang.Throwable 999 { 1000 try 1001 { 1002 final Object result = _invoke( myProxy, method, args ); 1003 1004 assert( result == null || 1005 ClassUtil.IsPrimitiveClass( method.getReturnType() ) || 1006 method.getReturnType().isAssignableFrom( result.getClass() ) ) : 1007 method.getName() + ": result of type " + result.getClass().getName() + 1008 " not assignable to " + method.getReturnType().getName() + ", " + 1009 "interfaces: " + toString( result.getClass().getInterfaces() + 1010 ", ObjectName = " + JMXUtil.toString( getTargetObjectName() ) ); 1011 1012 return result; 1013 } 1014 catch( IOException e ) 1015 { 1016 getProxyFactory().checkConnection(); 1017 throw e; 1018 } 1019 catch( InstanceNotFoundException e ) 1020 { 1021 checkValid(); 1022 throw e; 1023 } 1024 } 1025 1026 protected Object 1027 _invoke( 1028 final Object myProxy, 1029 final Method method, 1030 final Object [] args ) 1031 throws java.lang.Throwable 1032 { 1033 debugMethod( method.getName(), args ); 1034 1035 if ( ! targetIsValid() ) 1038 { 1039 throw new InstanceNotFoundException ( getTargetObjectName().toString() ); 1040 } 1041 1042 Object result = null; 1043 1044 final String methodName = method.getName(); 1045 final int numArgs = args == null ? 0 : args.length; 1046 1047 boolean handled = false; 1048 1049 if ( SPECIAL_METHOD_NAMES.contains( methodName ) ) 1050 { 1051 handled = true; 1052 result = handleSpecialMethod( myProxy, method, args ); 1053 } 1054 else if ( JMXUtil.isIsOrGetter( method ) ) 1055 { 1056 assert( ! handled ); 1057 1058 final String attrName = JMXUtil.getAttributeName( method ); 1059 1060 if ( CACHED_ATTRIBUTE_NAMES.contains( attrName ) ) 1061 { 1062 result = getCachedAttributeValue( attrName ); 1063 handled = true; 1064 } 1065 } 1066 1067 if ( ! handled ) 1068 { 1069 if ( isSingleProxyGetter( method, numArgs) ) 1070 { 1071 result = invokeSingleProxyGetter( myProxy, method, args ); 1072 } 1073 else if ( isProxySetGetter( method, numArgs ) ) 1074 { 1075 result = invokeProxySetGetter( myProxy, method, args ); 1076 } 1077 else if ( isProxyMapGetter( method, numArgs ) ) 1078 { 1079 result = invokeProxyMapGetter( myProxy, method, args ); 1080 } 1081 else if ( isProxyListGetter( method, numArgs ) ) 1082 { 1083 result = invokeProxyListGetter( myProxy, method, args ); 1084 } 1085 else if ( isProxyCreator( method ) ) 1086 { 1087 result = invokeProxyCreator( method, args ); 1088 } 1089 else 1090 { 1091 result = super.invoke( myProxy, method, args ); 1092 } 1093 } 1094 1095 if ( getDebug() ) 1096 { 1097 debug( AMXDebug.methodString( methodName, args ) + 1098 " => " + toString( result ) ); 1099 } 1100 1101 return( result ); 1102 } 1103 1104 1105 protected void 1106 addNotificationListener( final Object [] args ) 1107 throws IOException , InstanceNotFoundException 1108 { 1109 final NotificationListener listener = (NotificationListener )args[ 0 ]; 1110 final NotificationFilter filter = (NotificationFilter )(args.length <= 1 ? null : args[ 1 ]); 1111 final Object handback = args.length <= 1 ? null : args[ 2 ]; 1112 1113 getConnection().addNotificationListener( 1114 getTargetObjectName(), listener, filter, handback ); 1115 } 1116 1117 protected void 1118 removeNotificationListener( final Object [] args ) 1119 throws IOException , InstanceNotFoundException , ListenerNotFoundException 1120 { 1121 final NotificationListener listener = (NotificationListener )args[ 0 ]; 1122 1123 if ( args.length == 1 ) 1126 { 1127 getConnection().removeNotificationListener( getTargetObjectName(), listener ); 1128 } 1129 else 1130 { 1131 final NotificationFilter filter = (NotificationFilter )args[ 1 ]; 1132 final Object handback = args[ 2 ]; 1133 1134 getConnection().removeNotificationListener( 1135 getTargetObjectName(), listener, filter, handback ); 1136 } 1137 } 1138} 1139 1140 1141 1142 1143 1144 | Popular Tags |