1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs.provider.zip;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.commons.vfs.FileName;
22 import org.apache.commons.vfs.FileObject;
23 import org.apache.commons.vfs.FileSystem;
24 import org.apache.commons.vfs.FileSystemException;
25 import org.apache.commons.vfs.FileSystemOptions;
26 import org.apache.commons.vfs.Selectors;
27 import org.apache.commons.vfs.VfsLog;
28 import org.apache.commons.vfs.provider.AbstractFileSystem;
29 import org.apache.commons.vfs.provider.UriParser;
30
31 import java.io.File;
32 import java.io.IOException;
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.Enumeration;
36 import java.util.List;
37 import java.util.zip.ZipEntry;
38 import java.util.zip.ZipFile;
39
40 /***
41 * A read-only file system for Zip/Jar files.
42 *
43 * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
44 * @version $Revision: 484648 $ $Date: 2006-12-08 17:18:36 +0100 (Fr, 08 Dez 2006) $
45 */
46 public class ZipFileSystem
47 extends AbstractFileSystem
48 implements FileSystem
49 {
50 private final static Log log = LogFactory.getLog(ZipFileSystem.class);
51
52 private final File file;
53 private ZipFile zipFile;
54
55 public ZipFileSystem(final FileName rootName,
56 final FileObject parentLayer,
57 final FileSystemOptions fileSystemOptions)
58 throws FileSystemException
59 {
60 super(rootName, parentLayer, fileSystemOptions);
61
62
63 file = parentLayer.getFileSystem().replicateFile(parentLayer, Selectors.SELECT_SELF);
64
65
66 if (!file.exists())
67 {
68
69 zipFile = null;
70 return;
71 }
72
73
74 }
75
76 public void init() throws FileSystemException
77 {
78 super.init();
79
80 try
81 {
82
83 List strongRef = new ArrayList(100);
84 Enumeration entries = getZipFile().entries();
85 while (entries.hasMoreElements())
86 {
87 ZipEntry entry = (ZipEntry) entries.nextElement();
88 FileName name = getFileSystemManager().resolveName(getRootName(), UriParser.encode(entry.getName()));
89
90
91 ZipFileObject fileObj;
92 if (entry.isDirectory() && getFileFromCache(name) != null)
93 {
94 fileObj = (ZipFileObject) getFileFromCache(name);
95 fileObj.setZipEntry(entry);
96 continue;
97 }
98
99 fileObj = createZipFileObject(name, entry);
100 putFileToCache(fileObj);
101 strongRef.add(fileObj);
102 fileObj.holdObject(strongRef);
103
104
105
106 ZipFileObject parent = null;
107 for (FileName parentName = name.getParent();
108 parentName != null;
109 fileObj = parent, parentName = parentName.getParent())
110 {
111
112 parent = (ZipFileObject) getFileFromCache(parentName);
113 if (parent == null)
114 {
115 parent = createZipFileObject(parentName, null);
116 putFileToCache(parent);
117 strongRef.add(parent);
118 parent.holdObject(strongRef);
119 }
120
121
122 parent.attachChild(fileObj.getName());
123 }
124 }
125 }
126 finally
127 {
128 closeCommunicationLink();
129 }
130 }
131
132 protected ZipFile getZipFile() throws FileSystemException
133 {
134 if (zipFile == null && this.file.exists())
135 {
136 ZipFile zipFile = createZipFile(this.file);
137
138 this.zipFile = zipFile;
139 }
140
141 return zipFile;
142 }
143
144 protected ZipFileObject createZipFileObject(final FileName name,
145 final ZipEntry entry) throws FileSystemException
146 {
147 return new ZipFileObject(name, entry, this, true);
148 }
149
150 protected ZipFile createZipFile(final File file) throws FileSystemException
151 {
152 try
153 {
154 return new ZipFile(file);
155 }
156 catch (IOException ioe)
157 {
158 throw new FileSystemException("vfs.provider.zip/open-zip-file.error", file, ioe);
159 }
160 }
161
162 protected void doCloseCommunicationLink()
163 {
164
165 try
166 {
167 if (zipFile != null)
168 {
169 zipFile.close();
170 zipFile = null;
171 }
172 }
173 catch (final IOException e)
174 {
175
176 VfsLog.warn(getLogger(), log, "vfs.provider.zip/close-zip-file.error :" + file, e);
177 }
178 }
179
180 /***
181 * Returns the capabilities of this file system.
182 */
183 protected void addCapabilities(final Collection caps)
184 {
185 caps.addAll(ZipFileProvider.capabilities);
186 }
187
188 /***
189 * Creates a file object.
190 */
191 protected FileObject createFile(final FileName name) throws FileSystemException
192 {
193
194 return new ZipFileObject(name, null, this, false);
195 }
196
197 /***
198 * will be called after all file-objects closed their streams.
199 protected void notifyAllStreamsClosed()
200 {
201 closeCommunicationLink();
202 }
203 */
204 }