|
|||||||||||||||||||
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 |
|
|