01: package org.python.core;
02:
03: import java.io.*;
04: import java.util.zip.*;
05:
06: public class SyspathArchive extends PyString {
07: private ZipFile zipFile;
08:
09: public SyspathArchive(String archiveName) throws IOException {
10: super (archiveName);
11: archiveName = getArchiveName(archiveName);
12: if (archiveName == null) {
13: throw new IOException("path '" + archiveName
14: + "' not an archive");
15: }
16: this .zipFile = new ZipFile(new File(archiveName));
17: PySystemState.packageManager.addJar(archiveName, false);
18: }
19:
20: SyspathArchive(ZipFile zipFile, String archiveName) {
21: super (archiveName);
22: this .zipFile = zipFile;
23: }
24:
25: static String getArchiveName(String dir) {
26: String lowerName = dir.toLowerCase();
27: int idx = lowerName.indexOf(".zip");
28: if (idx < 0) {
29: idx = lowerName.indexOf(".jar");
30: }
31: if (idx < 0) {
32: return null;
33: }
34:
35: if (idx == dir.length() - 4) {
36: return dir;
37: }
38: char ch = dir.charAt(idx + 4);
39: if (ch == File.separatorChar || ch == '/') {
40: return dir.substring(0, idx + 4);
41: }
42: return null;
43: }
44:
45: public SyspathArchive makeSubfolder(String folder) {
46: return new SyspathArchive(this .zipFile, super .toString() + "/"
47: + folder);
48: }
49:
50: private String makeEntry(String entry) {
51: String archive = super .toString();
52: String folder = getArchiveName(super .toString());
53: if (archive.length() == folder.length()) {
54: return entry;
55: } else {
56: return archive.substring(folder.length() + 1) + "/" + entry;
57: }
58: }
59:
60: ZipEntry getEntry(String entryName) {
61: return this .zipFile.getEntry(makeEntry(entryName));
62: }
63:
64: InputStream getInputStream(ZipEntry entry) throws IOException {
65: InputStream istream = this .zipFile.getInputStream(entry);
66:
67: // Some jdk1.1 VMs have problems with detecting the end of a zip
68: // stream correctly. If you read beyond the end, you get a
69: // EOFException("Unexpected end of ZLIB input stream"), not a
70: // -1 return value.
71: // XXX: Since 1.1 is no longer supported, we should review the usefulness
72: // of this workaround.
73: // As a workaround we read the file fully here, but only getSize()
74: // bytes.
75: int len = (int) entry.getSize();
76: byte[] buffer = new byte[len];
77: int off = 0;
78: while (len > 0) {
79: int l = istream.read(buffer, off, buffer.length - off);
80: if (l < 0)
81: return null;
82: off += l;
83: len -= l;
84: }
85: istream.close();
86: return new ByteArrayInputStream(buffer);
87: }
88:
89: /*
90: protected void finalize() {
91: System.out.println("closing zip file " + toString());
92: try {
93: zipFile.close();
94: } catch (IOException e) {
95: Py.writeDebug("import", "closing zipEntry failed");
96: }
97: }
98: */
99: }
|