1 11 12 package org.eclipse.osgi.framework.adaptor.core; 13 14 import java.io.*; 15 import java.net.MalformedURLException ; 16 import java.net.URL ; 17 import java.util.*; 18 import java.util.zip.ZipEntry ; 19 import java.util.zip.ZipFile ; 20 import org.eclipse.osgi.framework.adaptor.BundleData; 21 import org.eclipse.osgi.framework.debug.Debug; 22 import org.eclipse.osgi.framework.internal.core.Constants; 23 import org.eclipse.osgi.framework.internal.protocol.bundleresource.Handler; 24 import org.eclipse.osgi.framework.util.SecureAction; 25 import org.eclipse.osgi.util.NLS; 26 import org.osgi.framework.FrameworkEvent; 27 28 36 abstract public class BundleFile { 37 static final SecureAction secureAction = new SecureAction(); 38 41 protected File basefile; 42 43 47 public BundleFile() { 48 } 50 51 56 public BundleFile(File basefile) { 57 this.basefile = basefile; 58 } 59 60 67 abstract public File getFile(String path); 68 69 76 abstract public BundleEntry getEntry(String path); 77 78 92 abstract public Enumeration getEntryPaths(String path); 93 94 98 abstract public void close() throws IOException; 99 100 104 abstract public void open() throws IOException; 105 106 112 abstract public boolean containsDir(String dir); 113 114 119 public URL getResourceURL(String path, long hostBundleID) { 120 return getResourceURL(path, hostBundleID, 0); 121 } 122 123 129 public URL getResourceURL(String path, long hostBundleID, int index) { 130 BundleEntry bundleEntry = getEntry(path); 131 if (bundleEntry == null) 132 return null; 133 if (path.length() == 0 || path.charAt(0) != '/') 134 path = '/' + path; 135 try { 136 return secureAction.getURL(Constants.OSGI_RESOURCE_URL_PROTOCOL, Long.toString(hostBundleID), index, path, new Handler(bundleEntry)); 138 } catch (MalformedURLException e) { 139 return null; 140 } 141 } 142 143 146 public static class ZipBundleFile extends BundleFile { 147 150 protected BundleData bundledata; 151 154 protected ZipFile zipFile; 155 158 protected boolean closed = true; 159 160 166 public ZipBundleFile(File basefile, BundleData bundledata) throws IOException { 167 super(basefile); 168 if (!secureAction.exists(basefile)) 169 throw new IOException(NLS.bind(AdaptorMsg.ADAPTER_FILEEXIST_EXCEPTION, basefile)); 170 this.bundledata = bundledata; 171 this.closed = true; 172 } 173 174 178 protected boolean checkedOpen() { 179 try { 180 return getZipFile() != null; 181 } catch (IOException e) { 182 AbstractBundleData abstractData = (AbstractBundleData) bundledata; 183 abstractData.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, abstractData.getBundle(), e); 184 return false; 185 } 186 } 187 188 193 protected ZipFile basicOpen() throws IOException { 194 return secureAction.getZipFile(this.basefile); 195 } 196 197 204 protected ZipFile getZipFile() throws IOException { 205 if (closed) { 206 zipFile = basicOpen(); 207 closed = false; 208 } 209 return zipFile; 210 } 211 212 private ZipEntry getZipEntry(String path) { 213 if (path.length() > 0 && path.charAt(0) == '/') 214 path = path.substring(1); 215 ZipEntry entry = zipFile.getEntry(path); 216 if (entry != null && entry.getSize() == 0 && !entry.isDirectory()) { 217 ZipEntry dirEntry = zipFile.getEntry(path + '/'); 219 if (dirEntry != null) 220 entry = dirEntry; 221 } 222 return entry; 223 } 224 225 232 protected File extractDirectory(String dirName) { 233 if (!checkedOpen()) 234 return null; 235 Enumeration entries = zipFile.entries(); 236 while (entries.hasMoreElements()) { 237 String entryPath = ((ZipEntry ) entries.nextElement()).getName(); 238 if (entryPath.startsWith(dirName) && !entryPath.endsWith("/")) getFile(entryPath); 240 } 241 return getExtractFile(dirName); 242 } 243 244 private File getExtractFile(String entryName) { 245 if (!(bundledata instanceof AbstractBundleData)) 246 return null; 247 String path = ".cp"; String name = entryName.replace('/', File.separatorChar); 249 if ((name.length() > 1) && (name.charAt(0) == File.separatorChar)) 250 path = path.concat(name); 251 else 252 path = path + File.separator + name; 253 File childGenDir = ((AbstractBundleData) bundledata).getGenerationDir(); 255 if (childGenDir != null) { 256 File childPath = new File (childGenDir, path); 257 if (childPath.exists()) 258 return childPath; 259 } 260 File parentGenDir = ((AbstractBundleData) bundledata).getParentGenerationDir(); 262 if (parentGenDir != null) { 263 File parentPath = new File (parentGenDir, path); 265 if (parentPath.exists()) 266 return parentPath; 268 } 269 File bundleGenerationDir = ((AbstractBundleData) bundledata).createGenerationDir(); 271 272 if (bundleGenerationDir != null && bundleGenerationDir.exists()) 273 return new File (bundleGenerationDir, path); 274 return null; 275 } 276 277 public File getFile(String entry) { 278 if (!checkedOpen()) 279 return null; 280 ZipEntry zipEntry = getZipEntry(entry); 281 if (zipEntry == null) { 282 return null; 283 } 284 285 try { 286 File nested = getExtractFile(zipEntry.getName()); 287 if (nested != null) { 288 if (nested.exists()) { 289 290 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 291 Debug.println("File already present: " + nested.getPath()); } 293 } else { 294 if (zipEntry.getName().endsWith("/")) { if (!nested.mkdirs()) { 296 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 297 Debug.println("Unable to create directory: " + nested.getPath()); } 299 throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, nested.getAbsolutePath())); 300 } 301 extractDirectory(zipEntry.getName()); 302 } else { 303 InputStream in = zipFile.getInputStream(zipEntry); 304 if (in == null) 305 return null; 306 307 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 308 Debug.println("Creating file: " + nested.getPath()); } 310 311 File dir = new File (nested.getParent()); 312 if (!dir.exists() && !dir.mkdirs()) { 313 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 314 Debug.println("Unable to create directory: " + dir.getPath()); } 316 throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, dir.getAbsolutePath())); 317 } 318 319 AbstractFrameworkAdaptor.readFile(in, nested); 320 } 321 } 322 323 return nested; 324 } 325 } catch (IOException e) { 326 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 327 Debug.printStackTrace(e); 328 } 329 } 330 return null; 331 } 332 333 public boolean containsDir(String dir) { 334 if (!checkedOpen()) 335 return false; 336 if (dir == null) 337 return false; 338 339 if (dir.length() == 0) 340 return true; 341 342 if (dir.charAt(0) == '/') { 343 if (dir.length() == 1) 344 return true; 345 dir = dir.substring(1); 346 } 347 348 if (dir.length() > 0 && dir.charAt(dir.length() - 1) != '/') 349 dir = dir + '/'; 350 351 Enumeration entries = zipFile.entries(); 352 ZipEntry zipEntry; 353 String entryPath; 354 while (entries.hasMoreElements()) { 355 zipEntry = (ZipEntry ) entries.nextElement(); 356 entryPath = zipEntry.getName(); 357 if (entryPath.startsWith(dir)) { 358 return true; 359 } 360 } 361 return false; 362 } 363 364 public BundleEntry getEntry(String path) { 365 if (!checkedOpen()) 366 return null; 367 ZipEntry zipEntry = getZipEntry(path); 368 if (zipEntry == null) { 369 if (path.length() == 0 || path.charAt(path.length() - 1) == '/') { 370 if (containsDir(path)) 372 return new BundleEntry.DirZipBundleEntry(this, path); 373 } 374 return null; 375 } 376 377 return new BundleEntry.ZipBundleEntry(zipEntry, this); 378 379 } 380 381 public Enumeration getEntryPaths(String path) { 382 if (!checkedOpen()) 383 return null; 384 if (path == null) { 385 throw new NullPointerException (); 386 } 387 388 if (path.length() > 0 && path.charAt(0) == '/') { 389 path = path.substring(1); 390 } 391 if (path.length() > 0 && path.charAt(path.length() - 1) != '/') { 392 path = new StringBuffer (path).append("/").toString(); } 394 395 Vector vEntries = new Vector(); 396 Enumeration entries = zipFile.entries(); 397 while (entries.hasMoreElements()) { 398 ZipEntry zipEntry = (ZipEntry ) entries.nextElement(); 399 String entryPath = zipEntry.getName(); 400 if (entryPath.startsWith(path)) { 401 if (path.length() < entryPath.length()) { 402 if (entryPath.lastIndexOf('/') < path.length()) { 403 vEntries.add(entryPath); 404 } else { 405 entryPath = entryPath.substring(path.length()); 406 int slash = entryPath.indexOf('/'); 407 entryPath = path + entryPath.substring(0, slash + 1); 408 if (!vEntries.contains(entryPath)) { 409 vEntries.add(entryPath); 410 } 411 } 412 } 413 } 414 } 415 return vEntries.elements(); 416 } 417 418 public void close() throws IOException { 419 if (!closed) { 420 closed = true; 421 zipFile.close(); 422 } 423 } 424 425 public void open() { 426 } 428 429 } 430 431 434 public static class DirBundleFile extends BundleFile { 435 436 441 public DirBundleFile(File basefile) throws IOException { 442 super(basefile); 443 if (!secureAction.exists(basefile) || !secureAction.isDirectory(basefile)) { 444 throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_EXCEPTION, basefile)); 445 } 446 } 447 448 public File getFile(String path) { 449 File filePath = new File (this.basefile, path); 450 if (secureAction.exists(filePath)) { 451 return filePath; 452 } 453 return null; 454 } 455 456 public BundleEntry getEntry(String path) { 457 File filePath = new File (this.basefile, path); 458 if (!secureAction.exists(filePath)) { 459 return null; 460 } 461 return new BundleEntry.FileBundleEntry(filePath, path); 462 } 463 464 public boolean containsDir(String dir) { 465 File dirPath = new File (this.basefile, dir); 466 return secureAction.exists(dirPath) && secureAction.isDirectory(dirPath); 467 } 468 469 public Enumeration getEntryPaths(final String path) { 470 final java.io.File pathFile = new java.io.File (basefile, path); 471 if (!secureAction.exists(pathFile)) 472 return new Enumeration() { 473 public boolean hasMoreElements() { 474 return false; 475 } 476 477 public Object nextElement() { 478 throw new NoSuchElementException(); 479 } 480 }; 481 if (secureAction.isDirectory(pathFile)) { 482 final String [] fileList = secureAction.list(pathFile); 483 final String dirPath = path.length() == 0 || path.charAt(path.length() - 1) == '/' ? path : path + '/'; 484 return new Enumeration() { 485 int cur = 0; 486 487 public boolean hasMoreElements() { 488 return fileList != null && cur < fileList.length; 489 } 490 491 public Object nextElement() { 492 if (!hasMoreElements()) { 493 throw new NoSuchElementException(); 494 } 495 java.io.File childFile = new java.io.File (pathFile, fileList[cur]); 496 StringBuffer sb = new StringBuffer (dirPath).append(fileList[cur++]); 497 if (secureAction.isDirectory(childFile)) { 498 sb.append("/"); } 500 return sb.toString(); 501 } 502 503 }; 504 } 505 return new Enumeration() { 506 int cur = 0; 507 508 public boolean hasMoreElements() { 509 return cur < 1; 510 } 511 512 public Object nextElement() { 513 if (cur == 0) { 514 cur = 1; 515 return path; 516 } 517 throw new NoSuchElementException(); 518 } 519 }; 520 } 521 522 public void close() { 523 } 525 526 public void open() { 527 } 529 } 530 531 542 public static class NestedDirBundleFile extends BundleFile { 543 BundleFile baseBundleFile; 544 String cp; 545 546 551 public NestedDirBundleFile(BundleFile baseBundlefile, String cp) { 552 super(baseBundlefile.basefile); 553 this.baseBundleFile = baseBundlefile; 554 this.cp = cp; 555 if (cp.charAt(cp.length() - 1) != '/') { 556 this.cp = this.cp + '/'; 557 } 558 } 559 560 public void close() { 561 } 563 564 public BundleEntry getEntry(String path) { 565 if (path.length() > 0 && path.charAt(0) == '/') 566 path = path.substring(1); 567 String newpath = new StringBuffer (cp).append(path).toString(); 568 return baseBundleFile.getEntry(newpath); 569 } 570 571 public boolean containsDir(String dir) { 572 if (dir == null) 573 return false; 574 575 if (dir.length() > 0 && dir.charAt(0) == '/') 576 dir = dir.substring(1); 577 String newdir = new StringBuffer (cp).append(dir).toString(); 578 return baseBundleFile.containsDir(newdir); 579 } 580 581 public Enumeration getEntryPaths(String path) { 582 return null; 584 } 585 586 public File getFile(String entry) { 587 return null; 589 } 590 591 public void open() throws IOException{ 592 } 594 } 595 596 600 public File getBaseFile() { 601 return basefile; 602 } 603 } 604 | Popular Tags |