1 18 package org.apache.tools.ant.taskdefs.optional.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 import org.apache.tools.ant.util.StringUtils; 28 29 40 public final class Extension { 41 44 public static final Attributes.Name EXTENSION_LIST 45 = new Attributes.Name ("Extension-List"); 46 47 57 public static final Attributes.Name OPTIONAL_EXTENSION_LIST 58 = new Attributes.Name ("Optional-Extension-List"); 59 60 63 public static final Attributes.Name EXTENSION_NAME = 64 new Attributes.Name ("Extension-Name"); 65 68 public static final Attributes.Name SPECIFICATION_VERSION 69 = Attributes.Name.SPECIFICATION_VERSION; 70 71 74 public static final Attributes.Name SPECIFICATION_VENDOR 75 = Attributes.Name.SPECIFICATION_VENDOR; 76 77 80 public static final Attributes.Name IMPLEMENTATION_VERSION 81 = Attributes.Name.IMPLEMENTATION_VERSION; 82 83 86 public static final Attributes.Name IMPLEMENTATION_VENDOR 87 = Attributes.Name.IMPLEMENTATION_VENDOR; 88 89 92 public static final Attributes.Name IMPLEMENTATION_URL 93 = new Attributes.Name ("Implementation-URL"); 94 95 98 public static final Attributes.Name IMPLEMENTATION_VENDOR_ID 99 = new Attributes.Name ("Implementation-Vendor-Id"); 100 101 104 public static final Compatibility COMPATIBLE 105 = new Compatibility("COMPATIBLE"); 106 107 111 public static final Compatibility REQUIRE_SPECIFICATION_UPGRADE 112 = new Compatibility("REQUIRE_SPECIFICATION_UPGRADE"); 113 114 118 public static final Compatibility REQUIRE_VENDOR_SWITCH 119 = new Compatibility("REQUIRE_VENDOR_SWITCH"); 120 121 125 public static final Compatibility REQUIRE_IMPLEMENTATION_UPGRADE 126 = new Compatibility("REQUIRE_IMPLEMENTATION_UPGRADE"); 127 128 134 public static final Compatibility INCOMPATIBLE 135 = new Compatibility("INCOMPATIBLE"); 136 137 140 private String extensionName; 141 142 146 private DeweyDecimal specificationVersion; 147 148 152 private String specificationVendor; 153 154 158 private String implementationVendorID; 159 160 164 private String implementationVendor; 165 166 170 private DeweyDecimal implementationVersion; 171 172 176 private String implementationURL; 177 178 187 public static Extension[] getAvailable(final Manifest manifest) { 188 if (null == manifest) { 189 return new Extension[ 0 ]; 190 } 191 192 final ArrayList results = new ArrayList (); 193 194 final Attributes mainAttributes = manifest.getMainAttributes(); 195 if (null != mainAttributes) { 196 final Extension extension = getExtension("", mainAttributes); 197 if (null != extension) { 198 results.add(extension); 199 } 200 } 201 202 final Map entries = manifest.getEntries(); 203 final Iterator keys = entries.keySet().iterator(); 204 while (keys.hasNext()) { 205 final String key = (String ) keys.next(); 206 final Attributes attributes = (Attributes ) entries.get(key); 207 final Extension extension = getExtension("", attributes); 208 if (null != extension) { 209 results.add(extension); 210 } 211 } 212 213 return (Extension[]) results.toArray(new Extension[results.size()]); 214 } 215 216 225 public static Extension[] getRequired(final Manifest manifest) { 226 return getListed(manifest, Attributes.Name.EXTENSION_LIST); 227 } 228 229 237 public static Extension[] getOptions(final Manifest manifest) { 238 return getListed(manifest, OPTIONAL_EXTENSION_LIST); 239 } 240 241 247 public static void addExtension(final Extension extension, 248 final Attributes attributes) { 249 addExtension(extension, "", attributes); 250 } 251 252 261 public static void addExtension(final Extension extension, 262 final String prefix, 263 final Attributes attributes) { 264 attributes.putValue(prefix + EXTENSION_NAME, 265 extension.getExtensionName()); 266 267 final String specificationVendor = extension.getSpecificationVendor(); 268 if (null != specificationVendor) { 269 attributes.putValue(prefix + SPECIFICATION_VENDOR, 270 specificationVendor); 271 } 272 273 final DeweyDecimal specificationVersion 274 = extension.getSpecificationVersion(); 275 if (null != specificationVersion) { 276 attributes.putValue(prefix + SPECIFICATION_VERSION, 277 specificationVersion.toString()); 278 } 279 280 final String implementationVendorID 281 = extension.getImplementationVendorID(); 282 if (null != implementationVendorID) { 283 attributes.putValue(prefix + IMPLEMENTATION_VENDOR_ID, 284 implementationVendorID); 285 } 286 287 final String implementationVendor = extension.getImplementationVendor(); 288 if (null != implementationVendor) { 289 attributes.putValue(prefix + IMPLEMENTATION_VENDOR, 290 implementationVendor); 291 } 292 293 final DeweyDecimal implementationVersion 294 = extension.getImplementationVersion(); 295 if (null != implementationVersion) { 296 attributes.putValue(prefix + IMPLEMENTATION_VERSION, 297 implementationVersion.toString()); 298 } 299 300 final String implementationURL = extension.getImplementationURL(); 301 if (null != implementationURL) { 302 attributes.putValue(prefix + IMPLEMENTATION_URL, 303 implementationURL); 304 } 305 } 306 307 320 public Extension(final String extensionName, 321 final String specificationVersion, 322 final String specificationVendor, 323 final String implementationVersion, 324 final String implementationVendor, 325 final String implementationVendorId, 326 final String implementationURL) { 327 this.extensionName = extensionName; 328 this.specificationVendor = specificationVendor; 329 330 if (null != specificationVersion) { 331 try { 332 this.specificationVersion 333 = new DeweyDecimal(specificationVersion); 334 } catch (final NumberFormatException nfe) { 335 final String error = "Bad specification version format '" 336 + specificationVersion + "' in '" + extensionName 337 + "'. (Reason: " + nfe + ")"; 338 throw new IllegalArgumentException (error); 339 } 340 } 341 342 this.implementationURL = implementationURL; 343 this.implementationVendor = implementationVendor; 344 this.implementationVendorID = implementationVendorId; 345 346 if (null != implementationVersion) { 347 try { 348 this.implementationVersion 349 = new DeweyDecimal(implementationVersion); 350 } catch (final NumberFormatException nfe) { 351 final String error = "Bad implementation version format '" 352 + implementationVersion + "' in '" + extensionName 353 + "'. (Reason: " + nfe + ")"; 354 throw new IllegalArgumentException (error); 355 } 356 } 357 358 if (null == this.extensionName) { 359 throw new NullPointerException ("extensionName property is null"); 360 } 361 } 362 363 368 public String getExtensionName() { 369 return extensionName; 370 } 371 372 377 public String getSpecificationVendor() { 378 return specificationVendor; 379 } 380 381 386 public DeweyDecimal getSpecificationVersion() { 387 return specificationVersion; 388 } 389 390 395 public String getImplementationURL() { 396 return implementationURL; 397 } 398 399 404 public String getImplementationVendor() { 405 return implementationVendor; 406 } 407 408 413 public String getImplementationVendorID() { 414 return implementationVendorID; 415 } 416 417 422 public DeweyDecimal getImplementationVersion() { 423 return implementationVersion; 424 } 425 426 434 public Compatibility getCompatibilityWith(final Extension required) { 435 if (!extensionName.equals(required.getExtensionName())) { 437 return INCOMPATIBLE; 438 } 439 440 final DeweyDecimal requiredSpecificationVersion 442 = required.getSpecificationVersion(); 443 if (null != requiredSpecificationVersion) { 444 if (null == specificationVersion 445 || !isCompatible(specificationVersion, requiredSpecificationVersion)) { 446 return REQUIRE_SPECIFICATION_UPGRADE; 447 } 448 } 449 450 final String requiredImplementationVendorID 452 = required.getImplementationVendorID(); 453 if (null != requiredImplementationVendorID) { 454 if (null == implementationVendorID 455 || !implementationVendorID.equals(requiredImplementationVendorID)) { 456 return REQUIRE_VENDOR_SWITCH; 457 } 458 } 459 460 final DeweyDecimal requiredImplementationVersion 462 = required.getImplementationVersion(); 463 if (null != requiredImplementationVersion) { 464 if (null == implementationVersion 465 || !isCompatible(implementationVersion, requiredImplementationVersion)) { 466 return REQUIRE_IMPLEMENTATION_UPGRADE; 467 } 468 } 469 470 return COMPATIBLE; 472 } 473 474 484 public boolean isCompatibleWith(final Extension required) { 485 return (COMPATIBLE == getCompatibilityWith(required)); 486 } 487 488 493 public String toString() { 494 final String brace = ": "; 495 496 final StringBuffer sb = new StringBuffer (EXTENSION_NAME.toString()); 497 sb.append(brace); 498 sb.append(extensionName); 499 sb.append(StringUtils.LINE_SEP); 500 501 if (null != specificationVersion) { 502 sb.append(SPECIFICATION_VERSION); 503 sb.append(brace); 504 sb.append(specificationVersion); 505 sb.append(StringUtils.LINE_SEP); 506 } 507 508 if (null != specificationVendor) { 509 sb.append(SPECIFICATION_VENDOR); 510 sb.append(brace); 511 sb.append(specificationVendor); 512 sb.append(StringUtils.LINE_SEP); 513 } 514 515 if (null != implementationVersion) { 516 sb.append(IMPLEMENTATION_VERSION); 517 sb.append(brace); 518 sb.append(implementationVersion); 519 sb.append(StringUtils.LINE_SEP); 520 } 521 522 if (null != implementationVendorID) { 523 sb.append(IMPLEMENTATION_VENDOR_ID); 524 sb.append(brace); 525 sb.append(implementationVendorID); 526 sb.append(StringUtils.LINE_SEP); 527 } 528 529 if (null != implementationVendor) { 530 sb.append(IMPLEMENTATION_VENDOR); 531 sb.append(brace); 532 sb.append(implementationVendor); 533 sb.append(StringUtils.LINE_SEP); 534 } 535 536 if (null != implementationURL) { 537 sb.append(IMPLEMENTATION_URL); 538 sb.append(brace); 539 sb.append(implementationURL); 540 sb.append(StringUtils.LINE_SEP); 541 } 542 543 return sb.toString(); 544 } 545 546 553 private boolean isCompatible(final DeweyDecimal first, 554 final DeweyDecimal second) { 555 return first.isGreaterThanOrEqual(second); 556 } 557 558 567 private static Extension[] getListed(final Manifest manifest, 568 final Attributes.Name listKey) { 569 final ArrayList results = new ArrayList (); 570 final Attributes mainAttributes = manifest.getMainAttributes(); 571 572 if (null != mainAttributes) { 573 getExtension(mainAttributes, results, listKey); 574 } 575 576 final Map entries = manifest.getEntries(); 577 final Iterator keys = entries.keySet().iterator(); 578 while (keys.hasNext()) { 579 final String key = (String ) keys.next(); 580 final Attributes attributes = (Attributes ) entries.get(key); 581 getExtension(attributes, results, listKey); 582 } 583 584 return (Extension[]) results.toArray(new Extension[results.size()]); 585 } 586 587 596 private static void getExtension(final Attributes attributes, 597 final ArrayList required, 598 final Attributes.Name listKey) { 599 final String names = attributes.getValue(listKey); 600 if (null == names) { 601 return; 602 } 603 604 final String [] extentions = split(names, " "); 605 for (int i = 0; i < extentions.length; i++) { 606 final String prefix = extentions[ i ] + "-"; 607 final Extension extension = getExtension(prefix, attributes); 608 609 if (null != extension) { 610 required.add(extension); 611 } 612 } 613 } 614 615 622 private static String [] split(final String string, 623 final String onToken) { 624 final StringTokenizer tokenizer = new StringTokenizer (string, onToken); 625 final String [] result = new String [ tokenizer.countTokens() ]; 626 627 for (int i = 0; i < result.length; i++) { 628 result[ i ] = tokenizer.nextToken(); 629 } 630 631 return result; 632 } 633 634 646 private static Extension getExtension(final String prefix, 647 final Attributes attributes) { 648 final String nameKey = prefix + EXTENSION_NAME; 652 final String name = getTrimmedString(attributes.getValue(nameKey)); 653 if (null == name) { 654 return null; 655 } 656 657 final String specVendorKey = prefix + SPECIFICATION_VENDOR; 658 final String specVendor 659 = getTrimmedString(attributes.getValue(specVendorKey)); 660 final String specVersionKey = prefix + SPECIFICATION_VERSION; 661 final String specVersion 662 = getTrimmedString(attributes.getValue(specVersionKey)); 663 664 final String impVersionKey = prefix + IMPLEMENTATION_VERSION; 665 final String impVersion 666 = getTrimmedString(attributes.getValue(impVersionKey)); 667 final String impVendorKey = prefix + IMPLEMENTATION_VENDOR; 668 final String impVendor 669 = getTrimmedString(attributes.getValue(impVendorKey)); 670 final String impVendorIDKey = prefix + IMPLEMENTATION_VENDOR_ID; 671 final String impVendorId 672 = getTrimmedString(attributes.getValue(impVendorIDKey)); 673 final String impURLKey = prefix + IMPLEMENTATION_URL; 674 final String impURL = getTrimmedString(attributes.getValue(impURLKey)); 675 676 return new Extension(name, specVersion, specVendor, impVersion, 677 impVendor, impVendorId, impURL); 678 } 679 680 686 private static String getTrimmedString(final String value) { 687 return null == value ? null : value.trim(); 688 } 689 } 690 | Popular Tags |