001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.vfs.provider.zip;
018:
019: import org.apache.commons.logging.Log;
020: import org.apache.commons.logging.LogFactory;
021: import org.apache.commons.vfs.FileName;
022: import org.apache.commons.vfs.FileObject;
023: import org.apache.commons.vfs.FileSystem;
024: import org.apache.commons.vfs.FileSystemException;
025: import org.apache.commons.vfs.FileSystemOptions;
026: import org.apache.commons.vfs.Selectors;
027: import org.apache.commons.vfs.VfsLog;
028: import org.apache.commons.vfs.provider.AbstractFileSystem;
029: import org.apache.commons.vfs.provider.UriParser;
030:
031: import java.io.File;
032: import java.io.IOException;
033: import java.util.ArrayList;
034: import java.util.Collection;
035: import java.util.Enumeration;
036: import java.util.List;
037: import java.util.zip.ZipEntry;
038: import java.util.zip.ZipFile;
039:
040: /**
041: * A read-only file system for Zip/Jar files.
042: *
043: * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
044: * @version $Revision: 484648 $ $Date: 2006-12-08 08:18:36 -0800 (Fri, 08 Dec 2006) $
045: */
046: public class ZipFileSystem extends AbstractFileSystem implements
047: FileSystem {
048: private final static Log log = LogFactory
049: .getLog(ZipFileSystem.class);
050:
051: private final File file;
052: private ZipFile zipFile;
053:
054: public ZipFileSystem(final FileName rootName,
055: final FileObject parentLayer,
056: final FileSystemOptions fileSystemOptions)
057: throws FileSystemException {
058: super (rootName, parentLayer, fileSystemOptions);
059:
060: // Make a local copy of the file
061: file = parentLayer.getFileSystem().replicateFile(parentLayer,
062: Selectors.SELECT_SELF);
063:
064: // Open the Zip file
065: if (!file.exists()) {
066: // Don't need to do anything
067: zipFile = null;
068: return;
069: }
070:
071: // zipFile = createZipFile(this.file);
072: }
073:
074: public void init() throws FileSystemException {
075: super .init();
076:
077: try {
078: // Build the index
079: List strongRef = new ArrayList(100);
080: Enumeration entries = getZipFile().entries();
081: while (entries.hasMoreElements()) {
082: ZipEntry entry = (ZipEntry) entries.nextElement();
083: FileName name = getFileSystemManager().resolveName(
084: getRootName(),
085: UriParser.encode(entry.getName()));
086:
087: // Create the file
088: ZipFileObject fileObj;
089: if (entry.isDirectory()
090: && getFileFromCache(name) != null) {
091: fileObj = (ZipFileObject) getFileFromCache(name);
092: fileObj.setZipEntry(entry);
093: continue;
094: }
095:
096: fileObj = createZipFileObject(name, entry);
097: putFileToCache(fileObj);
098: strongRef.add(fileObj);
099: fileObj.holdObject(strongRef);
100:
101: // Make sure all ancestors exist
102: // TODO - create these on demand
103: ZipFileObject parent = null;
104: for (FileName parentName = name.getParent(); parentName != null; fileObj = parent, parentName = parentName
105: .getParent()) {
106: // Locate the parent
107: parent = (ZipFileObject) getFileFromCache(parentName);
108: if (parent == null) {
109: parent = createZipFileObject(parentName, null);
110: putFileToCache(parent);
111: strongRef.add(parent);
112: parent.holdObject(strongRef);
113: }
114:
115: // Attach child to parent
116: parent.attachChild(fileObj.getName());
117: }
118: }
119: } finally {
120: closeCommunicationLink();
121: }
122: }
123:
124: protected ZipFile getZipFile() throws FileSystemException {
125: if (zipFile == null && this .file.exists()) {
126: ZipFile zipFile = createZipFile(this .file);
127:
128: this .zipFile = zipFile;
129: }
130:
131: return zipFile;
132: }
133:
134: protected ZipFileObject createZipFileObject(final FileName name,
135: final ZipEntry entry) throws FileSystemException {
136: return new ZipFileObject(name, entry, this , true);
137: }
138:
139: protected ZipFile createZipFile(final File file)
140: throws FileSystemException {
141: try {
142: return new ZipFile(file);
143: } catch (IOException ioe) {
144: throw new FileSystemException(
145: "vfs.provider.zip/open-zip-file.error", file, ioe);
146: }
147: }
148:
149: protected void doCloseCommunicationLink() {
150: // Release the zip file
151: try {
152: if (zipFile != null) {
153: zipFile.close();
154: zipFile = null;
155: }
156: } catch (final IOException e) {
157: // getLogger().warn("vfs.provider.zip/close-zip-file.error :" + file, e);
158: VfsLog
159: .warn(getLogger(), log,
160: "vfs.provider.zip/close-zip-file.error :"
161: + file, e);
162: }
163: }
164:
165: /**
166: * Returns the capabilities of this file system.
167: */
168: protected void addCapabilities(final Collection caps) {
169: caps.addAll(ZipFileProvider.capabilities);
170: }
171:
172: /**
173: * Creates a file object.
174: */
175: protected FileObject createFile(final FileName name)
176: throws FileSystemException {
177: // This is only called for files which do not exist in the Zip file
178: return new ZipFileObject(name, null, this , false);
179: }
180:
181: /**
182: * will be called after all file-objects closed their streams.
183: protected void notifyAllStreamsClosed()
184: {
185: closeCommunicationLink();
186: }
187: */
188: }
|