View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    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          // Make a local copy of the file
    63          file = parentLayer.getFileSystem().replicateFile(parentLayer, Selectors.SELECT_SELF);
    64
    65          // Open the Zip file
    66          if (!file.exists())
    67          {
    68              // Don't need to do anything
    69              zipFile = null;
    70              return;
    71          }
    72
    73          // zipFile = createZipFile(this.file);
    74      }
    75
    76      public void init() throws FileSystemException
    77      {
    78          super.init();
    79
    80          try
    81          {
    82              // Build the index
    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                  // Create the file
    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                 // Make sure all ancestors exist
    105                 // TODO - create these on demand
    106                 ZipFileObject parent = null;
    107                 for (FileName parentName = name.getParent();
    108                      parentName != null;
    109                      fileObj = parent, parentName = parentName.getParent())
    110                 {
    111                     // Locate the parent
    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                     // Attach child to parent
    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         // Release the zip file
    165         try
    166         {
    167             if (zipFile != null)
    168             {
    169                 zipFile.close();
    170                 zipFile = null;
    171             }
    172         }
    173         catch (final IOException e)
    174         {
    175             // getLogger().warn("vfs.provider.zip/close-zip-file.error :" + file, e);
    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         // This is only called for files which do not exist in the Zip file
    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 }