1 23 24 25 package com.sun.jdo.api.persistence.enhancer.util; 26 27 import java.util.Enumeration ; 28 import java.util.NoSuchElementException ; 29 import java.io.File ; 30 import java.io.IOException ; 31 import java.io.FilenameFilter ; 32 import java.util.zip.ZipFile ; 33 import java.util.zip.ZipEntry ; 34 35 38 39 abstract class ClassPathElement { 40 41 42 private ClassPathElement next; 43 44 45 46 50 public abstract ClassFileSource sourceOf(String className); 51 52 62 public abstract Enumeration classesInPackage(String packageName); 63 64 68 abstract boolean matches(File directory); 69 70 73 ClassPathElement next() { 74 return this.next; 75 } 76 77 80 void setNext(ClassPathElement next) { 81 this.next = next; 82 } 83 84 87 ClassPathElement() { 88 } 89 90 94 static ClassPathElement create(String elementSpec) { 95 File element = new File (elementSpec); 96 if (!element.isDirectory() && 97 looksLikeZipName(elementSpec)) 98 return new ZipFileClassPathElement(element); 99 else 100 return new DirectoryClassPathElement(element); 101 } 102 103 106 void append(ClassPathElement another) { 107 ClassPathElement e = this; 108 while (e.next() != null) 109 e = e.next(); 110 e.next = another; 111 } 112 113 116 static protected boolean looksLikeZipName(String fname) { 117 return (fname.length() > 4 && 118 (fname.regionMatches(true, fname.length() - 4, ".zip", 0, 4) || fname.regionMatches(true, fname.length() - 4, ".jar", 0, 4))); } 121 122 } 123 124 128 129 class DirectoryClassPathElement extends ClassPathElement { 130 131 private File directory; 132 133 private boolean exists; 134 135 136 137 141 public ClassFileSource sourceOf(String className) { 142 File f = fileOf(className); 143 if (f != null && f.exists()) { 144 return new ClassFileSource(className, f); 145 } 146 return null; 147 } 148 149 public Enumeration classesInPackage(String packageName) { 150 if (!exists) 151 return null; 152 153 return new DirectoryClassPackageEnumerator(directory, packageName); 154 } 155 156 boolean matches(File matchDirectory) { 157 String dir = FilePath.canonicalize(directory); 158 String matchDir = FilePath.canonicalize(matchDirectory); 159 return FilePath.canonicalNamesEqual(dir, matchDir); 160 } 161 162 165 DirectoryClassPathElement(File dirSpec) { 166 directory = dirSpec; 167 checkValid(); 168 } 169 170 171 172 176 private File fileOf(String className) { 177 if (exists && directory.isDirectory()) { 178 StringBuffer newPath = new StringBuffer (directory.getPath()); 179 if (newPath.charAt(newPath.length() - 1) != File.separatorChar) 180 newPath.append(File.separatorChar); 181 newPath.append(ClassPath.fileNameOf(className)); 182 183 File f = new File (newPath.toString()); 184 if (f.isFile()) 185 return f; 186 } 187 188 return null; 189 } 190 191 195 private boolean isValid() { 196 return exists; 197 } 198 199 private void checkValid() { 200 exists = directory.isDirectory(); 201 } 202 } 203 204 208 209 class ZipFileClassPathElement extends ClassPathElement { 210 211 private File zipFileElement; 212 private ZipFile zipFile; 213 214 215 216 220 public ClassFileSource sourceOf(String className) { 221 if (zipFile != null) { 222 ZipEntry entry = 223 zipFile.getEntry(ClassPath.zipFileNameOf(className)); 224 if (entry != null) { 225 return new ClassFileSource(className, zipFile); 226 } 227 } 228 return null; 229 } 230 231 public Enumeration classesInPackage(String packageName) { 232 if (zipFile == null) 233 return null; 234 235 return new ZipFileClassPackageEnumerator(zipFile, packageName); 236 } 237 238 boolean matches(File directory) { 239 return false; 240 } 241 242 245 ZipFileClassPathElement(File elementSpec) { 246 zipFileElement = elementSpec; 247 checkValid(); 248 } 249 250 251 252 private void checkValid() { 253 if (looksLikeZipName(zipFileElement.getPath()) && 254 zipFileElement.isFile()) { 255 try { 256 zipFile = ZipFileRegistry.openZipFile(zipFileElement); 257 } catch (IOException e) { 258 System.err.println("IO exception while reading " + 259 zipFileElement.getPath()); 260 zipFile = null; 261 } 262 } 263 } 264 } 265 266 267 271 272 class DirectoryClassPackageEnumerator 273 implements Enumeration , FilenameFilter { 274 275 private String [] matches; 276 private int nextMatch = -1; 277 String searchPackage; 278 279 285 DirectoryClassPackageEnumerator(File directory, String packageName) { 286 searchPackage = packageName; 287 String packageDirName = directory.getPath() + File.separator + 288 packageName.replace('/', File.separatorChar); 289 290 File packageDir = new File (packageDirName); 291 if (packageDir.isDirectory()) { 292 matches = packageDir.list(this); 293 if (matches != null && matches.length > 0) 294 nextMatch = 0; 295 } 296 } 297 298 public boolean hasMoreElements() { 299 return (nextMatch >= 0); 300 } 301 302 public Object nextElement() { 303 if (!hasMoreElements()) 304 throw new NoSuchElementException (); 305 String next = matches[nextMatch++]; 306 if (nextMatch >= matches.length) 307 nextMatch = -1; 308 return ClassPath.classNameOf(searchPackage + "/" + next); } 310 311 315 316 public boolean accept(File dir, String name) { 317 int nameLength = name.length(); 318 boolean isOk = (nameLength > 6 && 319 name.regionMatches(true, nameLength - 6, ".class", 0, 6)); return isOk; 321 } 322 323 } 324 325 329 330 class ZipFileClassPackageEnumerator implements Enumeration { 331 Enumeration zipFileEntries; 332 ZipEntry nextEntry; 333 String packageName; 334 335 ZipFileClassPackageEnumerator(ZipFile zipFile, String packageName) { 336 zipFileEntries = zipFile.entries(); 337 this.packageName = packageName; 338 } 339 340 public boolean hasMoreElements() { 341 while (nextEntry == null && zipFileEntries != null && 342 zipFileEntries.hasMoreElements()) { 343 ZipEntry ent = (ZipEntry ) zipFileEntries.nextElement(); 344 String memName = ent.getName(); 345 int memNameLength = memName.length(); 346 int packageNameLength = packageName.length(); 347 348 351 352 if (memNameLength > packageNameLength + 1 && 353 memName.regionMatches(false, 0, packageName, 354 0, packageNameLength) && 355 memName.charAt(packageNameLength) == '/') { 356 if (memName.indexOf('/', packageNameLength+1) == -1) { 357 boolean isOk = 358 (memNameLength > packageNameLength+7 && 359 memName.regionMatches(true, memNameLength - 6, ".class", 0, 6)); if (isOk) 361 nextEntry = ent; 362 } 363 } 364 } 365 return nextEntry != null; 366 } 367 368 public Object nextElement() { 369 if (!hasMoreElements()) 370 throw new NoSuchElementException (); 371 String className = nextEntry.getName(); 372 nextEntry = null; 373 return ClassPath.classNameOf(className); 374 } 375 } 376 | Popular Tags |