1 23 24 29 30 package com.sun.cli.util; 31 32 import javax.management.*; 33 import java.lang.reflect.Array ; 34 import java.lang.reflect.Constructor ; 35 36 37 40 final class ClassToClassMapping 41 { 42 final Class mSrc; 43 final Class mDest; 44 45 public 46 ClassToClassMapping( Class src, Class dest ) 47 { 48 mSrc = src; 49 mDest = dest; 50 } 51 } 52 53 54 57 public final class ClassUtil 58 { 59 private 60 ClassUtil( ) 61 { 62 } 64 65 static private void 66 p( Object o ) 67 { 68 System.out.println( o.toString() ); 69 } 70 71 77 public static boolean 78 objectIsArray( Object o ) 79 { 80 return( classIsArray( o.getClass() ) ); 81 } 82 83 89 public static boolean 90 classIsArray( Class theClass ) 91 { 92 return( classnameIsArray( theClass.getName() ) ); 93 } 94 95 101 public static boolean 102 objectIsPrimitiveArray( Object o ) 103 { 104 return( getPrimitiveArrayTypeCode( o.getClass() ) != 0 ); 105 } 106 107 113 public static boolean 114 classnameIsArray( String classname ) 115 { 116 return( classname.startsWith( "[" ) ); 117 } 118 119 120 126 public static boolean 127 classnameIsPrimitiveArray( String classname ) 128 { 129 return( getPrimitiveArrayTypeCode( classname ) != 0 ); 130 } 131 132 139 public static char 140 getPrimitiveArrayTypeCode( Class theClass ) 141 { 142 char typeCode = 0; 143 144 if ( classIsArray( theClass ) ) 145 { 146 typeCode = getPrimitiveArrayTypeCode( theClass.getName() ); 147 } 148 149 return( typeCode ); 150 } 151 152 158 public static char 159 getPrimitiveArrayTypeCode( String classname ) 160 { 161 char typeCode = 0; 162 163 final int length = classname.length(); 164 165 if ( classnameIsArray( classname ) && 166 classname.charAt( length - 2 ) == '[' ) 167 { 168 typeCode = classname.charAt( length - 1 ); 169 170 switch( typeCode ) 171 { 172 default: typeCode = 0; break; 173 174 case 'Z': 175 case 'B': 176 case 'C': 177 case 'S': 178 case 'I': 179 case 'J': 180 case 'F': 181 case 'D': 182 break; 183 } 184 } 185 186 return( typeCode ); 187 } 188 189 190 196 public static String 197 getArrayMemberClassName( String classname ) 198 { 199 String result = null; 200 201 if ( ! classnameIsArray( classname ) ) 202 { 203 throw new IllegalArgumentException ( "not an array" ); 204 } 205 206 final int classnameLength = classname.length(); 207 208 209 if ( classnameIsPrimitiveArray( classname ) ) 210 { 211 final char lastChar = classname.charAt(classnameLength -1 ); 212 213 switch( lastChar ) 214 { 215 default: assert( false ); 216 217 case 'Z': result = "boolean"; break; 219 case 'B': result = "byte"; break; 220 case 'C': result = "char"; break; 221 case 'S': result = "short"; break; 222 case 'I': result = "int"; break; 223 case 'J': result = "long"; break; 224 case 'F': result = "float"; break; 225 case 'D': result = "double"; break; 226 } 227 } 228 else 229 { 230 result = classname.substring( 2, classnameLength - 1 ); 232 } 233 234 return( result ); 235 } 236 237 238 239 240 243 final static class ClassNameToClassMapping 244 { 245 String mName; 246 Class mClass; 247 248 ClassNameToClassMapping( String name, Class theClass ) 249 { 250 mName = name; 251 mClass = theClass; 252 } 253 } 254 255 private static final ClassNameToClassMapping [] sPrimitiveNameToObjectClass = 256 new ClassNameToClassMapping [] 257 { 258 new ClassNameToClassMapping( "int", int.class ), 259 new ClassNameToClassMapping( "long", long.class ), 260 new ClassNameToClassMapping( "short", short.class ), 261 new ClassNameToClassMapping( "byte", byte.class ), 262 new ClassNameToClassMapping( "boolean", boolean.class ), 263 new ClassNameToClassMapping( "float", float.class ), 264 new ClassNameToClassMapping( "double", double.class ), 265 new ClassNameToClassMapping( "char", char.class ), 266 new ClassNameToClassMapping( "void", void.class ), 267 }; 268 269 276 public static Class 277 getClassFromName( final String classname ) 278 throws ClassNotFoundException 279 { 280 Class theClass = null; 281 282 if ( classname.startsWith( "[L" )) 283 { 284 theClass = Class.forName( classname ); 286 } 287 else 288 { 289 final int numMappings = Array.getLength( sPrimitiveNameToObjectClass ); 290 for( int i = 0; i < numMappings; ++i ) 291 { 292 if ( sPrimitiveNameToObjectClass[ i ].mName.equals( classname ) ) 293 { 294 theClass = sPrimitiveNameToObjectClass[ i ].mClass; 295 break; 296 } 297 } 298 299 if ( theClass == null ) 300 { 301 theClass = theClass.forName( classname ); 302 } 303 } 304 return( theClass ); 305 } 306 307 308 private static final ClassToClassMapping [] sPrimitiveClassToObjectClass = 309 new ClassToClassMapping [] 310 { 311 new ClassToClassMapping( int.class, Integer .class ), 312 new ClassToClassMapping( long.class, Long .class ), 313 new ClassToClassMapping( short.class, Short .class ), 314 new ClassToClassMapping( byte.class, Byte .class ), 315 new ClassToClassMapping( boolean.class, Boolean .class), 316 new ClassToClassMapping( float.class, Float .class ), 317 new ClassToClassMapping( double.class, Double .class ), 318 new ClassToClassMapping( char.class, Character .class ), 319 }; 320 326 public static Class 327 PrimitiveClassToObjectClass( final Class theClass ) 328 { 329 Class result = theClass; 330 331 final int numMappings = Array.getLength( sPrimitiveClassToObjectClass ); 332 for( int i = 0; i < numMappings; ++i ) 333 { 334 final ClassToClassMapping mapping = sPrimitiveClassToObjectClass[ i ]; 335 336 if ( mapping.mSrc.equals( theClass ) ) 337 { 338 result = mapping.mDest; 339 break; 340 } 341 } 342 343 return( result ); 344 } 345 346 352 public static boolean 353 IsPrimitiveClass( final Class theClass ) 354 { 355 boolean isSimple = false; 356 357 final int numMappings = Array.getLength( sPrimitiveClassToObjectClass ); 358 for( int i = 0; i < numMappings; ++i ) 359 { 360 final ClassToClassMapping mapping = sPrimitiveClassToObjectClass[ i ]; 361 362 if ( mapping.mSrc.equals( theClass ) ) 363 { 364 isSimple = true; 365 break; 366 } 367 } 368 369 return( isSimple ); 370 } 371 372 373 public static String 374 PrimitiveLetterToClassName( final char primitive) 375 { 376 String result = "" + primitive; 377 378 switch( primitive ) 380 { 381 case 'B': result = "byte"; break; 382 case 'C': result = "char"; break; 383 case 'D': result = "double"; break; 384 case 'F': result = "float"; break; 385 case 'I': result = "int"; break; 386 case 'J': result = "long"; break; 387 case 'S': result = "short"; break; 388 case 'Z': result = "boolean";break; 389 } 390 391 return( result ); 392 } 393 394 395 396 397 public static String [] 398 getTypes( final Object [] args ) 399 { 400 if ( args == null ) 401 return( null ); 402 403 final int numArgs = Array.getLength( args ); 404 405 final String [] types = new String [ numArgs ]; 406 407 for( int i = 0; i < numArgs; ++i ) 408 { 409 types[ i ] = args[ i ].getClass().getName(); 410 } 411 412 return( types ); 413 } 414 415 416 public static String 417 getFriendlyClassname( Class theClass ) 418 { 419 return( getFriendlyClassname( theClass.getName() ) ); 420 } 421 422 435 final static String javaLang = "java.lang."; 436 public static String 437 getFriendlyClassname( String type ) 438 { 439 String result = type; 440 441 if ( type.startsWith( "[" ) ) 442 { 443 int depth = 0; 445 while ( type.charAt( depth ) == (int)'[' ) 446 { 447 ++depth; 448 } 449 450 result = type.substring( depth, type.length() ); 452 453 if ( result.startsWith( "L" ) && result.endsWith( ";" ) ) 454 { 455 result = result.substring( 1, result.length() - 1 ); 456 } 457 else if ( result.length() == 1 ) 458 { 459 switch( result.charAt( 0 ) ) 461 { 462 case 'Z': result = "boolean"; break; 463 case 'B': result = "byte"; break; 464 case 'C': result = "char"; break; 465 case 'S': result = "short"; break; 466 case 'I': result = "int"; break; 467 case 'J': result = "long"; break; 468 case 'F': result = "float"; break; 469 case 'D': result = "double"; break; 470 } 471 } 472 473 for( int i = 0; i < depth; ++i ) 474 { 475 result = result + "[]"; 476 } 477 } 478 479 if ( result.startsWith( javaLang ) ) 480 { 481 result = result.substring( javaLang.length(), result.length() ); 482 } 483 484 return( result ); 485 } 486 487 488 490 public static Class 491 getArrayElementClass( final Class arrayClass ) 492 { 493 final String arrayClassName = arrayClass.getName(); 494 495 if ( ! classnameIsArray( arrayClassName ) ) 496 { 497 throw new IllegalArgumentException ( "not an array" ); 498 } 499 500 String name = arrayClassName; 501 502 name = name.substring( 1, name.length() ); 504 505 if ( ! name.startsWith( "[" ) ) 506 { 507 509 if ( name.startsWith( "L" ) ) 510 { 511 name = name.substring( 1, name.length() - 1); 513 } 514 else if ( name.length() == 1 ) 515 { 516 name = PrimitiveLetterToClassName( name.charAt( 0 ) ); 518 } 519 } 520 else 521 { 522 } 524 525 Class theClass = null; 526 try 527 { 528 theClass = getClassFromName( name ); 529 } 530 catch( ClassNotFoundException e ) 531 { 532 assert( false ); 533 } 534 535 return( theClass ); 536 } 537 538 public static Class 539 getInnerArrayElementClass( final Class arrayClass ) 540 throws ClassNotFoundException 541 { 542 Class elementClass = arrayClass; 543 544 do 545 { 546 elementClass = getArrayElementClass( elementClass ); 547 } 548 while ( classIsArray( elementClass ) ); 549 550 return( elementClass ); 551 } 552 553 554 555 556 private static Object 557 InstantiateObject( final String theString ) 558 throws Exception 559 { 560 Object result = null; 561 562 try 563 { 564 result = InstantiateNumber( theString ); 565 } 566 catch( NumberFormatException e ) 567 { 568 result = theString; 569 } 570 571 return( result ); 572 } 573 574 580 public static boolean 581 signaturesAreCompatible( Class [] callee, Class [] argsSignature ) 582 { 583 boolean compatible = false; 584 585 if ( callee.length == argsSignature.length ) 586 { 587 compatible = true; 588 589 for( int i = 0; i < callee.length; ++i ) 590 { 591 if ( ! callee[ i ].isAssignableFrom( argsSignature[ i ] ) ) 592 { 593 compatible = false; 594 break; 595 } 596 } 597 } 598 599 return( compatible ); 600 } 601 602 public static Object 603 InstantiateObject( final Class theClass, final Object [] args ) 604 throws Exception 605 { 606 final Class [] signature = new Class [ args.length ]; 607 608 for( int i = 0; i < signature.length; ++i ) 609 { 610 signature[ i ] = args[ i ].getClass(); 611 } 612 613 Constructor constructor = null; 614 try 615 { 616 constructor = theClass.getConstructor( signature ); 619 } 620 catch( NoSuchMethodException e ) 621 { 622 final Constructor [] constructors = theClass.getConstructors(); 623 624 int numMatches = 0; 625 for( int i = 0; i < constructors.length; ++i ) 626 { 627 final Constructor tempConstructor = constructors[ i ]; 628 629 final Class [] tempSignature = tempConstructor.getParameterTypes(); 630 631 if ( signaturesAreCompatible( tempSignature, signature ) ) 632 { 633 ++numMatches; 634 constructor = tempConstructor; 635 } 637 } 638 639 if ( numMatches != 1 ) 641 { 642 throw e; 643 } 644 } 645 646 Object result = null; 647 try 648 { 649 result = constructor.newInstance( args ); 650 } 651 catch( java.lang.reflect.InvocationTargetException e ) 652 { 653 final Throwable cause = e.getCause(); 655 656 if ( cause instanceof Exception ) 657 { 658 throw (Exception )cause; 659 } 660 else 661 { 662 throw e; 664 } 665 } 666 667 return( result ); 668 } 669 670 671 public static Object 672 InstantiateObject( final Class theClass, final String theString ) 673 throws Exception 674 { 675 final Class [] signature = new Class [] { String .class }; 676 final Constructor constructor = theClass.getConstructor( signature ); 677 678 Object result = null; 679 try 680 { 681 result = constructor.newInstance( new Object [] { theString } ); 682 } 683 catch( java.lang.reflect.InvocationTargetException e ) 684 { 685 Throwable cause = e.getCause(); 687 688 if ( cause instanceof Exception ) 689 { 690 throw (Exception )cause; 691 } 692 else 693 { 694 throw e; 696 } 697 } 698 699 return( result ); 700 } 701 702 707 private static Object 708 InstantiateNumber( final String theString ) 709 throws Exception 710 { 711 Object result = null; 712 713 if ( theString.indexOf( '.' ) >= 0 ) 714 { 715 result = InstantiateObject( Double .class, theString ); 716 } 717 else 718 { 719 try 720 { 721 result = InstantiateObject( Integer .class, theString ); 722 } 723 catch( NumberFormatException e ) 724 { 725 result = InstantiateObject( Long .class, theString ); 727 } 728 } 729 return( result ); 730 } 731 732 733 740 public static Object 741 InstantiateFromString( final Class theClass, final String theString ) 742 throws Exception 743 { 744 Object result = null; 745 746 if ( theClass == Object .class ) 748 { 749 result = InstantiateObject( theString ); 751 } 752 else if ( theClass == Number .class ) 753 { 754 result = InstantiateNumber( theString ); 756 } 757 else if ( theClass == Character .class || theClass == char.class) 758 { 759 if ( theString.length() != 1 ) 760 { 761 throw new IllegalArgumentException ( "not a character: " + theString ); 762 } 763 764 result = new Character ( theString.charAt( 0 ) ); 765 } 766 else 767 { 768 769 final Class objectClass = PrimitiveClassToObjectClass( theClass ); 770 771 result = InstantiateObject( objectClass, theString ); 772 } 773 774 return( result ); 775 } 776 777 778 785 public static Object 786 InstantiateDefault( final Class inClass ) 787 throws Exception 788 { 789 Object result = null; 790 791 final Class objectClass = PrimitiveClassToObjectClass( inClass ); 792 793 if ( Number .class.isAssignableFrom( objectClass ) ) 794 { 795 result = InstantiateFromString( objectClass, "0" ); 796 } 797 else if ( objectClass == Boolean .class) 798 { 799 result = new Boolean ( "true" ); 800 } 801 else if ( objectClass == Character .class) 802 { 803 result = new Character ( 'X' ); 804 } 805 else if ( classIsArray( objectClass ) ) 806 { 807 result = Array.newInstance( objectClass, 0 ); 808 } 809 else if ( objectClass == Object .class ) 810 { 811 result = new String ( "anyObject" ); 812 } 813 else if ( objectClass == String .class ) 814 { 815 result = new String ( "" ); 816 } 817 else if ( objectClass == java.net.URL .class ) 818 { 819 result = new java.net.URL ( "http://www.sun.com" ); 820 } 821 else if ( objectClass == java.net.URI .class ) 822 { 823 result = new java.net.URI ( "http://www.sun.com" ); 824 } 825 else if ( classIsArray( inClass ) ) 826 { 827 final int dimensions = 3; 828 result = Array.newInstance( getInnerArrayElementClass( inClass ), dimensions ); 829 } 830 else 831 { 832 result = objectClass.newInstance(); 833 } 835 return( result ); 836 } 837 838 839 844 final static String [] sJavaLangTypes = 845 { "Character", "Boolean", "Byte", "Short", "Integer", "Long", "Float", "Double", "String", "Object"}; 846 final static int sNumBaseTypes = Array.getLength( sJavaLangTypes ); 847 848 public static String 849 ExpandClassName( final String name ) 850 { 851 String fullName = name; 852 853 final int numTypes = sNumBaseTypes; 854 for( int i = 0; i < numTypes; ++i ) 855 { 856 if ( name.equals( sJavaLangTypes[ i ] ) ) 857 { 858 fullName = "java.lang." + name; 859 break; 860 } 861 } 862 863 if ( fullName == name ) { 865 if ( name.equals( "Number" ) ) 866 { 867 fullName = "java.lang." + name; 868 } 869 else if ( name.equals( "BigDecimal" ) || name.equals( "BigInteger" ) ) 870 { 871 fullName = "java.math." + name; 872 } 873 else if ( name.equals( "URL" ) || name.equals( "URI" ) ) 874 { 875 fullName = "java.net." + name; 876 } 877 else if ( name.equals( "Date" ) ) 878 { 879 fullName = "java.util." + name; 880 } 881 else if ( name.equals( "ObjectName" ) ) 882 { 883 fullName = "javax.management." + name; 884 } 885 886 } 887 888 return( fullName ); 889 } 890 891 892 893 898 public static Class 899 convertArrayClass( final Class arrayClass, final Class newInnerType ) 900 throws ClassNotFoundException 901 { 902 final String arrayClassname = arrayClass.getName(); 903 if ( ! arrayClassname.endsWith( ";" ) ) 904 { 905 throw new IllegalArgumentException ( "not an array of Object" ); 906 } 907 908 final int innerNameBegin = 1 + arrayClassname.indexOf( "L" ); 909 910 final String newClassName = arrayClassname.substring( 0, innerNameBegin ) + newInnerType.getName() + ";"; 911 912 final Class newClass = getClassFromName( newClassName ); 913 914 return( newClass ); 915 } 916 917 918 } 919 920 | Popular Tags |