| package org.apache.maven.shared.utils; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.Date; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipInputStream; |
| |
| import org.apache.maven.shared.utils.io.FileUtils; |
| import org.apache.maven.shared.utils.io.IOUtil; |
| |
| /** |
| * Expand will unpack the given zip archive. |
| * |
| * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a> |
| */ |
| class Expand |
| { |
| /** |
| * Source file which should get expanded |
| */ |
| private File source; |
| |
| /** |
| * destination directory |
| */ |
| private File dest; |
| |
| /** |
| * if the unpackaging should get performed if the destination already exists. |
| */ |
| private boolean overwrite = false; |
| |
| private static final int BUFFER_SIZE = 2 ^ 16; |
| |
| |
| /** |
| * The zip archive which should get expanded. |
| * |
| * @param sourceArchive |
| */ |
| public void setSrc( File sourceArchive ) |
| { |
| this.source = sourceArchive; |
| } |
| |
| /** |
| * Set the destination directory into which the archive should get expanded. |
| * The directory will get created if it doesn't yet exist |
| * while executing the expand. |
| * |
| * @param destinationDirectory |
| */ |
| public void setDest( File destinationDirectory ) |
| { |
| this.dest = destinationDirectory; |
| } |
| |
| /** |
| * If the destination directory should get overwritten if the content |
| * already exists. If <code>false</code> we will only overwrite if the local |
| * file or directory is older than the one in the archive. |
| * |
| * @param overwrite |
| */ |
| public void setOverwrite( boolean overwrite ) |
| { |
| this.overwrite = overwrite; |
| } |
| |
| /** |
| * Actually perform the unpacking of the source archive |
| * into the destination directory. |
| * |
| * @throws Exception |
| */ |
| public void execute() |
| throws Exception |
| { |
| expandFile( source, dest ); |
| } |
| |
| /** |
| * <p>It is intended to be overwritten when implementing an own unarchiver</p> |
| * <p/> |
| * <p><b>Note:</b> we kept this protected method for the sake of backward compatibility!</p> |
| * |
| * @param srcFile The source file. |
| * @param destination The destination. |
| * @throws Exception In case of failure. |
| */ |
| void expandFile( File srcFile, File destination ) |
| throws Exception |
| { |
| if ( source == null ) |
| { |
| throw new NullPointerException( "Source Archive must not be null!" ); |
| } |
| |
| File destDir = destination; |
| if ( destDir == null ) |
| { |
| destDir = new File( System.getProperty( "user.dir" ) ); |
| } |
| |
| ZipInputStream in = null; |
| try |
| { |
| in = new ZipInputStream( new FileInputStream( srcFile ) ); |
| |
| for ( ZipEntry zipEntry = in.getNextEntry(); zipEntry != null; zipEntry = in.getNextEntry() ) |
| { |
| String zipEntryName = zipEntry.getName(); |
| Date zipEntryDate = new Date( zipEntry.getTime() ); |
| |
| extractFile( source, destDir, in, zipEntryName, zipEntryDate, zipEntry.isDirectory() ); |
| } |
| |
| in.close(); |
| in = null; |
| } |
| finally |
| { |
| IOUtil.close( in ); |
| } |
| } |
| |
| /** |
| * Extract a single ZipEntry. |
| * <p/> |
| * <p><b>Note:</b> we kept this protected method for the sake of backward compatibility!</p> |
| * |
| * @param archive the archive to unpack |
| * @param destDir the destination dirctory |
| * @param compressedInputStream |
| * @param entryName |
| * @param entryDate |
| * @param isDirectory |
| * @throws Exception |
| */ |
| void extractFile( File archive, File destDir, InputStream compressedInputStream, String entryName, |
| Date entryDate, boolean isDirectory ) |
| throws Exception |
| { |
| File targetFile = new File( destDir, entryName ); |
| |
| if ( !targetFile.getAbsolutePath().startsWith( destDir.getAbsolutePath() ) ) |
| { |
| throw new IOException( "Entry '" + entryName + "' outside the target directory." ); |
| } |
| |
| // if overwrite is specified and the file type |
| // of the existing file does not match, then delete it |
| if ( overwrite && targetFile.exists() && targetFile.isDirectory() != isDirectory ) |
| { |
| deleteFileOrDir( targetFile ); |
| } |
| |
| if ( !targetFile.exists() || overwrite || targetFile.lastModified() <= entryDate.getTime() ) |
| { |
| if ( isDirectory ) |
| { |
| targetFile.mkdirs(); |
| } |
| else |
| { |
| byte[] buffer = new byte[BUFFER_SIZE]; |
| OutputStream out = null; |
| try |
| { |
| out = new FileOutputStream( targetFile ); |
| |
| int len; |
| while ( ( len = compressedInputStream.read( buffer ) ) >= 0 ) |
| { |
| out.write( buffer, 0, len ); |
| } |
| |
| out.close(); |
| out = null; |
| } |
| finally |
| { |
| IOUtil.close( out ); |
| } |
| targetFile.setLastModified( entryDate.getTime() ); |
| } |
| } |
| } |
| |
| /** |
| * small helper method who deletes the given directory or file. |
| * |
| * @param targetFile |
| * @throws IOException |
| */ |
| private void deleteFileOrDir( File targetFile ) |
| throws IOException |
| { |
| if ( targetFile.isDirectory() ) |
| { |
| FileUtils.deleteDirectory( targetFile ); |
| } |
| else |
| { |
| FileUtils.delete( targetFile ); |
| } |
| |
| } |
| } |