Adding unzip utility method

This commit is contained in:
Martin Stockhammer 2019-10-14 21:42:59 +02:00
parent aaa8b6ec2b
commit 7c683efd5d
5 changed files with 119 additions and 250 deletions

View File

@ -47,10 +47,6 @@
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.sisu</groupId>
<artifactId>org.eclipse.sisu.plexus</artifactId>
</dependency>
<dependency> <dependency>
@ -69,6 +65,12 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<pluginManagement> <pluginManagement>

View File

@ -21,8 +21,7 @@ package org.apache.archiva.common.utils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.*;
import java.io.UncheckedIOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -30,115 +29,96 @@ import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.Comparator; import java.util.Comparator;
import java.util.Optional; import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/** /**
*
* Utility class for file manipulation * Utility class for file manipulation
* *
* @author Martin Stockhammer <martin_s@apache.org> * @author Martin Stockhammer <martin_s@apache.org>
*/ */
public class FileUtils public class FileUtils {
{ private static final Logger log = LoggerFactory.getLogger(FileUtils.class);
private static final Logger log = LoggerFactory.getLogger( FileUtils.class );
/** /**
* Deletes the directory recursively and quietly. * Deletes the directory recursively and quietly.
* *
* @param dir * @param dir
*/ */
public static void deleteQuietly(Path dir) { public static void deleteQuietly(Path dir) {
try try {
{
Files.walk(dir) Files.walk(dir)
.sorted( Comparator.reverseOrder()) .sorted(Comparator.reverseOrder())
.forEach( file -> { .forEach(file -> {
try try {
{ Files.delete(file);
Files.delete( file ); } catch (IOException e) {
} // Ignore this
catch ( IOException e ) }
{
// Ignore this
}
}); });
} } catch (IOException e) {
catch ( IOException e )
{
// Ignore this // Ignore this
} }
} }
public static void deleteDirectory( Path dir ) throws IOException public static void deleteDirectory(Path dir) throws IOException {
{
if (!Files.exists(dir)) { if (!Files.exists(dir)) {
return; return;
} }
if (!Files.isDirectory( dir )) { if (!Files.isDirectory(dir)) {
throw new IOException("Given path is not a directory "+dir); throw new IOException("Given path is not a directory " + dir);
} }
boolean result = true; boolean result = true;
try try {
{ result = Files.walk(dir)
result = Files.walk( dir ) .sorted(Comparator.reverseOrder())
.sorted( Comparator.reverseOrder( ) ) .map(file ->
.map( file ->
{
try
{ {
Files.delete( file ); try {
return Optional.of( Boolean.TRUE ); Files.delete(file);
} return Optional.of(Boolean.TRUE);
catch ( UncheckedIOException | IOException e ) } catch (UncheckedIOException | IOException e) {
{ log.warn("File could not be deleted {}", file);
log.warn( "File could not be deleted {}", file ); return Optional.empty();
return Optional.empty( ); }
}
} ).allMatch( Optional::isPresent ); }).allMatch(Optional::isPresent);
} catch (UncheckedIOException e) { } catch (UncheckedIOException e) {
throw new IOException("File deletion failed ", e); throw new IOException("File deletion failed ", e);
} }
if (!result) { if (!result) {
throw new IOException("Error during recursive delete of "+dir.toAbsolutePath()); throw new IOException("Error during recursive delete of " + dir.toAbsolutePath());
} }
} }
public static String readFileToString( Path file, Charset encoding) public static String readFileToString(Path file, Charset encoding) {
{ try {
try return new String(Files.readAllBytes(file), encoding);
{ } catch (IOException e) {
return new String(Files.readAllBytes( file ), encoding );
}
catch ( IOException e )
{
log.error("Could not read from file {}", file); log.error("Could not read from file {}", file);
return ""; return "";
} }
} }
public static void writeStringToFile( Path file, Charset encoding, String value ) public static void writeStringToFile(Path file, Charset encoding, String value) {
{ try {
try Files.write(file, value.getBytes(encoding), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
{ } catch (IOException e) {
Files.write( file, value.getBytes( encoding ), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
catch ( IOException e )
{
log.error("Could not write to file {}", file); log.error("Could not write to file {}", file);
} }
} }
/** /**
* Return the base directory * Return the base directory
*
* @return * @return
*/ */
public static String getBasedir() public static String getBasedir() {
{ String basedir = System.getProperty("basedir");
String basedir = System.getProperty( "basedir" ); if (basedir == null) {
if ( basedir == null )
{
basedir = Paths.get("").toAbsolutePath().toString(); basedir = Paths.get("").toAbsolutePath().toString();
} }
@ -150,15 +130,56 @@ public class FileUtils
* the relative path is used. * the relative path is used.
* *
* @param parent The parent directory * @param parent The parent directory
* @param child The child * @param child The child
* @return The path parent/child * @return The path parent/child
*/ */
public Path resolveNonAbsolute(Path parent, String child) { public Path resolveNonAbsolute(Path parent, String child) {
Path childPath = Paths.get(child); Path childPath = Paths.get(child);
if (childPath.isAbsolute()) { if (childPath.isAbsolute()) {
return parent.resolve(childPath.getNameCount()>0 ? childPath.subpath(0, childPath.getNameCount()) : Paths.get("")); return parent.resolve(childPath.getNameCount() > 0 ? childPath.subpath(0, childPath.getNameCount()) : Paths.get(""));
} else { } else {
return parent.resolve(child); return parent.resolve(child);
} }
} }
public static void unzipFileEntry(ZipFile file, ZipEntry entry, Path destinationPath) throws IOException {
InputStream is = file.getInputStream(entry);
BufferedInputStream bis = new BufferedInputStream(is);
Path uncompressedFilePath = destinationPath.resolve(entry.getName());
Path parentPath = uncompressedFilePath.getParent();
if (!Files.exists(parentPath)) {
Files.createDirectories(parentPath);
}
Files.createFile(uncompressedFilePath);
OutputStream fileOutput = Files.newOutputStream(uncompressedFilePath);
while (bis.available() > 0) {
fileOutput.write(bis.read());
}
fileOutput.close();
}
/**
* Unzips a file into a destination directory. It does not update the modification time according the
* the date in the zip file. All subdirectories will be created if the zip file contains a directory structure.
*
* @param zipFile the path to the zip file
* @param destinationPath the destination path where the files should be extracted.
* @throws IOException if an error occurs during extract.
*/
public static void unzip(Path zipFile, Path destinationPath) throws IOException {
try (ZipFile file = new ZipFile(zipFile.toFile())) {
file.stream().forEach(e -> {
try {
if (e.isDirectory()) {
Files.createDirectories(destinationPath.resolve(e.getName()));
} else {
unzipFileEntry(file, e, destinationPath);
}
} catch (IOException ex) {
log.error("Error occured during unzip of zipFile={}, entry={}. Message: {}", zipFile, e.getName(), ex.getMessage());
}
});
}
}
} }

View File

@ -1,180 +0,0 @@
package org.apache.archiva.common.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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Slf4JPlexusLogger - temporary logger to provide an Slf4j Logger to those components
* outside of the archiva codebase that require a plexus logger.
*
*
*/
public class Slf4JPlexusLogger
implements org.codehaus.plexus.logging.Logger
{
private final Logger log;
public Slf4JPlexusLogger( Class<?> clazz )
{
log = LoggerFactory.getLogger( clazz );
}
public Slf4JPlexusLogger( String name )
{
log = LoggerFactory.getLogger( name );
}
@Override
public void debug( String message )
{
log.debug( message );
}
@Override
public void debug( String message, Throwable throwable )
{
log.debug( message, throwable );
}
@Override
public void error( String message )
{
log.error( message );
}
@Override
public void error( String message, Throwable throwable )
{
log.error( message, throwable );
}
@Override
public void fatalError( String message )
{
log.error( message );
}
@Override
public void fatalError( String message, Throwable throwable )
{
log.error( message, throwable );
}
@Override
public org.codehaus.plexus.logging.Logger getChildLogger( String name )
{
return new Slf4JPlexusLogger( log.getName() + "." + name );
}
@Override
public String getName()
{
return log.getName();
}
@Override
public int getThreshold()
{
if ( log.isTraceEnabled() )
{
return org.codehaus.plexus.logging.Logger.LEVEL_DEBUG;
}
else if ( log.isDebugEnabled() )
{
return org.codehaus.plexus.logging.Logger.LEVEL_DEBUG;
}
else if ( log.isInfoEnabled() )
{
return org.codehaus.plexus.logging.Logger.LEVEL_INFO;
}
else if ( log.isWarnEnabled() )
{
return org.codehaus.plexus.logging.Logger.LEVEL_WARN;
}
else if ( log.isErrorEnabled() )
{
return org.codehaus.plexus.logging.Logger.LEVEL_ERROR;
}
return org.codehaus.plexus.logging.Logger.LEVEL_DISABLED;
}
@Override
public void info( String message )
{
log.info( message );
}
@Override
public void info( String message, Throwable throwable )
{
log.info( message, throwable );
}
@Override
public boolean isDebugEnabled()
{
return log.isDebugEnabled();
}
@Override
public boolean isErrorEnabled()
{
return log.isErrorEnabled();
}
@Override
public boolean isFatalErrorEnabled()
{
return log.isErrorEnabled();
}
@Override
public boolean isInfoEnabled()
{
return log.isInfoEnabled();
}
@Override
public boolean isWarnEnabled()
{
return log.isWarnEnabled();
}
@Override
public void setThreshold( int threshold )
{
/* do nothing */
}
@Override
public void warn( String message )
{
log.warn( message );
}
@Override
public void warn( String message, Throwable throwable )
{
log.warn( message, throwable );
}
}

View File

@ -24,6 +24,7 @@ import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URISyntaxException;
import java.nio.file.FileSystems; import java.nio.file.FileSystems;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -156,4 +157,29 @@ public class FileUtilsTest
} }
} }
@Test
public void unzip() throws URISyntaxException, IOException {
Path destPath = Paths.get("target/unzip");
try {
Path zipFile = Paths.get(Thread.currentThread().getContextClassLoader().getResource("test-repository.zip").toURI());
if (Files.exists(destPath)) {
org.apache.commons.io.FileUtils.deleteQuietly(destPath.toFile());
}
FileUtils.unzip(zipFile, destPath);
assertTrue(Files.exists(destPath.resolve("org/apache/maven/A/1.0/A-1.0.pom")));
assertTrue(Files.isRegularFile(destPath.resolve("org/apache/maven/A/1.0/A-1.0.pom")));
assertTrue(Files.exists(destPath.resolve("org/apache/maven/A/1.0/A-1.0.war")));
assertTrue(Files.isRegularFile(destPath.resolve("org/apache/maven/A/1.0/A-1.0.war")));
assertTrue(Files.exists(destPath.resolve("org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar")));
assertTrue(Files.isRegularFile(destPath.resolve("org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar")));
assertTrue(Files.exists(destPath.resolve("KEYS")));
assertTrue(Files.isRegularFile(destPath.resolve("KEYS")));
assertTrue(Files.isDirectory(destPath.resolve("invalid")));
assertTrue(Files.isDirectory(destPath.resolve("javax")));
assertTrue(Files.isDirectory(destPath.resolve("org")));
} finally {
org.apache.commons.io.FileUtils.deleteQuietly(destPath.toFile());
}
}
} }