Coverage Report - org.codehaus.plexus.archiver.zip.AbstractZipUnArchiver
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractZipUnArchiver
83%
50/60
83%
15/18
2,235
AbstractZipUnArchiver$ZipEntryFileInfo
33%
6/18
10%
1/10
2,235
 
 1  
 /**
 2  
  *
 3  
  * Copyright 2004 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * 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.codehaus.plexus.archiver.zip;
 18  
 
 19  
 import java.io.File;
 20  
 import java.io.IOException;
 21  
 import java.io.InputStream;
 22  
 import java.io.UnsupportedEncodingException;
 23  
 import java.net.URL;
 24  
 import java.util.Date;
 25  
 import java.util.Enumeration;
 26  
 import javax.annotation.Nonnull;
 27  
 import org.apache.commons.compress.archivers.zip.UnicodePathExtraField;
 28  
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
 29  
 import org.apache.commons.compress.archivers.zip.ZipFile;
 30  
 import org.apache.commons.compress.utils.IOUtils;
 31  
 import org.codehaus.plexus.archiver.AbstractUnArchiver;
 32  
 import org.codehaus.plexus.archiver.ArchiverException;
 33  
 import org.codehaus.plexus.components.io.resources.PlexusIoResource;
 34  
 
 35  
 /**
 36  
  * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
 37  
  */
 38  
 public abstract class AbstractZipUnArchiver
 39  
     extends AbstractUnArchiver
 40  
 {
 41  
 
 42  
     private static final String NATIVE_ENCODING = "native-encoding";
 43  
 
 44  18
     private String encoding = "UTF8";
 45  
 
 46  
     public AbstractZipUnArchiver()
 47  18
     {
 48  18
     }
 49  
 
 50  
     public AbstractZipUnArchiver( final File sourceFile )
 51  
     {
 52  0
         super( sourceFile );
 53  0
     }
 54  
 
 55  
     /**
 56  
      * Sets the encoding to assume for file names and comments.
 57  
      * <p/>
 58  
      * <p>
 59  
      * Set to <code>native-encoding</code> if you want your platform's native encoding, defaults to UTF8.
 60  
      * </p>
 61  
      */
 62  
     public void setEncoding( String encoding )
 63  
     {
 64  0
         if ( NATIVE_ENCODING.equals( encoding ) )
 65  
         {
 66  0
             encoding = null;
 67  
         }
 68  0
         this.encoding = encoding;
 69  0
     }
 70  
 
 71  
     private static class ZipEntryFileInfo
 72  
         implements PlexusIoResource
 73  
     {
 74  
 
 75  
         private final org.apache.commons.compress.archivers.zip.ZipFile zipFile;
 76  
 
 77  
         private final ZipArchiveEntry zipEntry;
 78  
 
 79  
         ZipEntryFileInfo( final org.apache.commons.compress.archivers.zip.ZipFile zipFile,
 80  
                           final ZipArchiveEntry zipEntry )
 81  139
         {
 82  139
             this.zipFile = zipFile;
 83  139
             this.zipEntry = zipEntry;
 84  139
         }
 85  
 
 86  
         public String getName()
 87  
         {
 88  
             try
 89  
             {
 90  212
                 final UnicodePathExtraField unicodePath =
 91  
                     (UnicodePathExtraField) zipEntry.getExtraField( UnicodePathExtraField.UPATH_ID );
 92  
 
 93  212
                 return unicodePath != null
 94  
                            ? new String( unicodePath.getUnicodeName(), "UTF-8" )
 95  
                            : zipEntry.getName();
 96  
 
 97  
             }
 98  0
             catch ( final UnsupportedEncodingException e )
 99  
             {
 100  0
                 throw new AssertionError( e );
 101  
             }
 102  
         }
 103  
 
 104  
         @Override
 105  
         public boolean isDirectory()
 106  
         {
 107  0
             return zipEntry.isDirectory();
 108  
         }
 109  
 
 110  
         @Override
 111  
         public boolean isFile()
 112  
         {
 113  0
             return !zipEntry.isDirectory() && !zipEntry.isUnixSymlink();
 114  
         }
 115  
 
 116  
         @Override
 117  
         public boolean isSymbolicLink()
 118  
         {
 119  0
             return zipEntry.isUnixSymlink();
 120  
         }
 121  
 
 122  
         @Nonnull
 123  
         @Override
 124  
         public InputStream getContents()
 125  
             throws IOException
 126  
         {
 127  0
             return zipFile.getInputStream( zipEntry );
 128  
         }
 129  
 
 130  
         @Override
 131  
         public long getLastModified()
 132  
         {
 133  0
             final long l = zipEntry.getTime();
 134  0
             return l == 0 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : l;
 135  
         }
 136  
 
 137  
         @Override
 138  
         public long getSize()
 139  
         {
 140  0
             final long l = zipEntry.getSize();
 141  0
             return l == -1 ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : l;
 142  
         }
 143  
 
 144  
         @Override
 145  
         public URL getURL()
 146  
             throws IOException
 147  
         {
 148  0
             return null;
 149  
         }
 150  
 
 151  
         @Override
 152  
         public boolean isExisting()
 153  
         {
 154  0
             return true;
 155  
         }
 156  
 
 157  
     }
 158  
 
 159  
     @Override
 160  
     protected void execute()
 161  
         throws ArchiverException
 162  
     {
 163  9
         getLogger().debug( "Expanding: " + getSourceFile() + " into " + getDestDirectory() );
 164  9
         org.apache.commons.compress.archivers.zip.ZipFile zf = null;
 165  9
         InputStream in = null;
 166  
         try
 167  
         {
 168  9
             zf = new org.apache.commons.compress.archivers.zip.ZipFile( getSourceFile(), encoding, true );
 169  9
             final Enumeration e = zf.getEntriesInPhysicalOrder();
 170  101
             while ( e.hasMoreElements() )
 171  
             {
 172  92
                 final ZipArchiveEntry ze = (ZipArchiveEntry) e.nextElement();
 173  92
                 final ZipEntryFileInfo fileInfo = new ZipEntryFileInfo( zf, ze );
 174  92
                 if ( isSelected( fileInfo.getName(), fileInfo ) )
 175  
                 {
 176  92
                     in = zf.getInputStream( ze );
 177  
 
 178  92
                     extractFileIfIncluded( getSourceFile(), getDestDirectory(), in, fileInfo.getName(),
 179  
                                            new Date( ze.getTime() ), ze.isDirectory(),
 180  
                                            ze.getUnixMode() != 0 ? ze.getUnixMode() : null,
 181  
                                            resolveSymlink( zf, ze ) );
 182  
 
 183  92
                     in.close();
 184  92
                     in = null;
 185  
                 }
 186  92
             }
 187  
 
 188  9
             zf.close();
 189  9
             zf = null;
 190  
 
 191  9
             getLogger().debug( "expand complete" );
 192  
         }
 193  0
         catch ( final IOException ioe )
 194  
         {
 195  0
             throw new ArchiverException( "Error while expanding " + getSourceFile().getAbsolutePath(), ioe );
 196  
         }
 197  
         finally
 198  
         {
 199  9
             IOUtils.closeQuietly( in );
 200  9
             IOUtils.closeQuietly( zf );
 201  9
         }
 202  9
     }
 203  
 
 204  
     private String resolveSymlink( ZipFile zf, ZipArchiveEntry ze )
 205  
         throws IOException
 206  
     {
 207  123
         if ( ze.isUnixSymlink() )
 208  
         {
 209  21
             return zf.getUnixSymlink( ze );
 210  
         }
 211  
         else
 212  
         {
 213  102
             return null;
 214  
         }
 215  
     }
 216  
 
 217  
     private void extractFileIfIncluded( final File sourceFile, final File destDirectory, final InputStream inputStream,
 218  
                                         final String name, final Date time, final boolean isDirectory,
 219  
                                         final Integer mode, String symlinkDestination )
 220  
         throws IOException, ArchiverException
 221  
     {
 222  123
         extractFile( sourceFile, destDirectory, inputStream, name, time, isDirectory, mode, symlinkDestination );
 223  123
     }
 224  
 
 225  
     @Override
 226  
     protected void execute( final String path, final File outputDirectory )
 227  
         throws ArchiverException
 228  
     {
 229  8
         org.apache.commons.compress.archivers.zip.ZipFile zipFile = null;
 230  8
         InputStream in = null;
 231  
         try
 232  
         {
 233  8
             zipFile = new org.apache.commons.compress.archivers.zip.ZipFile( getSourceFile(), encoding, true );
 234  
 
 235  8
             final Enumeration e = zipFile.getEntriesInPhysicalOrder();
 236  
 
 237  55
             while ( e.hasMoreElements() )
 238  
             {
 239  47
                 final ZipArchiveEntry ze = (ZipArchiveEntry) e.nextElement();
 240  47
                 final ZipEntryFileInfo fileInfo = new ZipEntryFileInfo( zipFile, ze );
 241  47
                 if ( !isSelected( ze.getName(), fileInfo ) )
 242  
                 {
 243  13
                     continue;
 244  
                 }
 245  
 
 246  34
                 if ( ze.getName().startsWith( path ) )
 247  
                 {
 248  31
                     in = zipFile.getInputStream( ze );
 249  
 
 250  31
                     extractFileIfIncluded( getSourceFile(), outputDirectory, in,
 251  
                                            ze.getName(), new Date( ze.getTime() ), ze.isDirectory(),
 252  
                                            ze.getUnixMode() != 0 ? ze.getUnixMode() : null,
 253  
                                            resolveSymlink( zipFile, ze ) );
 254  
 
 255  31
                     in.close();
 256  31
                     in = null;
 257  
                 }
 258  34
             }
 259  
 
 260  8
             zipFile.close();
 261  8
             zipFile = null;
 262  
         }
 263  0
         catch ( final IOException ioe )
 264  
         {
 265  0
             throw new ArchiverException( "Error while expanding " + getSourceFile().getAbsolutePath(), ioe );
 266  
         }
 267  
         finally
 268  
         {
 269  8
             IOUtils.closeQuietly( in );
 270  8
             IOUtils.closeQuietly( zipFile );
 271  8
         }
 272  8
     }
 273  
 
 274  
 }