Coverage Report - org.apache.maven.shared.utils.Expand
 
Classes in this File Line Coverage Branch Coverage Complexity
Expand
77%
38/49
79%
19/24
3.143
 
 1  
 package org.apache.maven.shared.utils;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *  http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.File;
 23  
 import java.io.FileInputStream;
 24  
 import java.io.FileOutputStream;
 25  
 import java.io.IOException;
 26  
 import java.io.InputStream;
 27  
 import java.util.Date;
 28  
 import java.util.zip.ZipEntry;
 29  
 import java.util.zip.ZipInputStream;
 30  
 import org.apache.maven.shared.utils.io.FileUtils;
 31  
 
 32  
 /**
 33  
  * Expand will unpack the given zip archive.
 34  
  *
 35  
  * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
 36  
  */
 37  11
 class Expand
 38  
 {
 39  
     /**
 40  
      * Source file which should get expanded
 41  
      */
 42  
     private File source;
 43  
 
 44  
     /**
 45  
      * destination directory
 46  
      */
 47  
     private File dest;
 48  
 
 49  
     /**
 50  
      * if the unpackaging should get performed if the destination already exists.
 51  
      */
 52  11
     private boolean overwrite = false;
 53  
 
 54  
     private static final int BUFFER_SIZE = 2 ^ 16;
 55  
 
 56  
 
 57  
     /**
 58  
      * The zip archive which should get expanded.
 59  
      *
 60  
      * @param sourceArchive
 61  
      */
 62  
     public void setSrc( File sourceArchive )
 63  
     {
 64  10
         this.source = sourceArchive;
 65  10
     }
 66  
 
 67  
     /**
 68  
      * Set the destination directory into which the archive should get expanded.
 69  
      * The directory will get created if it doesn't yet exist
 70  
      * while executing the expand.
 71  
      *
 72  
      * @param destinationDirectory
 73  
      */
 74  
     public void setDest( File destinationDirectory )
 75  
     {
 76  10
         this.dest = destinationDirectory;
 77  10
     }
 78  
 
 79  
     /**
 80  
      * If the destination directory should get overwritten if the content
 81  
      * already exists. If <code>false</code> we will only overwrite if the local
 82  
      * file or directory is older than the one in the archive.
 83  
      *
 84  
      * @param overwrite
 85  
      */
 86  
     public void setOverwrite( boolean overwrite )
 87  
     {
 88  3
         this.overwrite = overwrite;
 89  3
     }
 90  
 
 91  
     /**
 92  
      * Actually perform the unpacking of the source archive
 93  
      * into the destination directory.
 94  
      *
 95  
      * @throws Exception
 96  
      */
 97  
     public void execute()
 98  
         throws Exception
 99  
     {
 100  9
         expandFile( source, dest );
 101  7
     }
 102  
 
 103  
     /**
 104  
      * <p>It is intended to be overwritten when implementing an own unarchiver</p>
 105  
      * <p/>
 106  
      * <p><b>Note:</b> we kept this protected method for the sake of backward compatibility!</p>
 107  
      *
 108  
      * @param srcFile
 109  
      * @param dest
 110  
      * @throws Exception
 111  
      */
 112  
     void expandFile( File srcFile, File dest )
 113  
         throws Exception
 114  
     {
 115  9
         if ( source == null )
 116  
         {
 117  1
             throw new NullPointerException( "Source Archive must not be null!" );
 118  
         }
 119  
 
 120  8
         File destDir = dest;
 121  8
         if ( destDir == null )
 122  
         {
 123  1
             destDir = new File( System.getProperty( "user.dir" ) );
 124  
         }
 125  
 
 126  8
         FileInputStream fileInputStream = new FileInputStream( srcFile );
 127  
         try
 128  
         {
 129  7
             ZipInputStream zipInputStream = new ZipInputStream( fileInputStream );
 130  
 
 131  
             ZipEntry zipEntry;
 132  
 
 133  21
             while ( ( zipEntry = zipInputStream.getNextEntry() ) != null )
 134  
             {
 135  14
                 String zipEntryName = zipEntry.getName();
 136  14
                 Date zipEntryDate = new Date( zipEntry.getTime() );
 137  
 
 138  14
                 extractFile( source, destDir, zipInputStream, zipEntryName, zipEntryDate, zipEntry.isDirectory() );
 139  14
             }
 140  
         }
 141  
         finally
 142  
         {
 143  0
             try
 144  
             {
 145  7
                 fileInputStream.close();
 146  
             }
 147  0
             catch ( IOException ioe )
 148  
             {
 149  
                 // no worries, all is ok ...
 150  7
             }
 151  0
         }
 152  7
     }
 153  
 
 154  
     /**
 155  
      * Extract a single ZipEntry.
 156  
      * <p/>
 157  
      * <p><b>Note:</b> we kept this protected method for the sake of backward compatibility!</p>
 158  
      *
 159  
      * @param archive               the archive to unpack
 160  
      * @param destDir               the destination dirctory
 161  
      * @param compressedInputStream
 162  
      * @param entryName
 163  
      * @param entryDate
 164  
      * @param isDirectory
 165  
      * @throws Exception
 166  
      */
 167  
     void extractFile( File archive, File destDir, InputStream compressedInputStream, String entryName,
 168  
                                 Date entryDate, boolean isDirectory )
 169  
         throws Exception
 170  
     {
 171  14
         File targetFile = new File( destDir, entryName );
 172  
 
 173  
         // if overwrite is specified and the file type
 174  
         // of the existing file does not match, then delete it
 175  14
         if ( overwrite && targetFile.exists() && targetFile.isDirectory() != isDirectory )
 176  
         {
 177  0
             deleteFileOrDir( targetFile );
 178  
         }
 179  
 
 180  14
         if ( !targetFile.exists() || overwrite || targetFile.lastModified() <= entryDate.getTime() )
 181  
         {
 182  12
             if ( isDirectory )
 183  
             {
 184  6
                 targetFile.mkdirs();
 185  
             }
 186  
             else
 187  
             {
 188  6
                 byte[] buffer = new byte[BUFFER_SIZE];
 189  6
                 FileOutputStream fileOutputStream = new FileOutputStream( targetFile );
 190  
                 try
 191  
                 {
 192  
                     int len;
 193  12
                     while ( ( len = compressedInputStream.read( buffer ) ) > 0 )
 194  
                     {
 195  6
                         fileOutputStream.write( buffer, 0, len );
 196  
                     }
 197  
                 }
 198  
                 finally
 199  
                 {
 200  0
                     try
 201  
                     {
 202  6
                         fileOutputStream.close();
 203  
                     }
 204  0
                     catch ( IOException ioe )
 205  
                     {
 206  
                         // no worries, all is ok ...
 207  6
                     }
 208  0
                 }
 209  6
                 targetFile.setLastModified( entryDate.getTime() );
 210  
             }
 211  
         }
 212  14
     }
 213  
 
 214  
     /**
 215  
      * small helper method who deletes the given directory or file.
 216  
      *
 217  
      * @param targetFile
 218  
      * @throws IOException
 219  
      */
 220  
     private void deleteFileOrDir( File targetFile )
 221  
         throws IOException
 222  
     {
 223  0
         if ( targetFile.isDirectory() )
 224  
         {
 225  0
             FileUtils.deleteDirectory( targetFile );
 226  
         }
 227  
         else
 228  
         {
 229  0
             targetFile.delete();
 230  
         }
 231  
 
 232  0
     }
 233  
 }