1 11 package org.codehaus.loom.extension; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.Map ; 16 import java.util.StringTokenizer ; 17 import java.util.jar.Attributes ; 18 import java.util.jar.Manifest ; 19 20 33 public final class Extension 34 { 35 40 public static final Attributes.Name EXTENSION_LIST = Attributes.Name.EXTENSION_LIST; 41 51 public static final Attributes.Name OPTIONAL_EXTENSION_LIST = 52 new Attributes.Name ( "Optional-Extension-List" ); 53 58 public static final Attributes.Name EXTENSION_NAME = 59 Attributes.Name.EXTENSION_NAME; 60 65 public static final Attributes.Name SPECIFICATION_VERSION = 66 Attributes.Name.SPECIFICATION_VERSION; 67 72 public static final Attributes.Name SPECIFICATION_VENDOR = 73 Attributes.Name.SPECIFICATION_VENDOR; 74 79 public static final Attributes.Name IMPLEMENTATION_VERSION = 80 Attributes.Name.IMPLEMENTATION_VERSION; 81 86 public static final Attributes.Name IMPLEMENTATION_VENDOR = 87 Attributes.Name.IMPLEMENTATION_VENDOR; 88 93 public static final Attributes.Name IMPLEMENTATION_URL = 94 Attributes.Name.IMPLEMENTATION_URL; 95 100 public static final Attributes.Name IMPLEMENTATION_VENDOR_ID = 101 Attributes.Name.IMPLEMENTATION_VENDOR_ID; 102 103 public static final Compatability COMPATIBLE = 104 new Compatability( "COMPATIBLE" ); 105 109 public static final Compatability REQUIRE_SPECIFICATION_UPGRADE = 110 new Compatability( "REQUIRE_SPECIFICATION_UPGRADE" ); 111 115 public static final Compatability REQUIRE_VENDOR_SWITCH = 116 new Compatability( "REQUIRE_VENDOR_SWITCH" ); 117 121 public static final Compatability REQUIRE_IMPLEMENTATION_UPGRADE = 122 new Compatability( "REQUIRE_IMPLEMENTATION_UPGRADE" ); 123 128 public static final Compatability INCOMPATIBLE = 129 new Compatability( "INCOMPATIBLE" ); 130 131 private String m_extensionName; 132 136 private DeweyDecimal m_specificationVersion; 137 141 private String m_specificationVendor; 142 146 private String m_implementationVendorID; 147 151 private String m_implementationVendor; 152 156 private String m_implementationVersion; 157 161 private String m_implementationURL; 162 163 172 public static Extension[] getAvailable( final Manifest manifest ) 173 { 174 if( null == manifest ) 175 { 176 return new Extension[ 0 ]; 177 } 178 final ArrayList results = new ArrayList (); 179 final Attributes mainAttributes = manifest.getMainAttributes(); 180 if( null != mainAttributes ) 181 { 182 final Extension extension = getExtension( "", mainAttributes ); 183 if( null != extension ) 184 { 185 results.add( extension ); 186 } 187 } 188 final Map entries = manifest.getEntries(); 189 final Iterator keys = entries.keySet().iterator(); 190 while( keys.hasNext() ) 191 { 192 final String key = (String )keys.next(); 193 final Attributes attributes = (Attributes )entries.get( key ); 194 final Extension extension = getExtension( "", attributes ); 195 if( null != extension ) 196 { 197 results.add( extension ); 198 } 199 } 200 return (Extension[])results.toArray( new Extension[ results.size() ] ); 201 } 202 203 211 public static Extension[] getAvailable( final Manifest [] manifests ) 212 { 213 final ArrayList set = new ArrayList (); 214 for( int i = 0; i < manifests.length; i++ ) 215 { 216 final Extension[] extensions = getAvailable( manifests[ i ] ); 217 for( int j = 0; j < extensions.length; j++ ) 218 { 219 set.add( extensions[ j ] ); 220 } 221 } 222 return (Extension[])set.toArray( new Extension[ set.size() ] ); 223 } 224 225 234 public static Extension[] getRequired( final Manifest manifest ) 235 { 236 return getListed( manifest, EXTENSION_LIST ); 237 } 238 239 247 public static Extension[] getRequired( final Manifest [] manifests ) 248 { 249 final ArrayList set = new ArrayList (); 250 for( int i = 0; i < manifests.length; i++ ) 251 { 252 final Extension[] extensions = getRequired( manifests[ i ] ); 253 for( int j = 0; j < extensions.length; j++ ) 254 { 255 set.add( extensions[ j ] ); 256 } 257 } 258 return (Extension[])set.toArray( new Extension[ set.size() ] ); 259 } 260 261 269 public static Extension[] getOptions( final Manifest manifest ) 270 { 271 return getListed( manifest, OPTIONAL_EXTENSION_LIST ); 272 } 273 274 280 public static void addExtension( final Extension extension, 281 final Attributes attributes ) 282 { 283 addExtension( extension, "", attributes ); 284 } 285 286 295 public static void addExtension( final Extension extension, 296 final String prefix, 297 final Attributes attributes ) 298 { 299 attributes.putValue( prefix + EXTENSION_NAME, 300 extension.getExtensionName() ); 301 final String specificationVendor = extension.getSpecificationVendor(); 302 if( null != specificationVendor ) 303 { 304 attributes.putValue( prefix + SPECIFICATION_VENDOR, 305 specificationVendor ); 306 } 307 final DeweyDecimal specificationVersion = extension.getSpecificationVersion(); 308 if( null != specificationVersion ) 309 { 310 attributes.putValue( prefix + SPECIFICATION_VERSION, 311 specificationVersion.toString() ); 312 } 313 final String implementationVendorID = extension.getImplementationVendorID(); 314 if( null != implementationVendorID ) 315 { 316 attributes.putValue( prefix + IMPLEMENTATION_VENDOR_ID, 317 implementationVendorID ); 318 } 319 final String implementationVendor = extension.getImplementationVendor(); 320 if( null != implementationVendor ) 321 { 322 attributes.putValue( prefix + IMPLEMENTATION_VENDOR, 323 implementationVendor ); 324 } 325 final String implementationVersion = extension.getImplementationVersion(); 326 if( null != implementationVersion ) 327 { 328 attributes.putValue( prefix + IMPLEMENTATION_VERSION, 329 implementationVersion.toString() ); 330 } 331 final String implementationURL = extension.getImplementationURL(); 332 if( null != implementationURL ) 333 { 334 attributes.putValue( prefix + IMPLEMENTATION_URL, 335 implementationURL ); 336 } 337 } 338 339 351 public Extension( final String extensionName, 352 final String specificationVersion, 353 final String specificationVendor, 354 final String implementationVersion, 355 final String implementationVendor, 356 final String implementationVendorId, 357 final String implementationURL ) 358 { 359 if( null == extensionName ) 360 { 361 throw new NullPointerException ( "extensionName" ); 362 } 363 m_extensionName = extensionName; 364 m_specificationVendor = specificationVendor; 365 if( null != specificationVersion ) 366 { 367 try 368 { 369 m_specificationVersion = 370 new DeweyDecimal( specificationVersion ); 371 } 372 catch( final NumberFormatException nfe ) 373 { 374 final String error = "Bad specification version format '" + 375 specificationVersion + 376 "' in '" + extensionName + "'. (Reason: " + nfe + ")"; 377 throw new IllegalArgumentException ( error ); 378 } 379 } 380 m_implementationURL = implementationURL; 381 m_implementationVendor = implementationVendor; 382 m_implementationVendorID = implementationVendorId; 383 m_implementationVersion = implementationVersion; 384 } 385 386 391 public String getExtensionName() 392 { 393 return m_extensionName; 394 } 395 396 401 public String getSpecificationVendor() 402 { 403 return m_specificationVendor; 404 } 405 406 411 public DeweyDecimal getSpecificationVersion() 412 { 413 return m_specificationVersion; 414 } 415 416 421 public String getImplementationURL() 422 { 423 return m_implementationURL; 424 } 425 426 431 public String getImplementationVendor() 432 { 433 return m_implementationVendor; 434 } 435 436 441 public String getImplementationVendorID() 442 { 443 return m_implementationVendorID; 444 } 445 446 451 public String getImplementationVersion() 452 { 453 return m_implementationVersion; 454 } 455 456 464 public Compatability getCompatibilityWith( final Extension required ) 465 { 466 if( !m_extensionName.equals( required.getExtensionName() ) ) 468 { 469 return INCOMPATIBLE; 470 } 471 final DeweyDecimal specificationVersion = required.getSpecificationVersion(); 473 if( null != specificationVersion ) 474 { 475 if( null == m_specificationVersion || 476 !isCompatible( m_specificationVersion, specificationVersion ) ) 477 { 478 return REQUIRE_SPECIFICATION_UPGRADE; 479 } 480 } 481 final String implementationVendorId = required.getImplementationVendorID(); 483 if( null != implementationVendorId ) 484 { 485 if( null == m_implementationVendorID || 486 !m_implementationVendorID.equals( implementationVendorId ) ) 487 { 488 return REQUIRE_VENDOR_SWITCH; 489 } 490 } 491 492 return COMPATIBLE; 494 } 495 496 506 public boolean isCompatibleWith( final Extension required ) 507 { 508 return ( COMPATIBLE == getCompatibilityWith( required ) ); 509 } 510 511 516 public String toString() 517 { 518 final String lineSeparator = System.getProperty( "line.separator" ); 519 final String brace = ": "; 520 final StringBuffer sb = new StringBuffer ( EXTENSION_NAME.toString() ); 521 sb.append( brace ); 522 sb.append( m_extensionName ); 523 sb.append( lineSeparator ); 524 if( null != m_specificationVersion ) 525 { 526 sb.append( SPECIFICATION_VERSION ); 527 sb.append( brace ); 528 sb.append( m_specificationVersion ); 529 sb.append( lineSeparator ); 530 } 531 if( null != m_specificationVendor ) 532 { 533 sb.append( SPECIFICATION_VENDOR ); 534 sb.append( brace ); 535 sb.append( m_specificationVendor ); 536 sb.append( lineSeparator ); 537 } 538 if( null != m_implementationVersion ) 539 { 540 sb.append( IMPLEMENTATION_VERSION ); 541 sb.append( brace ); 542 sb.append( m_implementationVersion ); 543 sb.append( lineSeparator ); 544 } 545 if( null != m_implementationVendorID ) 546 { 547 sb.append( IMPLEMENTATION_VENDOR_ID ); 548 sb.append( brace ); 549 sb.append( m_implementationVendorID ); 550 sb.append( lineSeparator ); 551 } 552 if( null != m_implementationVendor ) 553 { 554 sb.append( IMPLEMENTATION_VENDOR ); 555 sb.append( brace ); 556 sb.append( m_implementationVendor ); 557 sb.append( lineSeparator ); 558 } 559 if( null != m_implementationURL ) 560 { 561 sb.append( IMPLEMENTATION_URL ); 562 sb.append( brace ); 563 sb.append( m_implementationURL ); 564 sb.append( lineSeparator ); 565 } 566 return sb.toString(); 567 } 568 569 576 private boolean isCompatible( final DeweyDecimal first, 577 final DeweyDecimal second ) 578 { 579 return first.isGreaterThanOrEqual( second ); 580 } 581 582 591 private static Extension[] getListed( final Manifest manifest, 592 final Attributes.Name listKey ) 593 { 594 final ArrayList results = new ArrayList (); 595 final Attributes mainAttributes = manifest.getMainAttributes(); 596 if( null != mainAttributes ) 597 { 598 getExtension( mainAttributes, results, listKey ); 599 } 600 final Map entries = manifest.getEntries(); 601 final Iterator keys = entries.keySet().iterator(); 602 while( keys.hasNext() ) 603 { 604 final String key = (String )keys.next(); 605 final Attributes attributes = (Attributes )entries.get( key ); 606 getExtension( attributes, results, listKey ); 607 } 608 return (Extension[])results.toArray( new Extension[ 0 ] ); 609 } 610 611 620 private static void getExtension( final Attributes attributes, 621 final ArrayList required, 622 final Attributes.Name listKey ) 623 { 624 final String names = attributes.getValue( listKey ); 625 if( null == names ) 626 { 627 return; 628 } 629 final String [] extentions = split( names, " " ); 630 for( int i = 0; i < extentions.length; i++ ) 631 { 632 final String prefix = extentions[ i ] + "-"; 633 final Extension extension = getExtension( prefix, attributes ); 634 if( null != extension ) 635 { 636 required.add( extension ); 637 } 638 } 639 } 640 641 648 private static final String [] split( final String string, 649 final String onToken ) 650 { 651 final StringTokenizer tokenizer = new StringTokenizer ( string, 652 onToken ); 653 final String [] result = new String [ tokenizer.countTokens() ]; 654 for( int i = 0; i < result.length; i++ ) 655 { 656 result[ i ] = tokenizer.nextToken(); 657 } 658 return result; 659 } 660 661 671 private static Extension getExtension( final String prefix, 672 final Attributes attributes ) 673 { 674 final String nameKey = prefix + EXTENSION_NAME; 678 final String name = getTrimmedString( attributes.getValue( nameKey ) ); 679 if( null == name ) 680 { 681 return null; 682 } 683 final String specVendorKey = prefix + SPECIFICATION_VENDOR; 684 final String specVendor = getTrimmedString( 685 attributes.getValue( specVendorKey ) ); 686 final String specVersionKey = prefix + SPECIFICATION_VERSION; 687 final String specVersion = getTrimmedString( 688 attributes.getValue( specVersionKey ) ); 689 final String impVersionKey = prefix + IMPLEMENTATION_VERSION; 690 final String impVersion = getTrimmedString( 691 attributes.getValue( impVersionKey ) ); 692 final String impVendorKey = prefix + IMPLEMENTATION_VENDOR; 693 final String impVendor = getTrimmedString( 694 attributes.getValue( impVendorKey ) ); 695 final String impVendorIDKey = prefix + IMPLEMENTATION_VENDOR_ID; 696 final String impVendorId = getTrimmedString( 697 attributes.getValue( impVendorIDKey ) ); 698 final String impURLKey = prefix + IMPLEMENTATION_URL; 699 final String impURL = getTrimmedString( 700 attributes.getValue( impURLKey ) ); 701 return new Extension( name, specVersion, specVendor, impVersion, 702 impVendor, impVendorId, impURL ); 703 } 704 705 711 private static String getTrimmedString( final String value ) 712 { 713 if( null == value ) 714 { 715 return null; 716 } 717 else 718 { 719 return value.trim(); 720 } 721 } 722 } 723 | Popular Tags |