@@ -47,10 +47,6 @@ | |||
<groupId>org.slf4j</groupId> | |||
<artifactId>slf4j-api</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.eclipse.sisu</groupId> | |||
<artifactId>org.eclipse.sisu.plexus</artifactId> | |||
</dependency> | |||
<dependency> | |||
@@ -69,6 +65,12 @@ | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>commons-io</groupId> | |||
<artifactId>commons-io</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<pluginManagement> |
@@ -21,8 +21,7 @@ package org.apache.archiva.common.utils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.IOException; | |||
import java.io.UncheckedIOException; | |||
import java.io.*; | |||
import java.nio.charset.Charset; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
@@ -30,115 +29,96 @@ import java.nio.file.Paths; | |||
import java.nio.file.StandardOpenOption; | |||
import java.util.Comparator; | |||
import java.util.Optional; | |||
import java.util.zip.ZipEntry; | |||
import java.util.zip.ZipFile; | |||
/** | |||
* | |||
* Utility class for file manipulation | |||
* | |||
* @author Martin Stockhammer <martin_s@apache.org> | |||
*/ | |||
public class FileUtils | |||
{ | |||
private static final Logger log = LoggerFactory.getLogger( FileUtils.class ); | |||
public class FileUtils { | |||
private static final Logger log = LoggerFactory.getLogger(FileUtils.class); | |||
/** | |||
* Deletes the directory recursively and quietly. | |||
* | |||
* @param dir | |||
*/ | |||
public static void deleteQuietly(Path dir) { | |||
try | |||
{ | |||
try { | |||
Files.walk(dir) | |||
.sorted( Comparator.reverseOrder()) | |||
.forEach( file -> { | |||
try | |||
{ | |||
Files.delete( file ); | |||
} | |||
catch ( IOException e ) | |||
{ | |||
// Ignore this | |||
} | |||
.sorted(Comparator.reverseOrder()) | |||
.forEach(file -> { | |||
try { | |||
Files.delete(file); | |||
} catch (IOException e) { | |||
// Ignore this | |||
} | |||
}); | |||
} | |||
catch ( IOException e ) | |||
{ | |||
}); | |||
} catch (IOException e) { | |||
// Ignore this | |||
} | |||
} | |||
public static void deleteDirectory( Path dir ) throws IOException | |||
{ | |||
public static void deleteDirectory(Path dir) throws IOException { | |||
if (!Files.exists(dir)) { | |||
return; | |||
} | |||
if (!Files.isDirectory( dir )) { | |||
throw new IOException("Given path is not a directory "+dir); | |||
if (!Files.isDirectory(dir)) { | |||
throw new IOException("Given path is not a directory " + dir); | |||
} | |||
boolean result = true; | |||
try | |||
{ | |||
result = Files.walk( dir ) | |||
.sorted( Comparator.reverseOrder( ) ) | |||
.map( file -> | |||
{ | |||
try | |||
try { | |||
result = Files.walk(dir) | |||
.sorted(Comparator.reverseOrder()) | |||
.map(file -> | |||
{ | |||
Files.delete( file ); | |||
return Optional.of( Boolean.TRUE ); | |||
} | |||
catch ( UncheckedIOException | IOException e ) | |||
{ | |||
log.warn( "File could not be deleted {}", file ); | |||
return Optional.empty( ); | |||
} | |||
try { | |||
Files.delete(file); | |||
return Optional.of(Boolean.TRUE); | |||
} catch (UncheckedIOException | IOException e) { | |||
log.warn("File could not be deleted {}", file); | |||
return Optional.empty(); | |||
} | |||
} ).allMatch( Optional::isPresent ); | |||
}).allMatch(Optional::isPresent); | |||
} catch (UncheckedIOException e) { | |||
throw new IOException("File deletion failed ", e); | |||
} | |||
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) | |||
{ | |||
try | |||
{ | |||
return new String(Files.readAllBytes( file ), encoding ); | |||
} | |||
catch ( IOException e ) | |||
{ | |||
public static String readFileToString(Path file, Charset encoding) { | |||
try { | |||
return new String(Files.readAllBytes(file), encoding); | |||
} catch (IOException e) { | |||
log.error("Could not read from file {}", file); | |||
return ""; | |||
} | |||
} | |||
public static void writeStringToFile( Path file, Charset encoding, String value ) | |||
{ | |||
try | |||
{ | |||
Files.write( file, value.getBytes( encoding ), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); | |||
} | |||
catch ( IOException e ) | |||
{ | |||
public static void writeStringToFile(Path file, Charset encoding, String value) { | |||
try { | |||
Files.write(file, value.getBytes(encoding), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); | |||
} catch (IOException e) { | |||
log.error("Could not write to file {}", file); | |||
} | |||
} | |||
/** | |||
* Return the base directory | |||
* | |||
* @return | |||
*/ | |||
public static String getBasedir() | |||
{ | |||
String basedir = System.getProperty( "basedir" ); | |||
if ( basedir == null ) | |||
{ | |||
public static String getBasedir() { | |||
String basedir = System.getProperty("basedir"); | |||
if (basedir == null) { | |||
basedir = Paths.get("").toAbsolutePath().toString(); | |||
} | |||
@@ -150,15 +130,56 @@ public class FileUtils | |||
* the relative path is used. | |||
* | |||
* @param parent The parent directory | |||
* @param child The child | |||
* @param child The child | |||
* @return The path parent/child | |||
*/ | |||
public Path resolveNonAbsolute(Path parent, String child) { | |||
Path childPath = Paths.get(child); | |||
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 { | |||
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()); | |||
} | |||
}); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} |
@@ -24,6 +24,7 @@ import org.junit.Test; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.net.URISyntaxException; | |||
import java.nio.file.FileSystems; | |||
import java.nio.file.Files; | |||
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()); | |||
} | |||
} | |||
} |