1 23 24 29 30 package com.sun.appserv.management.util.jmx; 31 32 import java.io.IOException ; 33 34 import java.lang.reflect.Proxy ; 35 import java.lang.reflect.Method ; 36 import java.util.logging.Logger ; 37 38 import javax.management.Attribute ; 39 import javax.management.AttributeList ; 40 import javax.management.MBeanAttributeInfo ; 41 import javax.management.MBeanInfo ; 42 import javax.management.MBeanServerConnection ; 43 import javax.management.ObjectName ; 44 import javax.management.MBeanServerInvocationHandler ; 45 import javax.management.NotificationBroadcaster ; 46 import javax.management.ReflectionException ; 47 import javax.management.IntrospectionException ; 48 import javax.management.InstanceNotFoundException ; 49 import javax.management.AttributeNotFoundException ; 50 import javax.management.InvalidAttributeValueException ; 51 import javax.management.MBeanException ; 52 53 54 import com.sun.appserv.management.base.AMXDebug; 55 import com.sun.appserv.management.client.ConnectionSource; 56 import com.sun.appserv.management.util.jmx.JMXUtil; 57 import com.sun.appserv.management.util.jmx.AttributeNameMangler; 58 import com.sun.appserv.management.util.jmx.AttributeNameMapper; 59 import com.sun.appserv.management.util.jmx.AttributeNameMapperImpl; 60 import com.sun.appserv.management.util.misc.ExceptionUtil; 61 import com.sun.appserv.management.util.misc.StringUtil; 62 import com.sun.appserv.management.util.misc.ObjectUtil; 63 import com.sun.appserv.management.util.misc.Output; 64 65 66 74 public class MBeanProxyHandler extends MBeanServerInvocationHandler 75 { 77 protected final static String GET = "get"; 78 protected final static String SET = "set"; 79 protected final static String IS = "is"; 80 protected final static int GET_PREFIX_LENGTH = GET.length(); 81 protected final static int IS_PREFIX_LENGTH = IS.length(); 82 83 protected final ConnectionSource mConnectionSource; 84 protected AttributeNameMangler mMangler; 85 private AttributeNameMapper mMapper; 86 private final ObjectName mTargetObjectName; 87 private boolean mCacheMBeanInfo; 88 private MBeanInfo mCachedMBeanInfo; 89 private boolean mMBeanInfoIsInvariant = false; 90 private Logger mLogger; 91 private boolean mTargetValid; 92 private final Integer mHashCode; 93 94 protected Output mDebug; 95 96 97 static protected final String DEBUG_ID = 98 "com.sun.appserv.management.util.jmx.MBeanProxyHandler"; 99 100 public int 101 hashCode() 102 { 103 return ObjectUtil.hashCode( mTargetObjectName, 104 mConnectionSource, mLogger, mMangler, mMapper, mCachedMBeanInfo, mDebug) ^ 105 ObjectUtil.hashCode( mCacheMBeanInfo ) ^ 106 ObjectUtil.hashCode( mMBeanInfoIsInvariant ) ^ 107 ObjectUtil.hashCode( mTargetValid ); 108 } 109 110 public boolean 111 equals( final Object rhs ) 112 { 113 if ( rhs == this ) 114 { 115 return true; 116 } 117 118 final MBeanProxyHandler other = (MBeanProxyHandler)rhs; 119 120 boolean equals = mTargetObjectName.equals( other.getTargetObjectName() ); 121 if ( equals ) 122 { 123 try 124 { 125 equals = getConnection() == other.getConnection(); 126 } 127 catch( Exception e ) 128 { 129 equals = false; 130 } 131 } 132 133 return equals; 134 } 135 136 137 protected String 138 getDebugID() 139 { 140 return DEBUG_ID; 141 } 142 143 150 public 151 MBeanProxyHandler( 152 ConnectionSource connectionSource, 153 ObjectName objectName ) 154 throws IOException 155 { 156 this( connectionSource, objectName, (AttributeNameMangler)null ); 157 } 158 159 private 160 MBeanProxyHandler( 161 final ConnectionSource connectionSource, 162 final ObjectName objectName, 163 final AttributeNameMapper mapper, 164 final AttributeNameMangler mangler ) 165 throws IOException 166 { 167 super( connectionSource.getMBeanServerConnection( false ), objectName ); 168 169 mDebug = AMXDebug.getInstance().getOutput( getDebugID() ); 170 debugMethod( "MBeanProxyHandler", connectionSource, objectName, mapper, mangler ); 171 mMangler = mangler; 172 mMapper = mapper; 173 mConnectionSource = connectionSource; 174 mTargetObjectName = objectName; 175 mTargetValid = true; 176 177 mCacheMBeanInfo = true; 178 mCachedMBeanInfo = null; 179 mLogger = null; 180 181 mHashCode = this.hashCode(); 182 } 183 184 185 public final void 186 targetUnregistered() 187 { 188 debugMethod( mTargetObjectName.toString(), "targetUnregistered" ); 189 mTargetValid = false; 190 assert( ! targetIsValid() ); 191 } 192 193 public final void 194 connectionBad() 195 { 196 debugMethod( "connectionBad" ); 197 mTargetValid = false; 198 assert( ! targetIsValid() ); 199 } 200 201 protected final boolean 202 targetIsValid() 203 { 204 return( mTargetValid ); 205 } 206 207 public final boolean 208 checkValid() 209 { 210 if ( mTargetValid ) 211 { 212 try 213 { 214 mTargetValid = getConnection().isRegistered( getTargetObjectName() ); 215 } 216 catch( Exception e ) 217 { 218 debug( "checkValid: connection failed" ); 219 mTargetValid = false; 220 } 221 } 222 return( mTargetValid ); 223 } 224 225 232 public 233 MBeanProxyHandler( 234 ConnectionSource connectionSource, 235 ObjectName objectName, 236 AttributeNameMangler mangler ) 237 throws IOException 238 { 239 this( connectionSource, objectName, null, mangler ); 240 } 241 242 250 public 251 MBeanProxyHandler( 252 ConnectionSource connectionSource, 253 ObjectName objectName, 254 AttributeNameMapper mapper ) 255 throws IOException 256 { 257 this( connectionSource, objectName, mapper, null ); 258 } 259 260 public void 261 setProxyLogger( final Logger logger ) 262 { 263 mLogger = logger; 264 } 265 266 protected final static String LOGGER_NAME = "com.sun.appserv.management.Proxy"; 267 268 public Logger 269 getProxyLogger( ) 270 { 271 if ( mLogger == null ) 272 { 273 mLogger = Logger.getLogger( this.getClass().getName() ); 274 } 275 return( mLogger ); 276 } 277 278 public final ConnectionSource 279 getConnectionSource() 280 { 281 return( mConnectionSource ); 282 } 283 284 protected final MBeanServerConnection 285 getConnection() 286 throws IOException 287 { 288 return( mConnectionSource.getMBeanServerConnection( false ) ); 289 } 290 291 protected final ObjectName 292 getTargetObjectName() 293 { 294 return( mTargetObjectName ); 295 } 296 297 public static String [] 298 getAllAttributeNames( 299 final MBeanAttributeInfo [] infos ) 300 { 301 return( JMXUtil.getAttributeNames( infos ) ); 302 } 303 304 311 AttributeNameMapper 312 createMapper( 313 final MBeanAttributeInfo [] attributeInfos, 314 final AttributeNameMangler mangler) 315 { 316 return( new AttributeNameMapperImpl( getAllAttributeNames( attributeInfos ), mangler ) ); 317 } 318 319 323 protected void 324 initMapper( ) 325 throws IOException , IntrospectionException , ReflectionException , InstanceNotFoundException 326 { 327 if ( mMapper == null && mMangler != null) 329 { 330 final MBeanInfo mbeanInfo = getMBeanInfo( true ); 331 332 mMapper = createMapper( mbeanInfo.getAttributes(), mMangler); 333 } 334 } 335 336 protected String 337 extractAttributeNameFromMethod( String methodName ) 338 { 339 assert( methodName.startsWith( GET ) || 340 methodName.startsWith( SET ) || 341 methodName.startsWith( IS ) ); 342 final int startIndex = methodName.startsWith( GET ) || methodName.startsWith( SET ) ? 343 GET_PREFIX_LENGTH : IS_PREFIX_LENGTH; 344 return( methodName.substring( startIndex, methodName.length() ) ); 345 } 346 347 protected boolean 348 isMappedAttributeMethod( final String attributeName ) 349 { 350 boolean isMapped = false; 351 352 if ( mMapper != null ) 353 { 354 final String originalName = mMapper.derivedToOriginal( attributeName ); 355 356 isMapped = ! attributeName.equals( originalName ); 357 } 358 359 return( isMapped ); 360 } 361 362 363 protected void 364 cacheMBeanInfo( final boolean cacheIt ) 365 { 366 mCacheMBeanInfo = cacheIt; 367 mMBeanInfoIsInvariant = cacheIt; 368 if ( ! cacheIt ) 369 { 370 mCachedMBeanInfo = null; 371 } 372 } 373 374 public final boolean 375 getMBeanInfoIsInvariant() 376 { 377 return( mMBeanInfoIsInvariant ); 378 } 379 380 protected final void 381 setMBeanInfoIsInvariant( boolean isInvariant ) 382 { 383 mMBeanInfoIsInvariant = isInvariant; 384 } 385 386 protected final boolean 387 getCacheMBeanInfo() 388 { 389 return( mCacheMBeanInfo ); 390 } 391 392 397 protected MBeanInfo 398 getMBeanInfo( boolean refresh ) 399 throws IOException , InstanceNotFoundException , IntrospectionException , ReflectionException 400 { 401 if ( refresh || 402 (! mCacheMBeanInfo) || 403 mCachedMBeanInfo == null ) 404 { 405 mCachedMBeanInfo = getConnection().getMBeanInfo( getTargetObjectName() ); 406 } 407 return( mCachedMBeanInfo ); 408 } 409 410 413 public Object 414 getAttribute( final String attributeName ) 415 throws InstanceNotFoundException , ReflectionException , 416 MBeanException , AttributeNotFoundException , IOException 417 { 418 final Object result = 419 getConnection().getAttribute( getTargetObjectName(), attributeName ); 420 421 postGetAttributeHook( attributeName, result ); 422 423 return( result ); 424 } 425 426 427 430 public AttributeList 431 getAttributes( final String [] attrNames ) 432 throws IOException , InstanceNotFoundException , ReflectionException 433 { 434 final AttributeList results = 435 getConnection().getAttributes( getTargetObjectName(), attrNames ); 436 437 postGetAttributesHook( attrNames, results ); 438 439 return( results ); 440 } 441 442 445 public void 446 setAttribute( final Attribute attr ) 447 throws IOException , InstanceNotFoundException , ReflectionException , 448 AttributeNotFoundException , MBeanException , InvalidAttributeValueException 449 { 450 getConnection().setAttribute( getTargetObjectName(), attr ); 451 452 postSetAttributeHook( attr ); 453 } 454 455 458 public AttributeList 459 setAttributes( final AttributeList requested ) 460 throws IOException , InstanceNotFoundException , ReflectionException 461 { 462 final AttributeList results = getConnection().setAttributes( getTargetObjectName(), requested ); 463 464 postSetAttributesHook( requested, results ); 465 466 return( results ); 467 } 468 469 private final String LOG_LEVEL_NAME = "LogLevel"; 470 471 protected void 472 postGetAttributeHook( 473 final String name, 474 final Object value ) 475 { 476 } 477 478 protected void 479 postGetAttributesHook( 480 final String [] requested, 481 final AttributeList actual ) 482 { 483 } 484 485 protected void 486 postSetAttributeHook( final Attribute attr ) 487 { 488 } 489 490 protected void 491 postSetAttributesHook( 492 final AttributeList requested, 493 final AttributeList actual ) 494 { 495 } 496 497 498 506 public Object 507 invoke( 508 Object proxy, 509 Method method, 510 Object [] args 511 ) 512 throws java.lang.Throwable 513 { 514 final String methodName = method.getName(); 515 final int numArgs = args == null ? 0 : args.length; 516 517 debugMethod( method.getName(), args ); 518 519 Object result = null; 520 521 final boolean isGetter = JMXUtil.isIsOrGetter( method ); 522 final boolean isSetter = isGetter ? false : JMXUtil.isSetter( method ); 523 524 boolean handled = false; 525 526 if ( methodName.equals( "getTargetObjectName" ) ) 527 { 528 handled = true; 529 result = getTargetObjectName(); 530 } 531 else if ( methodName.equals( "getMBeanInfo" ) && numArgs <= 1) 532 { 533 handled = true; 534 535 if ( numArgs == 1 ) 536 { 537 result = getMBeanInfo( ((Boolean )args[ 0 ] ).booleanValue() ); 538 } 539 else if ( numArgs == 0 ) 540 { 541 result = getMBeanInfo( mCacheMBeanInfo ); 542 } 543 else 544 { 545 handled = false; 546 } 547 } 548 else if ( methodName.equals( "getProxyLogger" ) && numArgs == 0 ) 549 { 550 handled = true; 551 result = getProxyLogger(); 552 } 553 else if ( methodName.equals( "setProxyLogger" ) && 554 numArgs == 1 && 555 method.getParameterTypes()[ 0 ] == Logger .class ) 556 { 557 handled = true; 558 setProxyLogger( (Logger )args[ 0 ] ); 559 } 560 else if ( (isGetter || isSetter) ) 561 { 562 handled = true; 563 initMapper( ); 565 566 final String javaName = extractAttributeNameFromMethod( methodName ); 567 568 String attributeName = javaName; 569 570 if ( isMappedAttributeMethod( javaName ) ) 571 { 572 attributeName = mMapper.derivedToOriginal( javaName ); 573 } 574 575 577 if ( isGetter ) 578 { 579 result = getAttribute( attributeName ); 580 } 581 else 582 { 583 final Attribute attr = new Attribute ( attributeName, args[ 0 ] ); 584 setAttribute( attr ); 585 } 586 } 587 else if ( methodName.indexOf( "etAttribute" ) == 1 ) 588 { 589 handled = true; 590 591 593 if ( JMXUtil.isGetAttribute( method ) ) 595 { 596 final String attrName = (String )args[ 0 ]; 597 result = getAttribute( attrName ); 598 } 599 else if ( JMXUtil.isGetAttributes( method ) ) 600 { 601 final String [] attrNames = (String [])args[ 0 ]; 602 result = (AttributeList )getAttributes( attrNames ); 603 } 604 else if ( JMXUtil.isSetAttribute( method ) ) 605 { 606 final Attribute attr = (Attribute )args[ 0 ]; 607 setAttribute( attr ); 608 } 609 else if ( JMXUtil.isSetAttributes( method ) ) 610 { 611 final AttributeList requested = (AttributeList )args[ 0 ]; 612 result = (AttributeList )setAttributes( requested ); 613 } 614 else 615 { 616 handled = false; 617 } 618 } 619 else if ( methodName.equals( "hashCode" ) ) 620 { 621 628 result = mHashCode; 629 handled = true; 630 } 631 else if ( methodName.equals( "toString" ) ) 632 { 633 result = "proxy to " + JMXUtil.toString( getTargetObjectName() ); 634 handled = true; 635 } 636 else if ( methodName.equals( "equals" ) && numArgs == 1) 637 { 638 result = this.equals( args[ 0 ] ); 639 handled = true; 640 } 641 642 if ( ! handled ) 643 { 644 debugMethod( getTargetObjectName().toString(), "super.invoke", 645 method.getName(), args ); 646 647 result = super.invoke( proxy, method, args ); 648 } 649 650 return( result ); 651 } 652 653 protected boolean 654 getDebug() 655 { 656 return AMXDebug.getInstance().getDebug( getDebugID() ); 657 } 658 659 protected void 660 debugMethod( final String methodName, final Object ... args ) 661 { 662 if ( getDebug() ) 663 { 664 mDebug.println( AMXDebug.methodString( methodName, args ) ); 665 } 666 } 667 668 protected void 669 debugMethod( 670 final String msg, 671 final String methodName, 672 final Object ... args ) 673 { 674 if ( getDebug() ) 675 { 676 mDebug.println( AMXDebug.methodString( methodName, args ) + ": " + msg ); 677 } 678 } 679 680 protected void 681 debug( final Object ... args ) 682 { 683 if ( getDebug() ) 684 { 685 mDebug.println( StringUtil.toString( "", args) ); 686 } 687 } 688 689 protected void 690 debug( final Object o ) 691 { 692 mDebug.println( o ); 693 } 694 } 695 696 697 698 699 700 | Popular Tags |