1 23 24 package com.sun.enterprise.appclient.jws; 25 26 import java.io.File ; 27 import java.io.FilenameFilter ; 28 import java.io.IOException ; 29 import java.util.Collection ; 30 import java.util.HashMap ; 31 import java.util.HashSet ; 32 import java.util.LinkedList ; 33 import java.util.List ; 34 import java.util.Map ; 35 import java.util.Set ; 36 import java.util.StringTokenizer ; 37 import java.util.Vector ; 38 import java.util.jar.Attributes ; 39 import java.util.jar.JarFile ; 40 import java.util.jar.Manifest ; 41 42 56 public class ExtensionFileManager { 57 58 59 private static final String EXT_DIRS_PROPERTY_NAME = "java.ext.dirs"; 60 61 65 private Map <ExtensionKey, Extension> extensionFileInfo = null; 66 67 68 private Vector <File > extensionFileDirs = null; 69 70 73 public ExtensionFileManager() throws IOException { 74 extensionFileDirs = buildExtensionFileDirs(); 75 extensionFileInfo = buildExtensionFileEntries(extensionFileDirs); 76 } 77 78 84 public Map <ExtensionKey, Extension> getExtensionFileEntries() throws IOException { 85 return extensionFileInfo; 86 } 87 88 92 private Vector <File > buildExtensionFileDirs() { 93 Vector <File > result = new Vector <File >(); 94 95 String extDirs = System.getProperty(EXT_DIRS_PROPERTY_NAME); 96 StringTokenizer stkn = new StringTokenizer (extDirs, File.pathSeparator); 97 98 while (stkn.hasMoreTokens()) { 99 String extensionDirPath = stkn.nextToken(); 100 result.add(new File (extensionDirPath)); 101 } 102 return result; 103 } 104 105 111 private Map <ExtensionKey, Extension> buildExtensionFileEntries(Vector <File > dirs) throws IOException { 112 113 118 Map <ExtensionKey,Extension> result = new HashMap <ExtensionKey,Extension>(); 119 120 for (int i = 0; i < dirs.size(); i++) { 121 addExtJarsFromDirectory(result, i, dirs.get(i)); 122 } 123 return result; 124 } 125 126 130 137 private void addExtJarsFromDirectory(Map <ExtensionKey, Extension> map, int extensionDirNumber, File extDir) throws IOException { 138 File [] extJars = extDir.listFiles(new FilenameFilter () { 139 public boolean accept(File dir, String name) { 140 return name.endsWith(".jar"); 141 } 142 }); 143 if (extJars != null) { 144 for (File file : extJars) { 145 Extension entry = buildExtensionForJar(file, extensionDirNumber); 146 if (entry != null) { 147 map.put(entry.extensionKey, entry); 148 } 149 } 150 } 151 } 152 153 160 private Extension buildExtensionForJar(File file, int extDirectoryNumber) throws IOException { 161 Extension result = null; 162 JarFile jarFile = null; 163 try { 164 jarFile = new JarFile (file); 165 ExtensionKey key = getDefinedExtensionKey(jarFile); 166 if (key != null) { 167 result = new Extension(key, file, extDirectoryNumber); 168 } 169 return result; 170 } finally { 171 if (jarFile != null) { 172 jarFile.close(); 173 } 174 } 175 } 176 177 189 public Set <Extension> findExtensionTransitiveClosure(File anchorDir, Attributes mainAttrs) throws IOException { 190 191 Set <Extension> result = new HashSet <Extension>(); 192 193 Vector <File > filesToProcess = new Vector <File >(); 194 195 filesToProcess.addAll(getClassPathJars(anchorDir, mainAttrs)); 196 197 Set <Extension> extensionsUsedByApp = getReferencedExtensions(mainAttrs); 198 result.addAll(extensionsUsedByApp); 199 filesToProcess.addAll(extensionsToFiles(extensionsUsedByApp)); 200 201 206 for (int i = 0; i < filesToProcess.size(); i++) { 207 File nextFile = filesToProcess.get(i); 208 212 if (nextFile.exists()) { 213 JarFile nextJarFile = new JarFile (nextFile); 214 try { 215 Attributes attrs = getMainAttrs(nextJarFile); 216 Set <Extension> newExtensions = getReferencedExtensions(attrs); 217 result.addAll(newExtensions); 218 filesToProcess.addAll(extensionsToFiles(newExtensions)); 219 } finally { 220 if (nextJarFile != null) { 221 nextJarFile.close(); 222 } 223 } 224 } 225 } 226 return result; 227 } 228 229 234 private Set <File > extensionsToFiles(Set <Extension> extensions) { 235 Set <File > result = new HashSet <File >(); 236 for (Extension e : extensions) { 237 result.add(e.file); 238 } 239 return result; 240 } 241 242 249 private Set <Extension> getReferencedExtensions(Attributes mainAttrs) throws IOException { 250 Set <Extension> result = new HashSet <Extension>(); 251 Set <ExtensionKey> extensionKeys = getReferencedExtensionKeys(mainAttrs); 252 253 for (ExtensionKey key : extensionKeys) { 254 if ( ! result.contains(key)) { 255 Extension extension = extensionFileInfo.get(key); 256 257 262 if (extension != null) { 263 result.add(extension); 264 } else { 265 throw new IOException ("Jar file requires the extension " + key + " but it is not in the known extensions " + extensionFileInfo); 266 } 267 } 268 } 269 return result; 270 } 271 272 278 private Attributes getMainAttrs(JarFile jarFile) throws IOException { 279 Attributes result = null; 280 281 Manifest mf = jarFile.getManifest(); 282 if (mf != null) { 283 result = mf.getMainAttributes(); 284 } 285 return result; 286 } 287 288 294 private List <File > getClassPathJars(File anchorDir, Attributes mainAttrs) { 295 List <File > result = new LinkedList <File >(); 296 String classPathList = mainAttrs.getValue(Attributes.Name.CLASS_PATH); 297 if (classPathList != null) { 298 StringTokenizer stkn = new StringTokenizer (classPathList, " "); 299 while (stkn.hasMoreTokens()) { 300 String classPathJarPath = stkn.nextToken(); 301 File classPathJarFile = new File (classPathJarPath); 302 if ( ! classPathJarFile.isAbsolute()) { 303 classPathJarFile = new File (anchorDir, classPathJarPath); 304 } 305 result.add(classPathJarFile); 306 } 307 } 308 return result; 309 } 310 311 317 private ExtensionKey getDefinedExtensionKey(JarFile jarFile) throws IOException { 318 ExtensionKey result = null; 319 320 Attributes mainAttrs = getMainAttrs(jarFile); 321 if (mainAttrs != null) { 322 String extName = mainAttrs.getValue(Attributes.Name.EXTENSION_NAME); 323 if (extName != null) { 324 String specVersion = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION); 325 ExtensionKey entryKey = new ExtensionKey(extName, specVersion); 326 result = new ExtensionKey(extName, specVersion); 327 } 328 } 329 330 return result; 331 } 332 333 338 private Set <ExtensionKey> getReferencedExtensionKeys(Attributes mainAttrs) { 339 Set <ExtensionKey> result = new HashSet <ExtensionKey>(); 340 341 if (mainAttrs != null) { 342 String extensionList = mainAttrs.getValue(Attributes.Name.EXTENSION_LIST); 343 if (extensionList != null) { 344 StringTokenizer stkn = new StringTokenizer (extensionList, " "); 345 while (stkn.hasMoreTokens()) { 346 350 String token = stkn.nextToken().trim(); 351 String extName = mainAttrs.getValue(token + "-" + Attributes.Name.EXTENSION_NAME); 352 String specVersion = mainAttrs.getValue(token + "-" + Attributes.Name.SPECIFICATION_VERSION); 353 ExtensionKey key = new ExtensionKey(extName, specVersion); 354 result.add(key); 355 } 356 } 357 } 358 return result; 359 } 360 361 366 public class ExtensionKey { 367 private String extensionName = null; 368 369 private String specificationVersion = null; 370 371 376 public ExtensionKey(String extensionName, String specificationVersion) { 377 assert extensionName != null : "extensionName is null"; 378 this.extensionName = extensionName; 379 this.specificationVersion = (specificationVersion != null) ? specificationVersion : ""; 380 } 381 382 public boolean equals(Object other) { 383 boolean result = false; 384 if (other != null) { 385 if (other == this) { 386 result = true; 387 } else { 388 if (other instanceof ExtensionKey) { 389 ExtensionKey otherEntryKey = (ExtensionKey) other; 390 result = extensionName.equals(otherEntryKey.extensionName) && 391 specificationVersion.equals(otherEntryKey.specificationVersion); 392 } 393 } 394 } 395 return result; 396 } 397 398 public int hashCode() { 399 int result = 17; 400 result = 37 * result + extensionName.hashCode(); 401 result = 37 * result + specificationVersion.hashCode(); 402 return result; 403 } 404 405 public String toString() { 406 return "Name=" + extensionName + ", spec version = " + specificationVersion; 407 } 408 } 409 410 413 public class Extension { 414 415 private ExtensionKey extensionKey; 416 417 private File file = null; 418 419 420 private int extDirectoryNumber = -1; 421 422 public Extension(ExtensionKey extensionKey, File file, int extDirectoryNumber) { 423 assert extensionKey != null : "extensionKey is null"; 424 assert file != null : "file is null"; 425 426 this.extensionKey = extensionKey; 427 this.file = file; 428 this.extDirectoryNumber = extDirectoryNumber; 429 } 430 431 public boolean equals(Object other) { 432 boolean result = false; 433 if (other != null) { 434 if (other == this) { 435 result = true; 436 } else { 437 if (other instanceof Extension) { 438 Extension otherEntry = (Extension) other; 439 result = extensionKey.equals(otherEntry.extensionKey) && 440 file.equals(otherEntry.file) && 441 extDirectoryNumber == otherEntry.extDirectoryNumber; 442 } 443 } 444 } 445 return result; 446 } 447 448 public int hashCode() { 449 int result = 17; 450 result = result * 37 + extensionKey.hashCode(); 451 result = result * 37 + file.hashCode(); 452 result = result * 37 + extDirectoryNumber; 453 return result; 454 } 455 456 public int getExtDirectoryNumber() { 457 return extDirectoryNumber; 458 } 459 460 public File getFile() { 461 return file; 462 } 463 464 public String toString() { 465 return extensionKey.toString() + ", file = " + file.getAbsolutePath() + ", in ext dir " + extDirectoryNumber + "(" + extensionFileDirs.get(extDirectoryNumber).getAbsolutePath(); 466 } 467 } 468 } 469 | Popular Tags |