1 23 24 package com.sun.appserv.management.util.jmx; 25 26 import java.util.Map ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.Arrays ; 30 31 import javax.management.MBeanServerConnection ; 32 import javax.management.MBeanAttributeInfo ; 33 import javax.management.MBeanInfo ; 34 import javax.management.MBeanOperationInfo ; 35 import javax.management.MBeanParameterInfo ; 36 import javax.management.ObjectName ; 37 38 import com.sun.appserv.management.util.misc.ClassUtil; 39 import com.sun.appserv.management.util.jmx.AttributeNameMapper; 40 import com.sun.appserv.management.util.jmx.AttributeNameMapperImpl; 41 42 45 public class MBeanGenerator implements MBeanGeneratorHook 46 { 47 boolean mEmitComments; 48 Map <String ,Integer > mCounts; 49 AttributeNameMapper mMapper; 50 51 public 52 MBeanGenerator( ) 53 { 54 mCounts = null; 55 mEmitComments = true; 56 } 57 58 private final static String TAB = "\t"; 59 private final static String NEWLINE = "\n"; 60 private final static String PARAM_DELIM = ", "; 61 public final static String FINAL_PREFIX = "final "; 62 public final static int IMPORT_THRESHOLD = 2; 63 64 65 private static final String BRACKETS = "[]"; 66 67 static String 68 stripBrackets( String name ) 69 { 70 String result = name; 71 72 while( result.endsWith( BRACKETS ) ) 73 { 74 result = result.substring( 0, result.length() - BRACKETS.length() ); 75 } 76 77 return( result ); 78 } 79 80 81 private static void 82 countType( Map <String ,Integer > counts, String typeIn ) 83 { 84 final String type = stripBrackets( ClassUtil.getFriendlyClassname( typeIn ) ); 85 86 Integer count = counts.get( type ); 87 if ( count == null ) 88 { 89 count = new Integer ( 1 ); 90 } 91 else 92 { 93 count = new Integer ( count.intValue() + 1 ); 94 } 95 96 counts.put( type, count ); 97 } 98 99 102 public static void 103 countTypes( Map <String ,Integer > counts, MBeanAttributeInfo [] infos ) 104 { 105 for( int i = 0; i < infos.length; ++i ) 106 { 107 countType( counts, infos[ i ].getType() ); 108 } 109 } 110 111 114 private static void 115 countTypes( Map <String ,Integer > counts, MBeanOperationInfo [] infos ) 116 { 117 for( int i = 0; i < infos.length; ++i ) 118 { 119 countType( counts, infos[ i ].getReturnType() ); 120 121 final MBeanParameterInfo [] params = infos[ i ].getSignature(); 122 for( int p = 0; p < params.length; ++p ) 123 { 124 countType( counts, params[ p ].getType() ); 125 } 126 } 127 } 128 129 130 131 String 132 getCodeClassname( String classname ) 133 { 134 String name = ClassUtil.getFriendlyClassname( classname ); 135 136 if ( typeMayBeAbbreviated( name ) ) 137 { 138 name = ClassUtil.stripPackagePrefix( name ); 139 } 140 141 return( name ); 142 } 143 144 145 private Map <String ,Integer > 146 countAllTypes( MBeanInfo info ) 147 { 148 final Map <String ,Integer > counts = new HashMap <String ,Integer >(); 149 final MBeanAttributeInfo [] attrInfos = info.getAttributes(); 150 final MBeanOperationInfo [] operationInfos = info.getOperations(); 151 if ( attrInfos != null ) 152 { 153 countTypes( counts, attrInfos ); 154 } 155 if ( operationInfos != null ) 156 { 157 countTypes( counts, operationInfos ); 158 } 159 160 return( counts ); 161 } 162 163 private String 164 getImportBlock( Map counts ) 165 { 166 final StringBuffer buf = new StringBuffer (); 167 final Iterator iter = counts.keySet().iterator(); 168 169 while ( iter.hasNext() ) 170 { 171 final String key = (String )iter.next(); 172 final Integer count = (Integer )counts.get( key ); 173 174 if ( count.intValue() >= IMPORT_THRESHOLD && ! isUnqualifiedType( key ) ) 176 { 177 buf.append( "import " + key + ";" + NEWLINE ); 178 } 179 } 180 181 return( buf.toString() ); 182 } 183 184 protected boolean 185 isUnqualifiedType( String type ) 186 { 187 return( type.indexOf( "." ) < 0 ); 188 } 189 190 193 protected boolean 194 typeMayBeAbbreviated( String type ) 195 { 196 final Integer count = mCounts.get( type ); 197 if ( count == null ) 198 { 199 return( false ); 200 } 201 202 return( count.intValue() >= IMPORT_THRESHOLD ); 203 } 204 205 206 public String 207 generate( final MBeanInfo info, boolean emitComments ) 208 { 209 mEmitComments = emitComments; 210 211 final StringBuffer buf = new StringBuffer (); 212 213 if ( mEmitComments ) 214 { 215 buf.append( getHeaderComment( info ) + NEWLINE + NEWLINE ); 216 } 217 218 buf.append( "package " + getPackageName( info ) + ";" + NEWLINE ); 219 220 mCounts = countAllTypes( info ); 221 buf.append( NEWLINE + getImportBlock( mCounts ) + NEWLINE ); 222 223 if ( mEmitComments ) 224 { 225 buf.append( getInterfaceComment( info ) + NEWLINE + NEWLINE ); 226 } 227 String interfaceName = getClassname( info ); 228 buf.append( "public interface " + interfaceName + " \n{\n" ); 229 230 231 final MBeanAttributeInfo [] attrInfos = info.getAttributes(); 232 final MBeanOperationInfo [] operationInfos = info.getOperations(); 233 if ( attrInfos != null ) 234 { 235 Arrays.sort( attrInfos, MBeanAttributeInfoComparator.INSTANCE ); 236 buf.append( generateAttributes( attrInfos ) ); 237 } 238 if ( operationInfos != null ) 239 { 240 if ( operationInfos.length != 0 ) 241 { 242 Arrays.sort( operationInfos, MBeanOperationInfoComparator.INSTANCE ); 243 244 buf.append( NEWLINE + "// -------------------- Operations --------------------" + NEWLINE ); 245 buf.append( generateOperations( operationInfos ) ); 246 } 247 } 248 249 250 buf.append( "\n}" ); 251 252 return( buf.toString() ); 253 } 254 255 256 257 protected String 258 indent( String contents, String prefix) 259 { 260 final StringBuffer buf = new StringBuffer (); 261 if ( contents.length() != 0 ) 262 { 263 final String [] lines = contents.split( NEWLINE ); 264 265 for( int i = 0; i < lines.length; ++i ) 266 { 267 buf.append( prefix + lines[ i ] + NEWLINE); 268 } 269 270 buf.setLength( buf.length() - 1 ); 271 } 272 273 return( buf.toString() ); 274 } 275 276 protected String 277 indent( String contents ) 278 { 279 return( indent( contents, TAB ) ); 280 } 281 282 protected String 283 makeJavadocComment( String contents ) 284 { 285 return( "/**" + NEWLINE + indent( contents ) + NEWLINE + "*/" ); 286 } 287 288 289 protected String 290 formMethod( String returnType, String name, String [] params, String [] names ) 291 { 292 final String begin = "public " + getCodeClassname( returnType ) + TAB + name + "("; 293 String paramsString = ""; 294 if ( params != null && params.length != 0 ) 295 { 296 final StringBuffer buf = new StringBuffer (); 297 298 buf.append( " " ); 299 for( int i = 0; i < params.length; ++i ) 300 { 301 buf.append( FINAL_PREFIX ); 302 buf.append( getCodeClassname( params[ i ] ) ); 303 buf.append( " " + names[ i ] ); 304 buf.append( PARAM_DELIM ); 305 } 306 307 buf.setLength( buf.length() - PARAM_DELIM.length() ); buf.append( " " ); 309 paramsString = buf.toString(); 310 } 311 312 313 return( begin + paramsString + ");" ); 314 } 315 316 320 protected String 321 getAttributeNameComment( String attributeName, String javaName ) 322 { 323 String comment = ""; 324 325 if ( ! attributeName.equals( javaName ) ) 326 { 327 328 } 329 return( comment ); 330 } 331 332 protected String 333 generateAttributes( MBeanAttributeInfo [] infos ) 334 { 335 final StringBuffer buf = new StringBuffer (); 336 337 final String [] typeTemp = new String [ 1 ]; 338 final String [] nameTemp = new String [ 1 ]; 339 340 mMapper = new AttributeNameMapperImpl( JMXUtil.getAttributeNames( infos ) ); 341 342 for( int i = 0; i < infos.length; ++i ) 343 { 344 final MBeanAttributeInfo info = infos[ i ]; 345 346 final String attributeName = info.getName(); 347 final String type = info.getType(); 348 String comment = ""; 349 350 final String javaName = mMapper.originalToDerived( attributeName ); 351 352 if ( info.isReadable() ) 353 { 354 if ( mEmitComments ) 355 { 356 comment = getGetterComment( info, javaName ); 357 if ( comment.length() != 0 ) 358 { 359 buf.append( indent( comment ) + NEWLINE ); 360 } 361 } 362 buf.append( indent( formMethod( type, "get" + javaName, null, null) ) ); 363 } 364 365 if ( info.isWritable() ) 366 { 367 buf.append( NEWLINE ); 368 if ( mEmitComments ) 369 { 370 comment = getSetterComment( info, javaName ); 371 if ( comment.length() != 0 ) 372 { 373 buf.append( indent( comment ) + NEWLINE ); 374 } 375 } 376 377 typeTemp[ 0 ] = type; 378 nameTemp[ 0 ] = "value"; 379 380 buf.append( indent( formMethod( "void", "set" + javaName, typeTemp, nameTemp ) ) ); 381 } 382 383 buf.append( NEWLINE + NEWLINE ); 384 } 385 386 return( buf.toString() ); 387 } 388 389 protected String 390 generateOperations( MBeanOperationInfo [] infos ) 391 { 392 final StringBuffer buf = new StringBuffer (); 393 394 for( int i = 0; i < infos.length; ++i ) 395 { 396 final MBeanOperationInfo info = infos[ i ]; 397 final String name = info.getName(); 398 final String returnType = info.getReturnType(); 399 final MBeanParameterInfo [] paramInfos = info.getSignature(); 400 final int impact = info.getImpact(); 401 402 final String [] paramTypes = new String [ paramInfos.length ]; 403 for( int p = 0; p < paramInfos.length; ++p ) 404 { 405 paramTypes[ p ] = paramInfos[ p ].getType(); 406 } 407 408 final String [] paramNames = getParamNames( info ); 409 410 if ( mEmitComments ) 411 { 412 final String comment = getOperationComment( info, paramNames ); 413 if ( comment.length() != 0 ) 414 { 415 buf.append( NEWLINE + indent( comment ) + NEWLINE ); 416 } 417 } 418 419 final String method = formMethod( returnType, name, paramTypes, paramNames ); 420 buf.append( indent( method ) + NEWLINE ); 421 } 422 423 return( buf.toString() ); 424 } 425 426 protected boolean 427 isBoilerplateDescription( String description ) 428 { 429 return( description == null || description.length() == 0 || 430 description.indexOf( "Attribute exposed for management" ) >= 0 || 431 description.indexOf( "Operation exposed for management" ) >= 0 || 432 description.indexOf( "No Description was available" ) >= 0); 433 } 434 435 public String [] 436 getParamNames( MBeanOperationInfo info ) 437 { 438 final MBeanParameterInfo [] params = info.getSignature(); 439 440 final String [] names = new String [ params.length ]; 441 442 for( int i = 0; i < params.length; ++i ) 443 { 444 names[ i ] = params[ i ].getName(); 445 } 446 447 return( names ); 448 } 449 450 451 public String 452 getGetterSetterComment( MBeanAttributeInfo info, String actualName ) 453 { 454 String description = info.getDescription() == null ? "" : info.getDescription(); 455 if ( isBoilerplateDescription( description ) ) 456 { 457 description = ""; 458 } 459 460 final String nameComment = getAttributeNameComment( info.getName(), actualName ); 461 String result = null; 462 463 if ( description.length() == 0 && nameComment.length() == 0 ) 464 { 465 result = ""; 466 } 467 else 468 { 469 result = description; 470 if ( nameComment.length() != 0 ) 471 { 472 if ( description.length() != 0 ) 473 { 474 result = result + NEWLINE; 475 } 476 result = result + nameComment; 477 } 478 479 result = makeJavadocComment( result ); 480 } 481 482 return( result ); 483 } 484 485 public String 486 getGetterComment( MBeanAttributeInfo info, String actualName ) 487 { 488 return( getGetterSetterComment( info, actualName ) ); 489 } 490 491 public String 492 getSetterComment( MBeanAttributeInfo info, String actualName ) 493 { 494 return( getGetterSetterComment( info, actualName ) ); 495 } 496 497 public String 498 getOperationComment( MBeanOperationInfo info, final String [] paramNames ) 499 { 500 final String description = info.getDescription(); 501 502 if ( description == null || isBoilerplateDescription( description ) ) 503 { 504 return( "" ); 505 } 506 507 final StringBuffer buf = new StringBuffer (); 508 509 final MBeanParameterInfo [] signature = info.getSignature(); 510 for( int i = 0; i < paramNames.length; ++i ) 511 { 512 final String paramDescription = signature[i].getDescription(); 513 514 buf.append( "@param " + paramNames[ i ] + TAB + paramDescription + NEWLINE ); 515 } 516 517 final String returnType = getCodeClassname( info.getReturnType() ); 518 if ( ! returnType.equals( "void" ) ) 519 { 520 buf.append( "@return " + returnType + NEWLINE ); 521 } 522 523 return( makeJavadocComment( buf.toString() ) ); 524 } 525 526 public String 527 getHeaderComment( final MBeanInfo info ) 528 { 529 return( makeJavadocComment( "" ) ); 530 } 531 public String 532 getInterfaceComment( final MBeanInfo info ) 533 { 534 final String comment = "Implementing class was: " + info.getClassName(); 535 536 return( makeJavadocComment( comment ) ); 537 } 538 539 public String 540 getPackageName( final MBeanInfo info ) 541 { 542 return( "mbeans" ); 543 } 544 545 private static int sCounter = 0; 546 private static synchronized final int 547 getCounter() 548 { 549 return( sCounter++ ); 550 } 551 552 public String 553 getClassname( final MBeanInfo info ) 554 { 555 return( "Interface" + getCounter() ); 557 } 558 559 public String 560 getExceptions( final MBeanOperationInfo info ) 561 { 562 return( "" ); 563 } 564 } 565 566 567 568 569 570 571 | Popular Tags |