diff --git a/src/main/java/org/codehaus/plexus/archiver/tar/PlexusIoTarFileResourceCollection.java b/src/main/java/org/codehaus/plexus/archiver/tar/PlexusIoTarFileResourceCollection.java index 3e79f7b92..c79efa649 100644 --- a/src/main/java/org/codehaus/plexus/archiver/tar/PlexusIoTarFileResourceCollection.java +++ b/src/main/java/org/codehaus/plexus/archiver/tar/PlexusIoTarFileResourceCollection.java @@ -54,7 +54,9 @@ public boolean hasNext() public PlexusIoResource next() { final TarArchiveEntry entry = (TarArchiveEntry) en.nextElement(); - return new TarResource( tarFile, entry ); + return !entry.isSymbolicLink() + ? new TarResource( tarFile, entry ) + : new TarSymlinkResource( tarFile, entry ); } public void remove() diff --git a/src/main/java/org/codehaus/plexus/archiver/tar/TarSymlinkResource.java b/src/main/java/org/codehaus/plexus/archiver/tar/TarSymlinkResource.java new file mode 100644 index 000000000..9ac6f13e7 --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/tar/TarSymlinkResource.java @@ -0,0 +1,32 @@ +package org.codehaus.plexus.archiver.tar; + +import java.io.IOException; + +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier; + +/** + * A {@link TarResource} that represents symbolic link. + */ +public class TarSymlinkResource + extends TarResource + implements SymlinkDestinationSupplier +{ + private final String symlinkDestination; + + public TarSymlinkResource(TarFile tarFile, TarArchiveEntry entry) { + super(tarFile, entry); + symlinkDestination = entry.getLinkName(); + } + + @Override + public String getSymlinkDestination() throws IOException { + return symlinkDestination; + } + + @Override + public boolean isSymbolicLink() { + return true; + } + +} diff --git a/src/main/java/org/codehaus/plexus/archiver/zip/PlexusArchiverZipFileResourceCollection.java b/src/main/java/org/codehaus/plexus/archiver/zip/PlexusArchiverZipFileResourceCollection.java index 6f723a910..80d6bb670 100644 --- a/src/main/java/org/codehaus/plexus/archiver/zip/PlexusArchiverZipFileResourceCollection.java +++ b/src/main/java/org/codehaus/plexus/archiver/zip/PlexusArchiverZipFileResourceCollection.java @@ -57,7 +57,9 @@ public PlexusIoResource next() { final ZipArchiveEntry entry = (ZipArchiveEntry) en.nextElement(); - return new ZipResource( zipFile, entry, getStreamTransformer() ); + return !entry.isUnixSymlink() + ? new ZipResource( zipFile, entry, getStreamTransformer() ) + : new ZipSymlinkResource( zipFile, entry, getStreamTransformer() ); } public void remove() diff --git a/src/main/java/org/codehaus/plexus/archiver/zip/ZipSymlinkResource.java b/src/main/java/org/codehaus/plexus/archiver/zip/ZipSymlinkResource.java new file mode 100644 index 000000000..52b01318b --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/zip/ZipSymlinkResource.java @@ -0,0 +1,41 @@ +package org.codehaus.plexus.archiver.zip; + +import java.io.IOException; + +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.codehaus.plexus.components.io.functions.InputStreamTransformer; +import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier; + +/** + * A {@link ZipResource} that represents symbolic link. + */ +public class ZipSymlinkResource + extends ZipResource + implements SymlinkDestinationSupplier +{ + private final String symlinkDestination; + + public ZipSymlinkResource(ZipFile zipFile, ZipArchiveEntry entry, InputStreamTransformer streamTransformer) + { + super(zipFile, entry, streamTransformer); + try { + symlinkDestination = zipFile.getUnixSymlink(entry); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public String getSymlinkDestination() throws IOException + { + return symlinkDestination; + } + + @Override + public boolean isSymbolicLink() + { + return true; + } + +} diff --git a/src/test/java/org/codehaus/plexus/archiver/tar/TarArchiverTest.java b/src/test/java/org/codehaus/plexus/archiver/tar/TarArchiverTest.java index cf3d0a190..f982c7a21 100644 --- a/src/test/java/org/codehaus/plexus/archiver/tar/TarArchiverTest.java +++ b/src/test/java/org/codehaus/plexus/archiver/tar/TarArchiverTest.java @@ -34,6 +34,7 @@ import org.codehaus.plexus.archiver.gzip.GZipCompressor; import org.codehaus.plexus.archiver.util.ArchiveEntryUtils; import org.codehaus.plexus.archiver.util.Compressor; +import org.codehaus.plexus.archiver.util.DefaultArchivedFileSet; import org.codehaus.plexus.archiver.zip.ArchiveFileComparator; import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributeUtils; import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes; @@ -533,4 +534,21 @@ private void testCreateResourceCollection( TarHandler tarHandler ) cmp1.close(); cmp2.close(); } + + public void testSymlinkArchivedFileSet() + throws Exception + { + final File tarFile = getTestFile( "src/test/resources/symlinks/symlinks.tar" ); + final File tarFile2 = getTestFile( "target/output/pasymlinks-archivedFileset.tar" ); + final TarArchiver tarArchiver = getPosixTarArchiver(); + tarArchiver.setDestFile( tarFile2 ); + DefaultArchivedFileSet archivedFileSet = DefaultArchivedFileSet.archivedFileSet( tarFile ); + archivedFileSet.setUsingDefaultExcludes( false ); + tarArchiver.addArchivedFileSet( archivedFileSet ); + tarArchiver.createArchive(); + + final TarFile cmp1 = new TarFile( tarFile ); + final TarFile cmp2 = new TarFile( tarFile2 ); + ArchiveFileComparator.assertEquals( cmp1, cmp2, "" ); + } } diff --git a/src/test/java/org/codehaus/plexus/archiver/zip/ArchiveFileComparator.java b/src/test/java/org/codehaus/plexus/archiver/zip/ArchiveFileComparator.java index 12b37c545..a17a40f5b 100644 --- a/src/test/java/org/codehaus/plexus/archiver/zip/ArchiveFileComparator.java +++ b/src/test/java/org/codehaus/plexus/archiver/zip/ArchiveFileComparator.java @@ -83,6 +83,7 @@ private static void assertEquals( ArchiveFile file1, TarArchiveEntry entry1, throws IOException { Assert.assertEquals( entry1.isDirectory(), entry2.isDirectory() ); + Assert.assertEquals( entry1.isSymbolicLink(), entry2.isSymbolicLink() ); Assert.assertEquals( entry1.getModTime().getTime(), entry2.getModTime().getTime() ); final InputStream is1 = file1.getInputStream( entry1 ); @@ -98,7 +99,9 @@ private static void assertEquals( ZipFile file1, ZipArchiveEntry entry1, throws Exception { Assert.assertEquals( entry1.isDirectory(), entry2.isDirectory() ); - Assert.assertEquals( entry1.getLastModifiedDate().getTime(), entry2.getLastModifiedDate().getTime() ); + Assert.assertEquals( entry1.isUnixSymlink(), entry2.isUnixSymlink() ); + long timeDelta = entry1.getLastModifiedDate().getTime() - entry2.getLastModifiedDate().getTime(); + Assert.assertTrue( Math.abs( timeDelta ) <= 1000 ); final InputStream is1 = file1.getInputStream( entry1 ); final InputStream is2 = file2.getInputStream( entry2 ); diff --git a/src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java b/src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java index a561e2bab..67a50b81c 100644 --- a/src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java +++ b/src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java @@ -533,6 +533,20 @@ public void testSymlinkFileSet() assertTrue( fa.isSymbolicLink() ); } + public void testSymlinkArchivedFileSet() + throws Exception + { + final File zipFile = getTestFile( "src/test/resources/symlinks/symlinks.zip" ); + final File zipFile2 = getTestFile( "target/output/pasymlinks-archivedFileset.zip" ); + final ZipArchiver zipArchiver = getZipArchiver( zipFile2 ); + zipArchiver.addArchivedFileSet( zipFile ); + zipArchiver.createArchive(); + + final ZipFile cmp1 = new ZipFile( zipFile ); + final ZipFile cmp2 = new ZipFile( zipFile2 ); + ArchiveFileComparator.assertEquals( cmp1, cmp2, "" ); + } + /* */