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