1 17 18 package org.apache.avalon.extension; 19 20 import java.util.ArrayList ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 import java.util.StringTokenizer ; 24 import java.util.jar.Attributes ; 25 import java.util.jar.Manifest ; 26 27 40 public final class Extension 41 { 42 46 public static final Attributes.Name EXTENSION_LIST = Attributes.Name.EXTENSION_LIST; 47 48 58 public static final Attributes.Name OPTIONAL_EXTENSION_LIST = 59 new Attributes.Name ( "Optional-Extension-List" ); 60 61 65 public static final Attributes.Name EXTENSION_NAME = 66 Attributes.Name.EXTENSION_NAME; 67 68 72 public static final Attributes.Name SPECIFICATION_VERSION = 73 Attributes.Name.SPECIFICATION_VERSION; 74 75 79 public static final Attributes.Name SPECIFICATION_VENDOR = 80 Attributes.Name.SPECIFICATION_VENDOR; 81 82 86 public static final Attributes.Name IMPLEMENTATION_VERSION = 87 Attributes.Name.IMPLEMENTATION_VERSION; 88 89 93 public static final Attributes.Name IMPLEMENTATION_VENDOR = 94 Attributes.Name.IMPLEMENTATION_VENDOR; 95 96 100 public static final Attributes.Name IMPLEMENTATION_URL = 101 Attributes.Name.IMPLEMENTATION_URL; 102 103 107 public static final Attributes.Name IMPLEMENTATION_VENDOR_ID = 108 Attributes.Name.IMPLEMENTATION_VENDOR_ID; 109 110 113 public static final Compatability COMPATIBLE = 114 new Compatability( "COMPATIBLE" ); 115 116 120 public static final Compatability REQUIRE_SPECIFICATION_UPGRADE = 121 new Compatability( "REQUIRE_SPECIFICATION_UPGRADE" ); 122 123 127 public static final Compatability REQUIRE_VENDOR_SWITCH = 128 new Compatability( "REQUIRE_VENDOR_SWITCH" ); 129 130 134 public static final Compatability REQUIRE_IMPLEMENTATION_UPGRADE = 135 new Compatability( "REQUIRE_IMPLEMENTATION_UPGRADE" ); 136 137 143 public static final Compatability INCOMPATIBLE = 144 new Compatability( "INCOMPATIBLE" ); 145 146 149 private String m_extensionName; 150 151 155 private DeweyDecimal m_specificationVersion; 156 157 161 private String m_specificationVendor; 162 163 167 private String m_implementationVendorID; 168 169 173 private String m_implementationVendor; 174 175 179 private String m_implementationVersion; 180 181 185 private String m_implementationURL; 186 187 196 public static Extension[] getAvailable( final Manifest manifest ) 197 { 198 if( null == manifest ) 199 { 200 return new Extension[ 0 ]; 201 } 202 203 final ArrayList results = new ArrayList (); 204 205 final Attributes mainAttributes = manifest.getMainAttributes(); 206 if( null != mainAttributes ) 207 { 208 final Extension extension = getExtension( "", mainAttributes ); 209 if( null != extension ) 210 { 211 results.add( extension ); 212 } 213 } 214 215 final Map entries = manifest.getEntries(); 216 final Iterator keys = entries.keySet().iterator(); 217 while( keys.hasNext() ) 218 { 219 final String key = (String )keys.next(); 220 final Attributes attributes = (Attributes )entries.get( key ); 221 final Extension extension = getExtension( "", attributes ); 222 if( null != extension ) 223 { 224 results.add( extension ); 225 } 226 } 227 228 return (Extension[])results.toArray( new Extension[ results.size() ] ); 229 } 230 231 239 public static Extension[] getAvailable( final Manifest [] manifests ) 240 { 241 final ArrayList set = new ArrayList (); 242 243 for( int i = 0; i < manifests.length; i++ ) 244 { 245 final Extension[] extensions = getAvailable( manifests[ i ] ); 246 for( int j = 0; j < extensions.length; j++ ) 247 { 248 set.add( extensions[ j ] ); 249 } 250 } 251 252 return (Extension[])set.toArray( new Extension[ set.size() ] ); 253 } 254 255 264 public static Extension[] getRequired( final Manifest manifest ) 265 { 266 return getListed( manifest, EXTENSION_LIST ); 267 } 268 269 277 public static Extension[] getRequired( final Manifest [] manifests ) 278 { 279 final ArrayList set = new ArrayList (); 280 281 for( int i = 0; i < manifests.length; i++ ) 282 { 283 final Extension[] extensions = getRequired( manifests[ i ] ); 284 for( int j = 0; j < extensions.length; j++ ) 285 { 286 set.add( extensions[ j ] ); 287 } 288 } 289 290 return (Extension[])set.toArray( new Extension[ set.size() ] ); 291 } 292 293 301 public static Extension[] getOptions( final Manifest manifest ) 302 { 303 return getListed( manifest, OPTIONAL_EXTENSION_LIST ); 304 } 305 306 312 public static void addExtension( final Extension extension, 313 final Attributes attributes ) 314 { 315 addExtension( extension, "", attributes ); 316 } 317 318 327 public static void addExtension( final Extension extension, 328 final String prefix, 329 final Attributes attributes ) 330 { 331 attributes.putValue( prefix + EXTENSION_NAME, 332 extension.getExtensionName() ); 333 334 final String specificationVendor = extension.getSpecificationVendor(); 335 if( null != specificationVendor ) 336 { 337 attributes.putValue( prefix + SPECIFICATION_VENDOR, 338 specificationVendor ); 339 } 340 341 final DeweyDecimal specificationVersion = extension.getSpecificationVersion(); 342 if( null != specificationVersion ) 343 { 344 attributes.putValue( prefix + SPECIFICATION_VERSION, 345 specificationVersion.toString() ); 346 } 347 348 final String implementationVendorID = extension.getImplementationVendorID(); 349 if( null != implementationVendorID ) 350 { 351 attributes.putValue( prefix + IMPLEMENTATION_VENDOR_ID, 352 implementationVendorID ); 353 } 354 355 final String implementationVendor = extension.getImplementationVendor(); 356 if( null != implementationVendor ) 357 { 358 attributes.putValue( prefix + IMPLEMENTATION_VENDOR, 359 implementationVendor ); 360 } 361 362 final String implementationVersion = extension.getImplementationVersion(); 363 if( null != implementationVersion ) 364 { 365 attributes.putValue( prefix + IMPLEMENTATION_VERSION, 366 implementationVersion.toString() ); 367 } 368 369 final String implementationURL = extension.getImplementationURL(); 370 if( null != implementationURL ) 371 { 372 attributes.putValue( prefix + IMPLEMENTATION_URL, 373 implementationURL ); 374 } 375 } 376 377 390 public Extension( final String extensionName, 391 final String specificationVersion, 392 final String specificationVendor, 393 final String implementationVersion, 394 final String implementationVendor, 395 final String implementationVendorId, 396 final String implementationURL ) 397 { 398 m_extensionName = extensionName; 399 m_specificationVendor = specificationVendor; 400 401 if( null != specificationVersion ) 402 { 403 try 404 { 405 m_specificationVersion = new DeweyDecimal( specificationVersion ); 406 } 407 catch( final NumberFormatException nfe ) 408 { 409 414 } 419 } 420 421 m_implementationURL = implementationURL; 422 m_implementationVendor = implementationVendor; 423 m_implementationVendorID = implementationVendorId; 424 m_implementationVersion = implementationVersion; 425 426 if( null == m_extensionName ) 427 { 428 throw new NullPointerException ( "extensionName property is null" ); 429 } 430 } 431 432 437 public String getExtensionName() 438 { 439 return m_extensionName; 440 } 441 442 447 public String getSpecificationVendor() 448 { 449 return m_specificationVendor; 450 } 451 452 457 public DeweyDecimal getSpecificationVersion() 458 { 459 return m_specificationVersion; 460 } 461 462 467 public String getImplementationURL() 468 { 469 return m_implementationURL; 470 } 471 472 477 public String getImplementationVendor() 478 { 479 return m_implementationVendor; 480 } 481 482 487 public String getImplementationVendorID() 488 { 489 return m_implementationVendorID; 490 } 491 492 497 public String getImplementationVersion() 498 { 499 return m_implementationVersion; 500 } 501 502 510 public Compatability getCompatibilityWith( final Extension required ) 511 { 512 if( !m_extensionName.equals( required.getExtensionName() ) ) 514 { 515 return INCOMPATIBLE; 516 } 517 518 final DeweyDecimal specificationVersion = required.getSpecificationVersion(); 520 if( null != specificationVersion ) 521 { 522 if( null == m_specificationVersion || 523 !isCompatible( m_specificationVersion, specificationVersion ) ) 524 { 525 return REQUIRE_SPECIFICATION_UPGRADE; 526 } 527 } 528 529 final String implementationVendorId = required.getImplementationVendorID(); 531 if( null != implementationVendorId ) 532 { 533 if( null == m_implementationVendorID || 534 !m_implementationVendorID.equals( implementationVendorId ) ) 535 { 536 return REQUIRE_VENDOR_SWITCH; 537 } 538 } 539 540 541 return COMPATIBLE; 543 } 544 545 555 public boolean isCompatibleWith( final Extension required ) 556 { 557 return ( COMPATIBLE == getCompatibilityWith( required ) ); 558 } 559 560 565 public String toString() 566 { 567 final String lineSeparator = System.getProperty( "line.separator" ); 568 final String brace = ": "; 569 570 final StringBuffer sb = new StringBuffer ( EXTENSION_NAME.toString() ); 571 sb.append( brace ); 572 sb.append( m_extensionName ); 573 sb.append( lineSeparator ); 574 575 if( null != m_specificationVersion ) 576 { 577 sb.append( SPECIFICATION_VERSION ); 578 sb.append( brace ); 579 sb.append( m_specificationVersion ); 580 sb.append( lineSeparator ); 581 } 582 583 if( null != m_specificationVendor ) 584 { 585 sb.append( SPECIFICATION_VENDOR ); 586 sb.append( brace ); 587 sb.append( m_specificationVendor ); 588 sb.append( lineSeparator ); 589 } 590 591 if( null != m_implementationVersion ) 592 { 593 sb.append( IMPLEMENTATION_VERSION ); 594 sb.append( brace ); 595 sb.append( m_implementationVersion ); 596 sb.append( lineSeparator ); 597 } 598 599 if( null != m_implementationVendorID ) 600 { 601 sb.append( IMPLEMENTATION_VENDOR_ID ); 602 sb.append( brace ); 603 sb.append( m_implementationVendorID ); 604 sb.append( lineSeparator ); 605 } 606 607 if( null != m_implementationVendor ) 608 { 609 sb.append( IMPLEMENTATION_VENDOR ); 610 sb.append( brace ); 611 sb.append( m_implementationVendor ); 612 sb.append( lineSeparator ); 613 } 614 615 if( null != m_implementationURL ) 616 { 617 sb.append( IMPLEMENTATION_URL ); 618 sb.append( brace ); 619 sb.append( m_implementationURL ); 620 sb.append( lineSeparator ); 621 } 622 623 return sb.toString(); 624 } 625 626 633 private boolean isCompatible( final DeweyDecimal first, final DeweyDecimal second ) 634 { 635 return first.isGreaterThanOrEqual( second ); 636 } 637 638 647 private static Extension[] getListed( final Manifest manifest, 648 final Attributes.Name listKey ) 649 { 650 if( null == manifest ) 651 return new Extension[0]; 652 653 final ArrayList results = new ArrayList (); 654 final Attributes mainAttributes = manifest.getMainAttributes(); 655 656 if( null != mainAttributes ) 657 { 658 getExtension( mainAttributes, results, listKey ); 659 } 660 661 final Map entries = manifest.getEntries(); 662 final Iterator keys = entries.keySet().iterator(); 663 while( keys.hasNext() ) 664 { 665 final String key = (String )keys.next(); 666 final Attributes attributes = (Attributes )entries.get( key ); 667 getExtension( attributes, results, listKey ); 668 } 669 670 return (Extension[])results.toArray( new Extension[ 0 ] ); 671 } 672 673 681 private static void getExtension( final Attributes attributes, 682 final ArrayList required, 683 final Attributes.Name listKey ) 684 { 685 final String names = attributes.getValue( listKey ); 686 if( null == names ) 687 { 688 return; 689 } 690 691 final String [] extentions = split( names, " " ); 692 for( int i = 0; i < extentions.length; i++ ) 693 { 694 final String prefix = extentions[ i ] + "-"; 695 final Extension extension = getExtension( prefix, attributes ); 696 697 if( null != extension ) 698 { 699 required.add( extension ); 700 } 701 } 702 } 703 704 711 private static final String [] split( final String string, final String onToken ) 712 { 713 final StringTokenizer tokenizer = new StringTokenizer ( string, onToken ); 714 final String [] result = new String [ tokenizer.countTokens() ]; 715 716 for( int i = 0; i < result.length; i++ ) 717 { 718 result[ i ] = tokenizer.nextToken(); 719 } 720 721 return result; 722 } 723 724 735 private static Extension getExtension( final String prefix, final Attributes attributes ) 736 { 737 final String nameKey = prefix + EXTENSION_NAME; 741 final String name = getTrimmedString( attributes.getValue( nameKey ) ); 742 if( null == name ) 743 { 744 return null; 745 } 746 747 final String specVendorKey = prefix + SPECIFICATION_VENDOR; 748 final String specVendor = getTrimmedString( attributes.getValue( specVendorKey ) ); 749 final String specVersionKey = prefix + SPECIFICATION_VERSION; 750 final String specVersion = getTrimmedString( attributes.getValue( specVersionKey ) ); 751 752 final String impVersionKey = prefix + IMPLEMENTATION_VERSION; 753 final String impVersion = getTrimmedString( attributes.getValue( impVersionKey ) ); 754 final String impVendorKey = prefix + IMPLEMENTATION_VENDOR; 755 final String impVendor = getTrimmedString( attributes.getValue( impVendorKey ) ); 756 final String impVendorIDKey = prefix + IMPLEMENTATION_VENDOR_ID; 757 final String impVendorId = getTrimmedString( attributes.getValue( impVendorIDKey ) ); 758 final String impURLKey = prefix + IMPLEMENTATION_URL; 759 final String impURL = getTrimmedString( attributes.getValue( impURLKey ) ); 760 761 return new Extension( name, specVersion, specVendor, impVersion, 762 impVendor, impVendorId, impURL ); 763 } 764 765 771 private static String getTrimmedString( final String value ) 772 { 773 if( null == value ) 774 { 775 return null; 776 } 777 else 778 { 779 return value.replace('"', ' ').trim(); 780 } 781 } 782 } 783 | Popular Tags |