|
|||||||||||||||||||
| 30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
| Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
| Extension.java | 0% | 0% | 0% | 0% |
|
||||||||||||||
| 1 |
/*
|
|
| 2 |
* Copyright (C) The Spice Group. All rights reserved.
|
|
| 3 |
*
|
|
| 4 |
* This software is published under the terms of the Spice
|
|
| 5 |
* Software License version 1.1, a copy of which has been included
|
|
| 6 |
* with this distribution in the LICENSE.txt file.
|
|
| 7 |
*
|
|
| 8 |
* This product includes software developed by the
|
|
| 9 |
* Apache Software Foundation (http://www.apache.org/).
|
|
| 10 |
*/
|
|
| 11 |
package org.codehaus.spice.extension;
|
|
| 12 |
import java.util.ArrayList;
|
|
| 13 |
import java.util.Iterator;
|
|
| 14 |
import java.util.Map;
|
|
| 15 |
import java.util.StringTokenizer;
|
|
| 16 |
import java.util.jar.Attributes;
|
|
| 17 |
import java.util.jar.Manifest;
|
|
| 18 |
/**
|
|
| 19 |
* <p>Utility class that represents either an available "Optional Package"
|
|
| 20 |
* (formerly known as "Standard Extension") as described in the manifest
|
|
| 21 |
* of a JAR file, or the requirement for such an optional package.</p>
|
|
| 22 |
*
|
|
| 23 |
* <p>For more information about optional packages, see the document
|
|
| 24 |
* <em>Optional Package Versioning</em> in the documentation bundle for your
|
|
| 25 |
* Java2 Standard Edition package, in file
|
|
| 26 |
* <code>guide/extensions/versioning.html</code>.</p>
|
|
| 27 |
*
|
|
| 28 |
* @author <a href="mailto:craigmcc at apache.org">Craig R. McClanahan</a>
|
|
| 29 |
* @author <a href="mailto:peter at realityforge.org">Peter Donald</a>
|
|
| 30 |
* @version $Revision: 1.1 $ $Date: 2003/12/02 07:56:59 $
|
|
| 31 |
*/
|
|
| 32 |
public final class Extension |
|
| 33 |
{
|
|
| 34 |
/**
|
|
| 35 |
* Manifest Attribute Name object for EXTENSION_LIST.
|
|
| 36 |
* @see Attributes.Name#EXTENSION_LIST
|
|
| 37 |
*/
|
|
| 38 |
public static final Attributes.Name EXTENSION_LIST = Attributes.Name.EXTENSION_LIST; |
|
| 39 |
/**
|
|
| 40 |
* <code>Name</code> object for <code>Optional-Extension-List</code>
|
|
| 41 |
* manifest attribute used for declaring optional dependencies on
|
|
| 42 |
* installed extensions. Note that the dependencies declared by this method
|
|
| 43 |
* are not required for the library to operate but if present will be used.
|
|
| 44 |
* It is NOT part of the official "Optional Package" specification.
|
|
| 45 |
*
|
|
| 46 |
* @see <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/spec.html#dependnecy">
|
|
| 47 |
* Installed extension dependency</a>
|
|
| 48 |
*/
|
|
| 49 |
public static final Attributes.Name OPTIONAL_EXTENSION_LIST = |
|
| 50 |
new Attributes.Name( "Optional-Extension-List" ); |
|
| 51 |
/**
|
|
| 52 |
* Manifest Attribute Name object for EXTENSION_NAME.
|
|
| 53 |
* @see Attributes.Name#EXTENSION_NAME
|
|
| 54 |
*/
|
|
| 55 |
public static final Attributes.Name EXTENSION_NAME = |
|
| 56 |
Attributes.Name.EXTENSION_NAME; |
|
| 57 |
/**
|
|
| 58 |
* Manifest Attribute Name object for SPECIFICATION_VERSION.
|
|
| 59 |
* @see Attributes.Name#SPECIFICATION_VERSION
|
|
| 60 |
*/
|
|
| 61 |
public static final Attributes.Name SPECIFICATION_VERSION = |
|
| 62 |
Attributes.Name.SPECIFICATION_VERSION; |
|
| 63 |
/**
|
|
| 64 |
* Manifest Attribute Name object for SPECIFICATION_VENDOR.
|
|
| 65 |
* @see Attributes.Name#SPECIFICATION_VENDOR
|
|
| 66 |
*/
|
|
| 67 |
public static final Attributes.Name SPECIFICATION_VENDOR = |
|
| 68 |
Attributes.Name.SPECIFICATION_VENDOR; |
|
| 69 |
/**
|
|
| 70 |
* Manifest Attribute Name object for IMPLEMENTATION_VERSION.
|
|
| 71 |
* @see Attributes.Name#IMPLEMENTATION_VERSION
|
|
| 72 |
*/
|
|
| 73 |
public static final Attributes.Name IMPLEMENTATION_VERSION = |
|
| 74 |
Attributes.Name.IMPLEMENTATION_VERSION; |
|
| 75 |
/**
|
|
| 76 |
* Manifest Attribute Name object for IMPLEMENTATION_VENDOR.
|
|
| 77 |
* @see Attributes.Name#IMPLEMENTATION_VENDOR
|
|
| 78 |
*/
|
|
| 79 |
public static final Attributes.Name IMPLEMENTATION_VENDOR = |
|
| 80 |
Attributes.Name.IMPLEMENTATION_VENDOR; |
|
| 81 |
/**
|
|
| 82 |
* Manifest Attribute Name object for IMPLEMENTATION_URL.
|
|
| 83 |
* @see Attributes.Name#IMPLEMENTATION_URL
|
|
| 84 |
*/
|
|
| 85 |
public static final Attributes.Name IMPLEMENTATION_URL = |
|
| 86 |
Attributes.Name.IMPLEMENTATION_URL; |
|
| 87 |
/**
|
|
| 88 |
* Manifest Attribute Name object for IMPLEMENTATION_VENDOR_ID.
|
|
| 89 |
* @see Attributes.Name#IMPLEMENTATION_VENDOR_ID
|
|
| 90 |
*/
|
|
| 91 |
public static final Attributes.Name IMPLEMENTATION_VENDOR_ID = |
|
| 92 |
Attributes.Name.IMPLEMENTATION_VENDOR_ID; |
|
| 93 |
/**
|
|
| 94 |
* Enum indicating that extension is compatible with other extension.
|
|
| 95 |
*/
|
|
| 96 |
public static final Compatability COMPATIBLE = |
|
| 97 |
new Compatability( "COMPATIBLE" ); |
|
| 98 |
/**
|
|
| 99 |
* Enum indicating that extension requires an upgrade
|
|
| 100 |
* of specification to be compatible with other extension.
|
|
| 101 |
*/
|
|
| 102 |
public static final Compatability REQUIRE_SPECIFICATION_UPGRADE = |
|
| 103 |
new Compatability( "REQUIRE_SPECIFICATION_UPGRADE" ); |
|
| 104 |
/**
|
|
| 105 |
* Enum indicating that extension requires a vendor
|
|
| 106 |
* switch to be compatible with other extension.
|
|
| 107 |
*/
|
|
| 108 |
public static final Compatability REQUIRE_VENDOR_SWITCH = |
|
| 109 |
new Compatability( "REQUIRE_VENDOR_SWITCH" ); |
|
| 110 |
/**
|
|
| 111 |
* Enum indicating that extension requires an upgrade
|
|
| 112 |
* of implementation to be compatible with other extension.
|
|
| 113 |
*/
|
|
| 114 |
public static final Compatability REQUIRE_IMPLEMENTATION_UPGRADE = |
|
| 115 |
new Compatability( "REQUIRE_IMPLEMENTATION_UPGRADE" ); |
|
| 116 |
/**
|
|
| 117 |
* Enum indicating that extension is incompatible with
|
|
| 118 |
* other extension in ways other than other enums
|
|
| 119 |
* indicate). ie For example the other extension may have
|
|
| 120 |
* a different ID.
|
|
| 121 |
*/
|
|
| 122 |
public static final Compatability INCOMPATIBLE = |
|
| 123 |
new Compatability( "INCOMPATIBLE" ); |
|
| 124 |
/**
|
|
| 125 |
* The name of the optional package being made available, or required.
|
|
| 126 |
*/
|
|
| 127 |
private String m_extensionName;
|
|
| 128 |
/**
|
|
| 129 |
* The version number (dotted decimal notation) of the specification
|
|
| 130 |
* to which this optional package conforms.
|
|
| 131 |
*/
|
|
| 132 |
private DeweyDecimal m_specificationVersion;
|
|
| 133 |
/**
|
|
| 134 |
* The name of the company or organization that originated the
|
|
| 135 |
* specification to which this optional package conforms.
|
|
| 136 |
*/
|
|
| 137 |
private String m_specificationVendor;
|
|
| 138 |
/**
|
|
| 139 |
* The unique identifier of the company that produced the optional
|
|
| 140 |
* package contained in this JAR file.
|
|
| 141 |
*/
|
|
| 142 |
private String m_implementationVendorID;
|
|
| 143 |
/**
|
|
| 144 |
* The name of the company or organization that produced this
|
|
| 145 |
* implementation of this optional package.
|
|
| 146 |
*/
|
|
| 147 |
private String m_implementationVendor;
|
|
| 148 |
/**
|
|
| 149 |
* The version number (dotted decimal notation) for this implementation
|
|
| 150 |
* of the optional package.
|
|
| 151 |
*/
|
|
| 152 |
private String m_implementationVersion;
|
|
| 153 |
/**
|
|
| 154 |
* The URL from which the most recent version of this optional package
|
|
| 155 |
* can be obtained if it is not already installed.
|
|
| 156 |
*/
|
|
| 157 |
private String m_implementationURL;
|
|
| 158 |
/**
|
|
| 159 |
* Return an array of <code>Extension</code> objects representing optional
|
|
| 160 |
* packages that are available in the JAR file associated with the
|
|
| 161 |
* specified <code>Manifest</code>. If there are no such optional
|
|
| 162 |
* packages, a zero-length array is returned.
|
|
| 163 |
*
|
|
| 164 |
* @param manifest Manifest to be parsed
|
|
| 165 |
* @return the "available" extensions in specified manifest
|
|
| 166 |
*/
|
|
| 167 | 0 |
public static Extension[] getAvailable( final Manifest manifest ) |
| 168 |
{
|
|
| 169 | 0 |
if( null == manifest ) |
| 170 |
{
|
|
| 171 | 0 |
return new Extension[ 0 ]; |
| 172 |
} |
|
| 173 | 0 |
final ArrayList results = new ArrayList();
|
| 174 | 0 |
final Attributes mainAttributes = manifest.getMainAttributes(); |
| 175 | 0 |
if( null != mainAttributes ) |
| 176 |
{
|
|
| 177 | 0 |
final Extension extension = getExtension( "", mainAttributes );
|
| 178 | 0 |
if( null != extension ) |
| 179 |
{
|
|
| 180 | 0 |
results.add( extension ); |
| 181 |
} |
|
| 182 |
} |
|
| 183 | 0 |
final Map entries = manifest.getEntries(); |
| 184 | 0 |
final Iterator keys = entries.keySet().iterator(); |
| 185 | 0 |
while( keys.hasNext() )
|
| 186 |
{
|
|
| 187 | 0 |
final String key = (String)keys.next(); |
| 188 | 0 |
final Attributes attributes = (Attributes)entries.get( key ); |
| 189 | 0 |
final Extension extension = getExtension( "", attributes );
|
| 190 | 0 |
if( null != extension ) |
| 191 |
{
|
|
| 192 | 0 |
results.add( extension ); |
| 193 |
} |
|
| 194 |
} |
|
| 195 | 0 |
return (Extension[])results.toArray( new Extension[ results.size() ] ); |
| 196 |
} |
|
| 197 |
/**
|
|
| 198 |
* Retrieve the set of <code>Extension</code> objects that are available
|
|
| 199 |
* by the specified Manifest objects. If there are no such optional
|
|
| 200 |
* packages, a zero-length list is returned.
|
|
| 201 |
*
|
|
| 202 |
* @param manifests the manifests to scan
|
|
| 203 |
* @return the extensions
|
|
| 204 |
*/
|
|
| 205 | 0 |
public static Extension[] getAvailable( final Manifest[] manifests ) |
| 206 |
{
|
|
| 207 | 0 |
final ArrayList set = new ArrayList();
|
| 208 | 0 |
for( int i = 0; i < manifests.length; i++ ) |
| 209 |
{
|
|
| 210 | 0 |
final Extension[] extensions = getAvailable( manifests[ i ] ); |
| 211 | 0 |
for( int j = 0; j < extensions.length; j++ ) |
| 212 |
{
|
|
| 213 | 0 |
set.add( extensions[ j ] ); |
| 214 |
} |
|
| 215 |
} |
|
| 216 | 0 |
return (Extension[])set.toArray( new Extension[ set.size() ] ); |
| 217 |
} |
|
| 218 |
/**
|
|
| 219 |
* Return the set of <code>Extension</code> objects representing optional
|
|
| 220 |
* packages that are required by the application contained in the JAR
|
|
| 221 |
* file associated with the specified <code>Manifest</code>. If there
|
|
| 222 |
* are no such optional packages, a zero-length list is returned.
|
|
| 223 |
*
|
|
| 224 |
* @param manifest Manifest to be parsed
|
|
| 225 |
* @return the dependencies that are specified in manifes
|
|
| 226 |
*/
|
|
| 227 | 0 |
public static Extension[] getRequired( final Manifest manifest ) |
| 228 |
{
|
|
| 229 | 0 |
return getListed( manifest, EXTENSION_LIST );
|
| 230 |
} |
|
| 231 |
/**
|
|
| 232 |
* Retrieve the set of <code>Extension</code> objects that are required
|
|
| 233 |
* by the specified Manifest objects. If there are no such optional
|
|
| 234 |
* packages, a zero-length list is returned.
|
|
| 235 |
*
|
|
| 236 |
* @param manifests the manifests to scan
|
|
| 237 |
* @return the extensions
|
|
| 238 |
*/
|
|
| 239 | 0 |
public static Extension[] getRequired( final Manifest[] manifests ) |
| 240 |
{
|
|
| 241 | 0 |
final ArrayList set = new ArrayList();
|
| 242 | 0 |
for( int i = 0; i < manifests.length; i++ ) |
| 243 |
{
|
|
| 244 | 0 |
final Extension[] extensions = getRequired( manifests[ i ] ); |
| 245 | 0 |
for( int j = 0; j < extensions.length; j++ ) |
| 246 |
{
|
|
| 247 | 0 |
set.add( extensions[ j ] ); |
| 248 |
} |
|
| 249 |
} |
|
| 250 | 0 |
return (Extension[])set.toArray( new Extension[ set.size() ] ); |
| 251 |
} |
|
| 252 |
/**
|
|
| 253 |
* Return the set of <code>Extension</code> objects representing "Optional
|
|
| 254 |
* Packages" that the application declares they will use if present. If
|
|
| 255 |
* there are no such optional packages, a zero-length list is returned.
|
|
| 256 |
*
|
|
| 257 |
* @param manifest Manifest to be parsed
|
|
| 258 |
* @return the optional dependencies that are specified in manifest
|
|
| 259 |
*/
|
|
| 260 | 0 |
public static Extension[] getOptions( final Manifest manifest ) |
| 261 |
{
|
|
| 262 | 0 |
return getListed( manifest, OPTIONAL_EXTENSION_LIST );
|
| 263 |
} |
|
| 264 |
/**
|
|
| 265 |
* Add Extension to the specified manifest Attributes.
|
|
| 266 |
*
|
|
| 267 |
* @param attributes the attributes of manifest to add to
|
|
| 268 |
* @param extension the extension
|
|
| 269 |
*/
|
|
| 270 | 0 |
public static void addExtension( final Extension extension, |
| 271 |
final Attributes attributes ) |
|
| 272 |
{
|
|
| 273 | 0 |
addExtension( extension, "", attributes );
|
| 274 |
} |
|
| 275 |
/**
|
|
| 276 |
* Add Extension to the specified manifest Attributes.
|
|
| 277 |
* Use the specified prefix so that dependencies can added
|
|
| 278 |
* with a prefix such as "java3d-" etc.
|
|
| 279 |
*
|
|
| 280 |
* @param attributes the attributes of manifest to add to
|
|
| 281 |
* @param extension the extension
|
|
| 282 |
* @param prefix the name to prefix to extension
|
|
| 283 |
*/
|
|
| 284 | 0 |
public static void addExtension( final Extension extension, |
| 285 |
final String prefix, |
|
| 286 |
final Attributes attributes ) |
|
| 287 |
{
|
|
| 288 | 0 |
attributes.putValue( prefix + EXTENSION_NAME, |
| 289 |
extension.getExtensionName() ); |
|
| 290 | 0 |
final String specificationVendor = extension.getSpecificationVendor(); |
| 291 | 0 |
if( null != specificationVendor ) |
| 292 |
{
|
|
| 293 | 0 |
attributes.putValue( prefix + SPECIFICATION_VENDOR, |
| 294 |
specificationVendor ); |
|
| 295 |
} |
|
| 296 | 0 |
final DeweyDecimal specificationVersion = extension.getSpecificationVersion(); |
| 297 | 0 |
if( null != specificationVersion ) |
| 298 |
{
|
|
| 299 | 0 |
attributes.putValue( prefix + SPECIFICATION_VERSION, |
| 300 |
specificationVersion.toString() ); |
|
| 301 |
} |
|
| 302 | 0 |
final String implementationVendorID = extension.getImplementationVendorID(); |
| 303 | 0 |
if( null != implementationVendorID ) |
| 304 |
{
|
|
| 305 | 0 |
attributes.putValue( prefix + IMPLEMENTATION_VENDOR_ID, |
| 306 |
implementationVendorID ); |
|
| 307 |
} |
|
| 308 | 0 |
final String implementationVendor = extension.getImplementationVendor(); |
| 309 | 0 |
if( null != implementationVendor ) |
| 310 |
{
|
|
| 311 | 0 |
attributes.putValue( prefix + IMPLEMENTATION_VENDOR, |
| 312 |
implementationVendor ); |
|
| 313 |
} |
|
| 314 | 0 |
final String implementationVersion = extension.getImplementationVersion(); |
| 315 | 0 |
if( null != implementationVersion ) |
| 316 |
{
|
|
| 317 | 0 |
attributes.putValue( prefix + IMPLEMENTATION_VERSION, |
| 318 |
implementationVersion.toString() ); |
|
| 319 |
} |
|
| 320 | 0 |
final String implementationURL = extension.getImplementationURL(); |
| 321 | 0 |
if( null != implementationURL ) |
| 322 |
{
|
|
| 323 | 0 |
attributes.putValue( prefix + IMPLEMENTATION_URL, |
| 324 |
implementationURL ); |
|
| 325 |
} |
|
| 326 |
} |
|
| 327 |
/**
|
|
| 328 |
* The constructor to create Extension object.
|
|
| 329 |
* Note that every component is allowed to be specified
|
|
| 330 |
* but only the extensionName is mandatory.
|
|
| 331 |
*
|
|
| 332 |
* @param extensionName the name of extension.
|
|
| 333 |
* @param specificationVersion the specification Version of extension.
|
|
| 334 |
* @param specificationVendor the specification Vendor of extension.
|
|
| 335 |
* @param implementationVersion the implementation Version of extension.
|
|
| 336 |
* @param implementationVendor the implementation Vendor of extension.
|
|
| 337 |
* @param implementationVendorId the implementation VendorId of extension.
|
|
| 338 |
* @param implementationURL the implementation URL of extension.
|
|
| 339 |
*/
|
|
| 340 | 0 |
public Extension( final String extensionName,
|
| 341 |
final String specificationVersion, |
|
| 342 |
final String specificationVendor, |
|
| 343 |
final String implementationVersion, |
|
| 344 |
final String implementationVendor, |
|
| 345 |
final String implementationVendorId, |
|
| 346 |
final String implementationURL ) |
|
| 347 |
{
|
|
| 348 | 0 |
if( null == extensionName ) |
| 349 |
{
|
|
| 350 | 0 |
throw new NullPointerException( "extensionName" ); |
| 351 |
} |
|
| 352 | 0 |
m_extensionName = extensionName; |
| 353 | 0 |
m_specificationVendor = specificationVendor; |
| 354 | 0 |
if( null != specificationVersion ) |
| 355 |
{
|
|
| 356 | 0 |
try
|
| 357 |
{
|
|
| 358 | 0 |
m_specificationVersion = new DeweyDecimal( specificationVersion );
|
| 359 |
} |
|
| 360 |
catch( final NumberFormatException nfe )
|
|
| 361 |
{
|
|
| 362 | 0 |
final String error = "Bad specification version format '" + specificationVersion +
|
| 363 |
"' in '" + extensionName + "'. (Reason: " + nfe + ")"; |
|
| 364 | 0 |
throw new IllegalArgumentException( error ); |
| 365 |
} |
|
| 366 |
} |
|
| 367 | 0 |
m_implementationURL = implementationURL; |
| 368 | 0 |
m_implementationVendor = implementationVendor; |
| 369 | 0 |
m_implementationVendorID = implementationVendorId; |
| 370 | 0 |
m_implementationVersion = implementationVersion; |
| 371 |
} |
|
| 372 |
/**
|
|
| 373 |
* Get the name of the extension.
|
|
| 374 |
*
|
|
| 375 |
* @return the name of the extension
|
|
| 376 |
*/
|
|
| 377 | 0 |
public String getExtensionName()
|
| 378 |
{
|
|
| 379 | 0 |
return m_extensionName;
|
| 380 |
} |
|
| 381 |
/**
|
|
| 382 |
* Get the vendor of the extensions specification.
|
|
| 383 |
*
|
|
| 384 |
* @return the vendor of the extensions specification.
|
|
| 385 |
*/
|
|
| 386 | 0 |
public String getSpecificationVendor()
|
| 387 |
{
|
|
| 388 | 0 |
return m_specificationVendor;
|
| 389 |
} |
|
| 390 |
/**
|
|
| 391 |
* Get the version of the extensions specification.
|
|
| 392 |
*
|
|
| 393 |
* @return the version of the extensions specification.
|
|
| 394 |
*/
|
|
| 395 | 0 |
public DeweyDecimal getSpecificationVersion()
|
| 396 |
{
|
|
| 397 | 0 |
return m_specificationVersion;
|
| 398 |
} |
|
| 399 |
/**
|
|
| 400 |
* Get the url of the extensions implementation.
|
|
| 401 |
*
|
|
| 402 |
* @return the url of the extensions implementation.
|
|
| 403 |
*/
|
|
| 404 | 0 |
public String getImplementationURL()
|
| 405 |
{
|
|
| 406 | 0 |
return m_implementationURL;
|
| 407 |
} |
|
| 408 |
/**
|
|
| 409 |
* Get the vendor of the extensions implementation.
|
|
| 410 |
*
|
|
| 411 |
* @return the vendor of the extensions implementation.
|
|
| 412 |
*/
|
|
| 413 | 0 |
public String getImplementationVendor()
|
| 414 |
{
|
|
| 415 | 0 |
return m_implementationVendor;
|
| 416 |
} |
|
| 417 |
/**
|
|
| 418 |
* Get the vendorID of the extensions implementation.
|
|
| 419 |
*
|
|
| 420 |
* @return the vendorID of the extensions implementation.
|
|
| 421 |
*/
|
|
| 422 | 0 |
public String getImplementationVendorID()
|
| 423 |
{
|
|
| 424 | 0 |
return m_implementationVendorID;
|
| 425 |
} |
|
| 426 |
/**
|
|
| 427 |
* Get the version of the extensions implementation.
|
|
| 428 |
*
|
|
| 429 |
* @return the version of the extensions implementation.
|
|
| 430 |
*/
|
|
| 431 | 0 |
public String getImplementationVersion()
|
| 432 |
{
|
|
| 433 | 0 |
return m_implementationVersion;
|
| 434 |
} |
|
| 435 |
/**
|
|
| 436 |
* Return a Compatibility enum indicating the relationship of this
|
|
| 437 |
* <code>Extension</code> with the specified <code>Extension</code>.
|
|
| 438 |
*
|
|
| 439 |
* @param required Description of the required optional package
|
|
| 440 |
* @return the enum indicating the compatability (or lack thereof)
|
|
| 441 |
* of specifed extension
|
|
| 442 |
*/
|
|
| 443 | 0 |
public Compatability getCompatibilityWith( final Extension required )
|
| 444 |
{
|
|
| 445 |
// Extension Name must match
|
|
| 446 | 0 |
if( !m_extensionName.equals( required.getExtensionName() ) )
|
| 447 |
{
|
|
| 448 | 0 |
return INCOMPATIBLE;
|
| 449 |
} |
|
| 450 |
// Available specification version must be >= required
|
|
| 451 | 0 |
final DeweyDecimal specificationVersion = required.getSpecificationVersion(); |
| 452 | 0 |
if( null != specificationVersion ) |
| 453 |
{
|
|
| 454 | 0 |
if( null == m_specificationVersion || |
| 455 |
!isCompatible( m_specificationVersion, specificationVersion ) ) |
|
| 456 |
{
|
|
| 457 | 0 |
return REQUIRE_SPECIFICATION_UPGRADE;
|
| 458 |
} |
|
| 459 |
} |
|
| 460 |
// Implementation Vendor ID must match
|
|
| 461 | 0 |
final String implementationVendorId = required.getImplementationVendorID(); |
| 462 | 0 |
if( null != implementationVendorId ) |
| 463 |
{
|
|
| 464 | 0 |
if( null == m_implementationVendorID || |
| 465 |
!m_implementationVendorID.equals( implementationVendorId ) ) |
|
| 466 |
{
|
|
| 467 | 0 |
return REQUIRE_VENDOR_SWITCH;
|
| 468 |
} |
|
| 469 |
} |
|
| 470 |
|
|
| 471 |
// This available optional package satisfies the requirements
|
|
| 472 | 0 |
return COMPATIBLE;
|
| 473 |
} |
|
| 474 |
/**
|
|
| 475 |
* Return <code>true</code> if the specified <code>Extension</code>
|
|
| 476 |
* (which represents an optional package required by an application)
|
|
| 477 |
* is satisfied by this <code>Extension</code> (which represents an
|
|
| 478 |
* optional package that is already installed. Otherwise, return
|
|
| 479 |
* <code>false</code>.
|
|
| 480 |
*
|
|
| 481 |
* @param required Description of the required optional package
|
|
| 482 |
* @return true if the specified extension is compatible with this extension
|
|
| 483 |
*/
|
|
| 484 | 0 |
public boolean isCompatibleWith( final Extension required ) |
| 485 |
{
|
|
| 486 | 0 |
return ( COMPATIBLE == getCompatibilityWith( required ) );
|
| 487 |
} |
|
| 488 |
/**
|
|
| 489 |
* Return a String representation of this object.
|
|
| 490 |
*
|
|
| 491 |
* @return string representation of object.
|
|
| 492 |
*/
|
|
| 493 | 0 |
public String toString()
|
| 494 |
{
|
|
| 495 | 0 |
final String lineSeparator = System.getProperty( "line.separator" );
|
| 496 | 0 |
final String brace = ": ";
|
| 497 | 0 |
final StringBuffer sb = new StringBuffer( EXTENSION_NAME.toString() );
|
| 498 | 0 |
sb.append( brace ); |
| 499 | 0 |
sb.append( m_extensionName ); |
| 500 | 0 |
sb.append( lineSeparator ); |
| 501 | 0 |
if( null != m_specificationVersion ) |
| 502 |
{
|
|
| 503 | 0 |
sb.append( SPECIFICATION_VERSION ); |
| 504 | 0 |
sb.append( brace ); |
| 505 | 0 |
sb.append( m_specificationVersion ); |
| 506 | 0 |
sb.append( lineSeparator ); |
| 507 |
} |
|
| 508 | 0 |
if( null != m_specificationVendor ) |
| 509 |
{
|
|
| 510 | 0 |
sb.append( SPECIFICATION_VENDOR ); |
| 511 | 0 |
sb.append( brace ); |
| 512 | 0 |
sb.append( m_specificationVendor ); |
| 513 | 0 |
sb.append( lineSeparator ); |
| 514 |
} |
|
| 515 | 0 |
if( null != m_implementationVersion ) |
| 516 |
{
|
|
| 517 | 0 |
sb.append( IMPLEMENTATION_VERSION ); |
| 518 | 0 |
sb.append( brace ); |
| 519 | 0 |
sb.append( m_implementationVersion ); |
| 520 | 0 |
sb.append( lineSeparator ); |
| 521 |
} |
|
| 522 | 0 |
if( null != m_implementationVendorID ) |
| 523 |
{
|
|
| 524 | 0 |
sb.append( IMPLEMENTATION_VENDOR_ID ); |
| 525 | 0 |
sb.append( brace ); |
| 526 | 0 |
sb.append( m_implementationVendorID ); |
| 527 | 0 |
sb.append( lineSeparator ); |
| 528 |
} |
|
| 529 | 0 |
if( null != m_implementationVendor ) |
| 530 |
{
|
|
| 531 | 0 |
sb.append( IMPLEMENTATION_VENDOR ); |
| 532 | 0 |
sb.append( brace ); |
| 533 | 0 |
sb.append( m_implementationVendor ); |
| 534 | 0 |
sb.append( lineSeparator ); |
| 535 |
} |
|
| 536 | 0 |
if( null != m_implementationURL ) |
| 537 |
{
|
|
| 538 | 0 |
sb.append( IMPLEMENTATION_URL ); |
| 539 | 0 |
sb.append( brace ); |
| 540 | 0 |
sb.append( m_implementationURL ); |
| 541 | 0 |
sb.append( lineSeparator ); |
| 542 |
} |
|
| 543 | 0 |
return sb.toString();
|
| 544 |
} |
|
| 545 |
/**
|
|
| 546 |
* Return <code>true</code> if the first version number is greater than
|
|
| 547 |
* or equal to the second; otherwise return <code>false</code>.
|
|
| 548 |
*
|
|
| 549 |
* @param first First version number (dotted decimal)
|
|
| 550 |
* @param second Second version number (dotted decimal)
|
|
| 551 |
*/
|
|
| 552 | 0 |
private boolean isCompatible( final DeweyDecimal first, final DeweyDecimal second ) |
| 553 |
{
|
|
| 554 | 0 |
return first.isGreaterThanOrEqual( second );
|
| 555 |
} |
|
| 556 |
/**
|
|
| 557 |
* Retrieve all the extensions listed under a particular key
|
|
| 558 |
* (Usually EXTENSION_LIST or OPTIONAL_EXTENSION_LIST).
|
|
| 559 |
*
|
|
| 560 |
* @param manifest the manifest to extract extensions from
|
|
| 561 |
* @param listKey the key used to get list (Usually
|
|
| 562 |
* EXTENSION_LIST or OPTIONAL_EXTENSION_LIST)
|
|
| 563 |
* @return the list of listed extensions
|
|
| 564 |
*/
|
|
| 565 | 0 |
private static Extension[] getListed( final Manifest manifest, |
| 566 |
final Attributes.Name listKey ) |
|
| 567 |
{
|
|
| 568 | 0 |
final ArrayList results = new ArrayList();
|
| 569 | 0 |
final Attributes mainAttributes = manifest.getMainAttributes(); |
| 570 | 0 |
if( null != mainAttributes ) |
| 571 |
{
|
|
| 572 | 0 |
getExtension( mainAttributes, results, listKey ); |
| 573 |
} |
|
| 574 | 0 |
final Map entries = manifest.getEntries(); |
| 575 | 0 |
final Iterator keys = entries.keySet().iterator(); |
| 576 | 0 |
while( keys.hasNext() )
|
| 577 |
{
|
|
| 578 | 0 |
final String key = (String)keys.next(); |
| 579 | 0 |
final Attributes attributes = (Attributes)entries.get( key ); |
| 580 | 0 |
getExtension( attributes, results, listKey ); |
| 581 |
} |
|
| 582 | 0 |
return (Extension[])results.toArray( new Extension[ 0 ] ); |
| 583 |
} |
|
| 584 |
/**
|
|
| 585 |
* Add required optional packages defined in the specified attributes entry, if any.
|
|
| 586 |
*
|
|
| 587 |
* @param attributes Attributes to be parsed
|
|
| 588 |
* @param required list to add required optional packages to
|
|
| 589 |
* @param listKey the key to use to lookup list, usually EXTENSION_LIST
|
|
| 590 |
* or OPTIONAL_EXTENSION_LIST
|
|
| 591 |
*/
|
|
| 592 | 0 |
private static void getExtension( final Attributes attributes, |
| 593 |
final ArrayList required, |
|
| 594 |
final Attributes.Name listKey ) |
|
| 595 |
{
|
|
| 596 | 0 |
final String names = attributes.getValue( listKey ); |
| 597 | 0 |
if( null == names ) |
| 598 |
{
|
|
| 599 | 0 |
return;
|
| 600 |
} |
|
| 601 | 0 |
final String[] extentions = split( names, " " );
|
| 602 | 0 |
for( int i = 0; i < extentions.length; i++ ) |
| 603 |
{
|
|
| 604 | 0 |
final String prefix = extentions[ i ] + "-";
|
| 605 | 0 |
final Extension extension = getExtension( prefix, attributes ); |
| 606 | 0 |
if( null != extension ) |
| 607 |
{
|
|
| 608 | 0 |
required.add( extension ); |
| 609 |
} |
|
| 610 |
} |
|
| 611 |
} |
|
| 612 |
/**
|
|
| 613 |
* Splits the string on every token into an array of strings.
|
|
| 614 |
*
|
|
| 615 |
* @param string the string
|
|
| 616 |
* @param onToken the token
|
|
| 617 |
* @return the resultant array
|
|
| 618 |
*/
|
|
| 619 | 0 |
private static final String[] split( final String string, final String onToken ) |
| 620 |
{
|
|
| 621 | 0 |
final StringTokenizer tokenizer = new StringTokenizer( string, onToken );
|
| 622 | 0 |
final String[] result = new String[ tokenizer.countTokens() ];
|
| 623 | 0 |
for( int i = 0; i < result.length; i++ ) |
| 624 |
{
|
|
| 625 | 0 |
result[ i ] = tokenizer.nextToken(); |
| 626 |
} |
|
| 627 | 0 |
return result;
|
| 628 |
} |
|
| 629 |
/**
|
|
| 630 |
* Extract an Extension from Attributes.
|
|
| 631 |
* Prefix indicates the prefix checked for each string.
|
|
| 632 |
* Usually the prefix is <em>"<extension>-"</em> if looking for a
|
|
| 633 |
* <b>Required</b> extension. If you are looking for an <b>Available</b> extension
|
|
| 634 |
* then the prefix is <em>""</em>.
|
|
| 635 |
*
|
|
| 636 |
* @param prefix the prefix for each attribute name
|
|
| 637 |
* @param attributes Attributes to searched
|
|
| 638 |
* @return the new Extension object, or null
|
|
| 639 |
*/
|
|
| 640 | 0 |
private static Extension getExtension( final String prefix, final Attributes attributes ) |
| 641 |
{
|
|
| 642 |
//WARNING: We trim the values of all the attributes because
|
|
| 643 |
//Some extension declarations are badly defined (ie have spaces
|
|
| 644 |
//after version or vendorID)
|
|
| 645 | 0 |
final String nameKey = prefix + EXTENSION_NAME; |
| 646 | 0 |
final String name = getTrimmedString( attributes.getValue( nameKey ) ); |
| 647 | 0 |
if( null == name ) |
| 648 |
{
|
|
| 649 | 0 |
return null; |
| 650 |
} |
|
| 651 | 0 |
final String specVendorKey = prefix + SPECIFICATION_VENDOR; |
| 652 | 0 |
final String specVendor = getTrimmedString( attributes.getValue( specVendorKey ) ); |
| 653 | 0 |
final String specVersionKey = prefix + SPECIFICATION_VERSION; |
| 654 | 0 |
final String specVersion = getTrimmedString( attributes.getValue( specVersionKey ) ); |
| 655 | 0 |
final String impVersionKey = prefix + IMPLEMENTATION_VERSION; |
| 656 | 0 |
final String impVersion = getTrimmedString( attributes.getValue( impVersionKey ) ); |
| 657 | 0 |
final String impVendorKey = prefix + IMPLEMENTATION_VENDOR; |
| 658 | 0 |
final String impVendor = getTrimmedString( attributes.getValue( impVendorKey ) ); |
| 659 | 0 |
final String impVendorIDKey = prefix + IMPLEMENTATION_VENDOR_ID; |
| 660 | 0 |
final String impVendorId = getTrimmedString( attributes.getValue( impVendorIDKey ) ); |
| 661 | 0 |
final String impURLKey = prefix + IMPLEMENTATION_URL; |
| 662 | 0 |
final String impURL = getTrimmedString( attributes.getValue( impURLKey ) ); |
| 663 | 0 |
return new Extension( name, specVersion, specVendor, impVersion, |
| 664 |
impVendor, impVendorId, impURL ); |
|
| 665 |
} |
|
| 666 |
/**
|
|
| 667 |
* Trim the supplied string if the string is non-null
|
|
| 668 |
*
|
|
| 669 |
* @param value the string to trim or null
|
|
| 670 |
* @return the trimmed string or null
|
|
| 671 |
*/
|
|
| 672 | 0 |
private static String getTrimmedString( final String value ) |
| 673 |
{
|
|
| 674 | 0 |
if( null == value ) |
| 675 |
{
|
|
| 676 | 0 |
return null; |
| 677 |
} |
|
| 678 |
else
|
|
| 679 |
{
|
|
| 680 | 0 |
return value.trim();
|
| 681 |
} |
|
| 682 |
} |
|
| 683 |
} |
|
| 684 |
|
|
||||||||||