diff --git a/pom.xml b/pom.xml index 3376419fc..caf778d61 100644 --- a/pom.xml +++ b/pom.xml @@ -97,6 +97,12 @@ 1.9 runtime + + com.github.luben + zstd-jni + 1.5.2-3 + runtime + com.google.code.findbugs jsr305 diff --git a/src/main/java/org/codehaus/plexus/archiver/manager/DefaultArchiverManager.java b/src/main/java/org/codehaus/plexus/archiver/manager/DefaultArchiverManager.java index 5eea03035..884fd2dbe 100644 --- a/src/main/java/org/codehaus/plexus/archiver/manager/DefaultArchiverManager.java +++ b/src/main/java/org/codehaus/plexus/archiver/manager/DefaultArchiverManager.java @@ -110,6 +110,7 @@ String getFileExtention( @Nonnull File file ) if ( "gz".equals( archiveExt ) || "bz2".equals( archiveExt ) || "xz".equals( archiveExt ) + || "zst".equals( archiveExt ) || "snappy".equals( archiveExt ) ) { String[] tokens = StringUtils.split( path, "." ); diff --git a/src/main/java/org/codehaus/plexus/archiver/tar/PlexusIoTarZstdFileResourceCollection.java b/src/main/java/org/codehaus/plexus/archiver/tar/PlexusIoTarZstdFileResourceCollection.java new file mode 100644 index 000000000..aa084c10d --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/tar/PlexusIoTarZstdFileResourceCollection.java @@ -0,0 +1,38 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.tar; + +import javax.inject.Named; +import java.io.File; + +/** + * Alias for {@link PlexusIoTarFileResourceCollection} + */ +@Named( "tar.zst" ) +public class PlexusIoTarZstdFileResourceCollection extends PlexusIoTarFileResourceCollection +{ + + public PlexusIoTarZstdFileResourceCollection() + { + } + + @Override + protected TarFile newTarFile( File file ) + { + return new ZstdTarFile( file ); + } + +} diff --git a/src/main/java/org/codehaus/plexus/archiver/tar/TarArchiver.java b/src/main/java/org/codehaus/plexus/archiver/tar/TarArchiver.java index 8166a1f35..f63e0e5f4 100644 --- a/src/main/java/org/codehaus/plexus/archiver/tar/TarArchiver.java +++ b/src/main/java/org/codehaus/plexus/archiver/tar/TarArchiver.java @@ -31,6 +31,7 @@ import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream; +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorOutputStream; import org.codehaus.plexus.archiver.AbstractArchiver; import org.codehaus.plexus.archiver.ArchiveEntry; import org.codehaus.plexus.archiver.ArchiverException; @@ -484,7 +485,8 @@ public enum TarCompressionMethod gzip, bzip2, snappy, - xz + xz, + zstd } @@ -507,6 +509,10 @@ else if ( TarCompressionMethod.xz.equals( tarCompressionMethod ) ) { return new XZCompressorOutputStream( bufferedOutputStream( ostream ) ); } + else if ( TarCompressionMethod.zstd.equals( tarCompressionMethod ) ) + { + return new ZstdCompressorOutputStream( bufferedOutputStream( ostream ) ); + } return ostream; } diff --git a/src/main/java/org/codehaus/plexus/archiver/tar/TarUnArchiver.java b/src/main/java/org/codehaus/plexus/archiver/tar/TarUnArchiver.java index 9e68cfdf3..d88c3dd11 100644 --- a/src/main/java/org/codehaus/plexus/archiver/tar/TarUnArchiver.java +++ b/src/main/java/org/codehaus/plexus/archiver/tar/TarUnArchiver.java @@ -30,6 +30,7 @@ import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; import org.apache.commons.compress.compressors.xz.XZCompressorInputStream; +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorInputStream; import org.codehaus.plexus.archiver.AbstractUnArchiver; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.util.Streams; @@ -159,6 +160,10 @@ else if ( compression == UntarCompressionMethod.XZ ) { return new XZCompressorInputStream( istream ); } + else if ( compression == UntarCompressionMethod.ZSTD ) + { + return new ZstdCompressorInputStream( istream ); + } return istream; } @@ -172,7 +177,8 @@ public enum UntarCompressionMethod GZIP( "gzip" ), BZIP2( "bzip2" ), SNAPPY( "snappy" ), - XZ( "xz" ); + XZ( "xz" ), + ZSTD( "zstd" ); final String value; diff --git a/src/main/java/org/codehaus/plexus/archiver/tar/TarZstdUnArchiver.java b/src/main/java/org/codehaus/plexus/archiver/tar/TarZstdUnArchiver.java new file mode 100644 index 000000000..b144ccfcc --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/tar/TarZstdUnArchiver.java @@ -0,0 +1,45 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.tar; + +import javax.inject.Named; +import java.io.File; + +/** + * Extract files in tar with zstd compression + */ +@Named( "tar.zst" ) +public class TarZstdUnArchiver extends TarUnArchiver +{ + + public TarZstdUnArchiver() + { + setupCompressionMethod(); + } + + public TarZstdUnArchiver( File sourceFile ) + { + super( sourceFile ); + + setupCompressionMethod(); + } + + private final void setupCompressionMethod() + { + setCompression( UntarCompressionMethod.ZSTD ); + } + +} diff --git a/src/main/java/org/codehaus/plexus/archiver/tar/ZstdTarFile.java b/src/main/java/org/codehaus/plexus/archiver/tar/ZstdTarFile.java new file mode 100644 index 000000000..9a65686c8 --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/tar/ZstdTarFile.java @@ -0,0 +1,41 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.tar; + +import org.codehaus.plexus.archiver.zstd.ZstdUnArchiver; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +/** + * Extension of {@link org.codehaus.plexus.archiver.tar.TarFile} for zst compressed files. + */ +public class ZstdTarFile extends TarFile +{ + + public ZstdTarFile( File file ) + { + super( file ); + } + + @Override + protected InputStream getInputStream( File file ) throws IOException + { + return ZstdUnArchiver.getZstdInputStream( super.getInputStream( file ) ); + } + +} diff --git a/src/main/java/org/codehaus/plexus/archiver/zstd/PlexusIoZstdResourceCollection.java b/src/main/java/org/codehaus/plexus/archiver/zstd/PlexusIoZstdResourceCollection.java new file mode 100644 index 000000000..84a9d0e62 --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/zstd/PlexusIoZstdResourceCollection.java @@ -0,0 +1,56 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.zstd; + +import javax.inject.Named; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; + +import org.codehaus.plexus.archiver.util.Streams; +import org.codehaus.plexus.components.io.attributes.FileAttributes; +import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes; +import org.codehaus.plexus.components.io.resources.PlexusIoCompressedFileResourceCollection; + +/** + * Implementation of {@link org.codehaus.plexus.components.io.resources.PlexusIoResourceCollection} for + * zstd compressed files. + */ +@Named( "zst" ) +public class PlexusIoZstdResourceCollection extends PlexusIoCompressedFileResourceCollection +{ + + @Override + protected PlexusIoResourceAttributes getAttributes( File file ) throws IOException + { + return new FileAttributes( file, new HashMap(), new HashMap() ); + } + + @Override + protected String getDefaultExtension() + { + return ".zst"; + } + + @Override + protected InputStream getInputStream( File file ) throws IOException + { + return ZstdUnArchiver.getZstdInputStream( Streams.fileInputStream( file ) ); + } + +} diff --git a/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdArchiver.java b/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdArchiver.java new file mode 100644 index 000000000..f2484d746 --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdArchiver.java @@ -0,0 +1,90 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.zstd; + +import javax.inject.Named; + +import java.io.IOException; +import org.codehaus.plexus.archiver.AbstractArchiver; +import org.codehaus.plexus.archiver.ArchiveEntry; +import org.codehaus.plexus.archiver.ArchiverException; +import org.codehaus.plexus.archiver.ResourceIterator; +import org.codehaus.plexus.archiver.exceptions.EmptyArchiveException; + +/** + * Zstd archiver. + */ +@Named( "zst" ) +public class ZstdArchiver extends AbstractArchiver +{ + + private final ZstdCompressor compressor = new ZstdCompressor(); + + public ZstdArchiver() + { + } + + /** + * Set compression level + */ + public void setLevel( Integer level ) + throws ArchiverException + { + compressor.setLevel( level ); + } + + @Override + protected void execute() throws ArchiverException, IOException + { + if ( !checkForced() ) + { + return; + } + + ResourceIterator iter = getResources(); + if ( !iter.hasNext() ) + { + throw new EmptyArchiveException( "archive cannot be empty" ); + } + ArchiveEntry entry = iter.next(); + if ( iter.hasNext() ) + { + throw new ArchiverException( "There is more than one file in input." ); + } + compressor.setSource( entry.getResource() ); + compressor.setDestFile( getDestFile() ); + compressor.compress(); + } + + @Override + public boolean isSupportingForced() + { + return true; + } + + @Override + protected void close() throws IOException + { + compressor.close(); + } + + @Override + protected String getArchiveType() + { + return "zstd"; + } + +} diff --git a/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdCompressor.java b/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdCompressor.java new file mode 100644 index 000000000..4dc06d2ea --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdCompressor.java @@ -0,0 +1,86 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.zstd; + +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorOutputStream; +import org.codehaus.plexus.archiver.ArchiverException; +import org.codehaus.plexus.archiver.util.Compressor; + +import java.io.BufferedOutputStream; +import java.io.IOException; + +import static org.codehaus.plexus.archiver.util.Streams.bufferedOutputStream; +import static org.codehaus.plexus.archiver.util.Streams.fileOutputStream; + +/** + * Zstd compression + */ +public class ZstdCompressor extends Compressor +{ + + private Integer level; + + private ZstdCompressorOutputStream zstdOut; + + public ZstdCompressor() + { + } + + public void setLevel( Integer level ) + { + this.level = level; + } + + @Override + public void compress() throws ArchiverException + { + try + { + BufferedOutputStream outStream = bufferedOutputStream( fileOutputStream( getDestFile() ) ); + if (level == null) + { + zstdOut = new ZstdCompressorOutputStream( outStream ); + } + else + { + zstdOut = new ZstdCompressorOutputStream( outStream, level ); + } + compress( getSource(), zstdOut); + } + catch ( IOException ioe ) + { + throw new ArchiverException( "Problem creating zstd " + ioe.getMessage(), ioe ); + } + } + + @Override + public void close() + { + try + { + if ( this.zstdOut != null ) + { + this.zstdOut.close(); + zstdOut = null; + } + } + catch ( final IOException e ) + { + throw new ArchiverException( "Failure closing target.", e ); + } + } + +} diff --git a/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdUnArchiver.java b/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdUnArchiver.java new file mode 100644 index 000000000..7dcf6c1f5 --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/zstd/ZstdUnArchiver.java @@ -0,0 +1,86 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.zstd; + +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorInputStream; +import org.codehaus.plexus.archiver.AbstractUnArchiver; +import org.codehaus.plexus.archiver.ArchiverException; + +import javax.annotation.Nonnull; +import javax.inject.Named; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import static org.codehaus.plexus.archiver.util.Streams.bufferedInputStream; +import static org.codehaus.plexus.archiver.util.Streams.bufferedOutputStream; +import static org.codehaus.plexus.archiver.util.Streams.copyFully; +import static org.codehaus.plexus.archiver.util.Streams.fileInputStream; +import static org.codehaus.plexus.archiver.util.Streams.fileOutputStream; + +/** + * Unarchiver for zstd-compressed files. + */ +@Named( "zst" ) +public class ZstdUnArchiver extends AbstractUnArchiver +{ + + private static final String OPERATION_ZSTD = "zstd"; + + public ZstdUnArchiver() + { + } + + public ZstdUnArchiver( File source ) + { + super( source ); + } + + @Override + protected void execute() throws ArchiverException + { + if ( getSourceFile().lastModified() > getDestFile().lastModified() ) + { + getLogger().info( "Expanding " + getSourceFile().getAbsolutePath() + " to " + + getDestFile().getAbsolutePath() ); + + copyFully( getZstdInputStream( bufferedInputStream( fileInputStream( getSourceFile(), OPERATION_ZSTD) ) ), + bufferedOutputStream( fileOutputStream( getDestFile(), OPERATION_ZSTD) ), OPERATION_ZSTD); + + } + } + + public static @Nonnull + ZstdCompressorInputStream getZstdInputStream( InputStream in ) + throws ArchiverException + { + try + { + return new ZstdCompressorInputStream( in ); + } + catch ( IOException ioe ) + { + throw new ArchiverException( "Trouble creating Zstd compressor, invalid file ?", ioe ); + } + } + + @Override + protected void execute( String path, File outputDirectory ) throws ArchiverException + { + throw new UnsupportedOperationException( "Targeted execution not supported in zstd format" ); + } + +} diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt index 747c47982..f12f3c60a 100644 --- a/src/site/apt/index.apt +++ b/src/site/apt/index.apt @@ -24,6 +24,7 @@ Plexus Archiver | | {{{./xref/org/codehaus/plexus/archiver/jar/JarArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/snappy/SnappyArchiver.html}<<>>}}, +| | {{{./xref/org/codehaus/plexus/archiver/zstandard/ZstdArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/tar/TarArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/war/WarArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/zip/ZipArchiver.html}<<>>}}. @@ -34,11 +35,13 @@ Plexus Archiver | | {{{./xref/org/codehaus/plexus/archiver/xz.XZUnArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/gzip.GZipUnArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/snappy.SnappyUnArchiver.html}<<>>}}, +| | {{{./xref/org/codehaus/plexus/archiver/zstandard.ZstdUnArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/tar.TarUnArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/zip.ZipUnArchiver.html}<<>>}} | | (also available as <<>>, <<>>, <<>>, <<>>, <<>>, <<>>, <<>>, <<>>, <<>>, <<>>), | | {{{./xref/org/codehaus/plexus/archiver/tar.TarGZipUnArchiver.html}<<>>}} or <<>>, | | {{{./xref/org/codehaus/plexus/archiver/tar.TarBZip2UnArchiver.html}<<>>}} or <<>>, | | {{{./xref/org/codehaus/plexus/archiver/tar.TarXZUnArchiver.html}<<>>}} or <<>>, +| | {{{./xref/org/codehaus/plexus/archiver/tar.TarZstdUnArchiver.html}<<>>}}, | | {{{./xref/org/codehaus/plexus/archiver/tar.TarSnappyUnArchiver.html}<<>>}}. *------------------+-----------------+ diff --git a/src/test/java/org/codehaus/plexus/archiver/tar/TarZstdUnArchiverTest.java b/src/test/java/org/codehaus/plexus/archiver/tar/TarZstdUnArchiverTest.java new file mode 100644 index 000000000..061449647 --- /dev/null +++ b/src/test/java/org/codehaus/plexus/archiver/tar/TarZstdUnArchiverTest.java @@ -0,0 +1,89 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.tar; + +import java.io.File; +import org.codehaus.plexus.archiver.Archiver; +import org.codehaus.plexus.archiver.TestSupport; +import org.codehaus.plexus.archiver.UnArchiver; +import org.codehaus.plexus.archiver.zstd.ZstdArchiver; +import org.codehaus.plexus.util.FileUtils; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TarZstdUnArchiverTest extends TestSupport +{ + + @Test + public void testExtract() + throws Exception + { + TarArchiver tarArchiver = (TarArchiver) lookup( Archiver.class, "tar" ); + tarArchiver.setLongfile( TarLongFileMode.posix ); + + String fileName1 = "TarBZip2UnArchiverTest1.txt"; + String fileName2 = "TarBZip2UnArchiverTest2.txt"; + File file1InTar = getTestFile( "target/output/" + fileName1 ); + File file2InTar = getTestFile( "target/output/" + fileName2 ); + file1InTar.delete(); + file2InTar.delete(); + + assertFalse( file1InTar.exists() ); + assertFalse( file2InTar.exists() ); + + File testZstdFile = getTestFile( "target/output/archive.tar.zst" ); + if ( testZstdFile.exists() ) + { + FileUtils.fileDelete( testZstdFile.getPath() ); + } + assertFalse( testZstdFile.exists() ); + + tarArchiver.addFile( getTestFile( "src/test/resources/manifests/manifest1.mf" ), fileName1 ); + tarArchiver.addFile( getTestFile( "src/test/resources/manifests/manifest2.mf" ), fileName2, 0664 ); + tarArchiver.setDestFile( getTestFile( "target/output/archive.tar" ) ); + tarArchiver.createArchive(); + + ZstdArchiver zstdArchiver = (ZstdArchiver) lookup( Archiver.class, "zst" ); + + zstdArchiver.setDestFile( testZstdFile ); + zstdArchiver.addFile( getTestFile( "target/output/archive.tar" ), "dontcare" ); + zstdArchiver.createArchive(); + + assertTrue( testZstdFile.exists() ); + + TarZstdUnArchiver tarZstdUnArchiver = (TarZstdUnArchiver) lookup( UnArchiver.class, "tar.zst" ); + + tarZstdUnArchiver.setDestDirectory( getTestFile( "target/output" ) ); + tarZstdUnArchiver.setSourceFile( testZstdFile ); + tarZstdUnArchiver.extract(); + + assertTrue( file1InTar.exists() ); + assertTrue( file2InTar.exists() ); + + assertEquals( testZstdFile, tarZstdUnArchiver.getSourceFile() ); + } + + @Test + public void testLookup() throws Exception + { + assertNotNull( lookup( UnArchiver.class, "tar.zst" ) ); + } + +} diff --git a/src/test/java/org/codehaus/plexus/archiver/zstd/ZstdArchiverTest.java b/src/test/java/org/codehaus/plexus/archiver/zstd/ZstdArchiverTest.java new file mode 100644 index 000000000..eed3367e2 --- /dev/null +++ b/src/test/java/org/codehaus/plexus/archiver/zstd/ZstdArchiverTest.java @@ -0,0 +1,152 @@ +/* + * Copyright 2022 The Apache Software Foundation + * + * Licensed 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. + */ +package org.codehaus.plexus.archiver.zstd; + +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.codehaus.plexus.archiver.Archiver; +import org.codehaus.plexus.archiver.BasePlexusArchiverTest; +import org.codehaus.plexus.archiver.exceptions.EmptyArchiveException; +import org.codehaus.plexus.archiver.zip.ZipArchiver; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.IOUtil; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +public class ZstdArchiverTest extends BasePlexusArchiverTest +{ + + @Test + public void testCreateArchive() + throws Exception + { + ZipArchiver zipArchiver = (ZipArchiver) lookup( Archiver.class, "zip" ); + zipArchiver.addDirectory( getTestFile( "src" ) ); + zipArchiver.setDestFile( getTestFile( "target/output/archiveForxz.zip" ) ); + zipArchiver.createArchive(); + + ZstdArchiver archiver = (ZstdArchiver) lookup( Archiver.class, "zst" ); + String[] inputFiles = new String[ 1 ]; + inputFiles[0] = "archiveForxz.zip"; + + File targetOutputFile = getTestFile( "target/output/archive.zst" ); + if ( targetOutputFile.exists() ) + { + FileUtils.fileDelete( targetOutputFile.getPath() ); + } + assertFalse( targetOutputFile.exists() ); + + archiver.addDirectory( getTestFile( "target/output" ), inputFiles, null ); + archiver.setDestFile( targetOutputFile ); + archiver.createArchive(); + + assertTrue( targetOutputFile.exists() ); + } + + @Test + public void testCreateEmptyArchive() + throws Exception + { + ZstdArchiver archiver = (ZstdArchiver) lookup( Archiver.class, "zst" ); + archiver.setDestFile( getTestFile( "target/output/empty.zst" ) ); + try + { + archiver.createArchive(); + + fail( "Creating empty archive should throw EmptyArchiveException" ); + } + catch ( EmptyArchiveException ignore ) + { + } + } + + @Test + public void testCreateResourceCollection() throws Exception + { + final File pomFile = new File( "pom.xml" ); + final File zstFile = new File( "target/output/pom.xml.zst" ); + ZstdArchiver zstdArchiver = (ZstdArchiver) lookup( Archiver.class, "zst" ); + zstdArchiver.setDestFile( zstFile ); + zstdArchiver.addFile( pomFile, "pom.xml" ); + FileUtils.removePath( zstFile.getPath() ); + zstdArchiver.createArchive(); + + System.out.println( "Created: " + zstFile.getAbsolutePath() ); + + final File zipFile = new File( "target/output/pomxz.zip" ); + ZipArchiver zipArchiver = (ZipArchiver) lookup( Archiver.class, "zip" ); + zipArchiver.setDestFile( zipFile ); + zipArchiver.addArchivedFileSet( zstFile, "prfx/" ); + FileUtils.removePath( zipFile.getPath() ); + zipArchiver.createArchive(); + + final ZipFile juZipFile = new ZipFile( zipFile ); + final ZipEntry zipEntry = juZipFile.getEntry( "prfx/target/output/pom.xml" ); + final InputStream archivePom = juZipFile.getInputStream( zipEntry ); + final InputStream pom = Files.newInputStream( pomFile.toPath() ); + + assertTrue( Arrays.equals( IOUtil.toByteArray( pom ), IOUtil.toByteArray( archivePom ) ) ); + archivePom.close(); + pom.close(); + juZipFile.close(); + } + + /** + * Tests the .std archiver is forced set to true, and after that + * tests the behavior when the forced is set to false. + * + * @throws Exception + */ + @Test + public void testZstIsForcedBehaviour() throws Exception + { + ZstdArchiver zstdArchiver = (ZstdArchiver) createArchiver( "zst" ); + + assertTrue( zstdArchiver.isSupportingForced() ); + zstdArchiver.createArchive(); + + final long creationTime = zstdArchiver.getDestFile().lastModified(); + + waitUntilNewTimestamp( zstdArchiver.getDestFile(), creationTime ); + + zstdArchiver = (ZstdArchiver) createArchiver( "zst" ); + + zstdArchiver.setForced( true ); + zstdArchiver.createArchive(); + + final long firstRunTime = zstdArchiver.getDestFile().lastModified(); + + assertFalse( creationTime == firstRunTime ); + + zstdArchiver = (ZstdArchiver) createArchiver( "zst" ); + + zstdArchiver.setForced( false ); + zstdArchiver.createArchive(); + + final long secondRunTime = zstdArchiver.getDestFile().lastModified(); + + assertEquals( firstRunTime, secondRunTime ); + } + +}