1 8 package org.apache.avalon.excalibur.extension; 9 10 import java.util.ArrayList ; 11 import java.util.Iterator ; 12 import java.util.List ; 13 import java.util.Map ; 14 import java.util.StringTokenizer ; 15 import java.util.jar.Attributes.Name; 16 import java.util.jar.Attributes ; 17 import java.util.jar.Manifest ; 18 import org.apache.avalon.excalibur.util.DeweyDecimal; 19 import org.apache.avalon.excalibur.util.StringUtil; 20 21 35 public final class Extension 36 { 37 public static final Compatability COMPATIBLE = 38 new Compatability( "COMPATIBLE" ); 39 public static final Compatability REQUIRE_SPECIFICATION_UPGRADE = 40 new Compatability( "REQUIRE_SPECIFICATION_UPGRADE" ); 41 public static final Compatability REQUIRE_VENDOR_SWITCH = 42 new Compatability( "REQUIRE_VENDOR_SWITCH" ); 43 public static final Compatability REQUIRE_IMPLEMENTATION_UPGRADE = 44 new Compatability( "REQUIRE_IMPLEMENTATION_UPGRADE" ); 45 public static final Compatability INCOMPATIBLE = 46 new Compatability( "INCOMPATIBLE" ); 47 48 51 private String m_extensionName; 52 53 57 private DeweyDecimal m_specificationVersion; 58 59 63 private String m_specificationVendor; 64 65 69 private String m_implementationURL; 70 71 75 private String m_implementationVendor; 76 77 81 private String m_implementationVendorId; 82 83 87 private DeweyDecimal m_implementationVersion; 88 89 90 98 public static Extension[] getAvailable( final Manifest manifest ) 99 { 100 if( null == manifest ) return new Extension[ 0 ]; 101 102 final ArrayList results = new ArrayList (); 103 104 final Attributes mainAttributes = manifest.getMainAttributes(); 105 if( null != mainAttributes ) 106 { 107 final Extension extension = getExtension( "", mainAttributes ); 108 if( null != extension ) results.add( extension ); 109 } 110 111 final Map entries = manifest.getEntries(); 112 final Iterator keys = entries.keySet().iterator(); 113 while( keys.hasNext() ) 114 { 115 final String key = (String )keys.next(); 116 final Attributes attributes = (Attributes )entries.get( key ); 117 final Extension extension = getExtension( "", attributes ); 118 if( null != extension ) results.add( extension ); 119 } 120 121 return (Extension[])results.toArray( new Extension[ 0 ] ); 122 } 123 124 132 public static Extension[] getRequired( final Manifest manifest ) 133 { 134 final ArrayList results = new ArrayList (); 135 final Attributes mainAttributes = manifest.getMainAttributes(); 136 137 if( null != mainAttributes ) 138 { 139 getRequired( mainAttributes, results ); 140 } 141 142 final Map entries = manifest.getEntries(); 143 final Iterator keys = entries.keySet().iterator(); 144 while( keys.hasNext() ) 145 { 146 final String key = (String )keys.next(); 147 final Attributes attributes = (Attributes )entries.get( key ); 148 getRequired( mainAttributes, results ); 149 } 150 151 return (Extension[])results.toArray( new Extension[ 0 ] ); 152 } 153 154 160 private static void getRequired( final Attributes attributes, 161 final ArrayList required ) 162 { 163 final String names = attributes.getValue( Name.EXTENSION_LIST ); 164 if( null == names ) return; 165 166 final String [] extentions = StringUtil.split( names, " " ); 167 for( int i = 0; i < extentions.length; i++ ) 168 { 169 final String prefix = extentions[ i ] + "-"; 170 final Extension extension = getExtension( prefix, attributes ); 171 172 if( null != extension ) 173 { 174 required.add( extension ); 175 } 176 } 177 } 178 179 190 private static Extension getExtension( final String prefix, final Attributes attributes ) 191 { 192 final String name = getTrimmedString( attributes.getValue( prefix + Name.EXTENSION_NAME ) ); 196 if( null == name ) return null; 197 198 final String specVendor = 199 getTrimmedString( attributes.getValue( prefix + Name.SPECIFICATION_VENDOR ) ); 200 final String specVersion = 201 getTrimmedString( attributes.getValue( prefix + Name.SPECIFICATION_VERSION ) ); 202 203 final String impVersion = 204 getTrimmedString( attributes.getValue( prefix + Name.IMPLEMENTATION_VERSION ) ); 205 final String impVendor = 206 getTrimmedString( attributes.getValue( prefix + Name.IMPLEMENTATION_VENDOR ) ); 207 final String impVendorId = 208 getTrimmedString( attributes.getValue( prefix + Name.IMPLEMENTATION_VENDOR_ID ) ); 209 final String impURL = 210 getTrimmedString( attributes.getValue( prefix + Name.IMPLEMENTATION_URL ) ); 211 212 return new Extension( name, specVersion, specVendor, impVersion, 213 impVendor, impVendorId, impURL ); 214 } 215 216 private static String getTrimmedString( final String value ) 217 { 218 if( null == value ) return null; 219 else 220 { 221 return value.trim(); 222 } 223 } 224 225 238 public Extension( final String extensionName, 239 final String specificationVersion, 240 final String specificationVendor, 241 final String implementationVersion, 242 final String implementationVendor, 243 final String implementationVendorId, 244 final String implementationURL ) 245 { 246 m_extensionName = extensionName; 247 m_specificationVendor = specificationVendor; 248 249 if( null != specificationVersion ) 250 { 251 try 252 { 253 m_specificationVersion = new DeweyDecimal( specificationVersion ); 254 } 255 catch( NumberFormatException nfe ) 256 { 257 final String error = "Bad specification version format '" + specificationVersion + 258 "' in '" + extensionName + "'. (Reason: " + nfe + ")"; 259 throw new IllegalArgumentException ( error ); 260 } 261 } 262 263 m_implementationURL = implementationURL; 264 m_implementationVendor = implementationVendor; 265 m_implementationVendorId = implementationVendorId; 266 267 if( null != implementationVersion ) 268 { 269 try 270 { 271 m_implementationVersion = new DeweyDecimal( implementationVersion ); 272 } 273 catch( NumberFormatException nfe ) 274 { 275 final String error = "Bad implementation version format '" + implementationVersion + 276 "' in '" + extensionName + "'. (Reason: " + nfe + ")"; 277 throw new IllegalArgumentException ( error ); 278 } 279 } 280 281 if( null == m_extensionName ) 282 { 283 throw new NullPointerException ( "extensionName property is null" ); 284 } 285 } 286 287 public String getExtensionName() 288 { 289 return m_extensionName; 290 } 291 292 public String getSpecificationVendor() 293 { 294 return m_specificationVendor; 295 } 296 297 public DeweyDecimal getSpecificationVersion() 298 { 299 return m_specificationVersion; 300 } 301 302 public String getImplementationURL() 303 { 304 return m_implementationURL; 305 } 306 307 public String getImplementationVendor() 308 { 309 return m_implementationVendor; 310 } 311 312 public String getImplementationVendorId() 313 { 314 return m_implementationVendorId; 315 } 316 317 public DeweyDecimal getImplementationVersion() 318 { 319 return m_implementationVersion; 320 } 321 322 323 329 public Compatability getCompatibilityWith( final Extension required ) 330 { 331 if( false == m_extensionName.equals( required.getExtensionName() ) ) 333 { 334 return INCOMPATIBLE; 335 } 336 337 final DeweyDecimal specificationVersion = required.getSpecificationVersion(); 339 if( null != specificationVersion ) 340 { 341 if( null == m_specificationVersion || 342 false == isCompatible( m_specificationVersion, specificationVersion ) ) 343 { 344 return REQUIRE_SPECIFICATION_UPGRADE; 345 } 346 } 347 348 final String implementationVendorId = required.getImplementationVendorId(); 350 if( null != implementationVendorId ) 351 { 352 if( null == m_implementationVendorId || 353 false == m_implementationVendorId.equals( implementationVendorId ) ) 354 { 355 return REQUIRE_VENDOR_SWITCH; 356 } 357 } 358 359 final DeweyDecimal implementationVersion = required.getImplementationVersion(); 361 if( null != implementationVersion ) 362 { 363 if( null == m_implementationVersion || 364 false == isCompatible( m_implementationVersion, implementationVersion ) ) 365 { 366 return REQUIRE_IMPLEMENTATION_UPGRADE; 367 } 368 } 369 370 return COMPATIBLE; 372 } 373 374 383 public boolean isCompatibleWith( final Extension required ) 384 { 385 return ( COMPATIBLE == getCompatibilityWith( required ) ); 386 } 387 388 391 public String toString() 392 { 393 final StringBuffer sb = new StringBuffer ( "Extension[" ); 394 sb.append( m_extensionName ); 395 396 if( null != m_implementationURL ) 397 { 398 sb.append( ", implementationURL=" ); 399 sb.append( m_implementationURL ); 400 } 401 402 if( null != m_implementationVendor ) 403 { 404 sb.append( ", implementationVendor=" ); 405 sb.append( m_implementationVendor ); 406 } 407 408 if( null != m_implementationVendorId ) 409 { 410 sb.append( ", implementationVendorId=" ); 411 sb.append( m_implementationVendorId ); 412 } 413 414 if( null != m_implementationVersion ) 415 { 416 sb.append( ", implementationVersion=" ); 417 sb.append( m_implementationVersion ); 418 } 419 420 if( null != m_specificationVendor ) 421 { 422 sb.append( ", specificationVendor=" ); 423 sb.append( m_specificationVendor ); 424 } 425 426 if( null != m_specificationVersion ) 427 { 428 sb.append( ", specificationVersion=" ); 429 sb.append( m_specificationVersion ); 430 } 431 432 sb.append( "]" ); 433 434 return sb.toString(); 435 } 436 437 446 private boolean isCompatible( final DeweyDecimal first, final DeweyDecimal second ) 447 { 448 return first.isGreaterThanOrEqual( second ); 449 } 450 451 public static final class Compatability 452 { 453 private final String m_name; 454 455 protected Compatability( final String name ) 456 { 457 m_name = name; 458 } 459 460 public String toString() 461 { 462 return m_name; 463 } 464 } 465 } 466 | Popular Tags |