Skip to content

Add support for symlinks in PlexusIoZipFileResourceCollection #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier;
import org.codehaus.plexus.components.io.resources.AbstractPlexusIoArchiveResourceCollection;
import org.codehaus.plexus.components.io.resources.EncodingSupported;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
Expand Down Expand Up @@ -79,6 +80,59 @@ public URL getResource( String name )
private static class ZipFileResourceIterator
implements Iterator<PlexusIoResource>, Closeable
{
private class ZipFileResource
extends PlexusIoURLResource
{
private ZipFileResource( ZipArchiveEntry entry )
{
super( entry.getName(), entry.getTime() == -1 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : entry.getTime(),
entry.isDirectory() ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : entry.getSize(),
!entry.isDirectory(), entry.isDirectory(), true );
}

public URL getURL()
throws IOException
{
String spec = getName();
if ( spec.startsWith( "/" ) )
{
// Code path for PLXCOMP-170. Note that urlClassloader does not seem to produce correct
// urls for this. Which again means files loaded via this path cannot have file names
// requiring url encoding
spec = "./" + spec;
return new URL( url, spec );
}
return urlClassLoader.getResource( spec );
}
}

private class ZipFileSymlinkResource
extends ZipFileResource
implements SymlinkDestinationSupplier
{
private final ZipArchiveEntry entry;

private ZipFileSymlinkResource( ZipArchiveEntry entry )
{
super( entry );

this.entry = entry;
}

@Override
public String getSymlinkDestination()
throws IOException
{
return zipFile.getUnixSymlink( entry );
}

@Override
public boolean isSymbolicLink()
{
return true;
}
}

private final Enumeration<ZipArchiveEntry> en;

private final URL url;
Expand All @@ -103,28 +157,10 @@ public boolean hasNext()
public PlexusIoResource next()
{
final ZipArchiveEntry entry = en.nextElement();
long l = entry.getTime();
final long lastModified = l == -1 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : l;
final boolean dir = entry.isDirectory();
final long size = dir ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : entry.getSize();

return new PlexusIoURLResource( entry.getName(), lastModified, size, !dir, dir, true )
{
public URL getURL()
throws IOException
{
String spec = getName();
if ( spec.startsWith( "/" ) )
{
// Code path for PLXCOMP-170. Note that urlClassloader does not seem to produce correct
// urls for this. Which again means files loaded via this path cannot have file names
// requiring url encoding
spec = "./" + spec;
return new URL( url, spec );
}
return urlClassLoader.getResource( spec );
}
};
return entry.isUnixSymlink()
? new ZipFileSymlinkResource( entry )
: new ZipFileResource( entry );
}

public void remove()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

import org.apache.commons.io.IOUtils;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier;
import org.codehaus.plexus.components.io.resources.*;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class PlexusIoZipFileResourceCollectionTest
Expand Down Expand Up @@ -87,4 +90,39 @@ public void testFilesThatAreNotThere()
}
}

public void testSymlinkEntries()
throws Exception
{
File testZip = new File( getBasedir(), "src/test/resources/symlinks/symlinks.zip" );
Map<String, String> symLinks = new HashMap<String, String>();
symLinks.put( "symDir", "targetDir/" );
symLinks.put( "symLinkToDirOnTheOutside", "../dirOnTheOutside/" );
symLinks.put( "symLinkToTheOutside", "../onTheOutside.txt" );
symLinks.put( "symR", "fileR.txt" );
symLinks.put( "symW", "fileW.txt" );
symLinks.put( "symX", "fileX.txt" );
PlexusIoZipFileResourceCollection
prc = new PlexusIoZipFileResourceCollection();
prc.setFile( testZip );
final Iterator<PlexusIoResource> entries = prc.getEntries();
while ( entries.hasNext() )
{
final PlexusIoResource next = entries.next();
String symLinkTarget = symLinks.remove( next.getName() );
if ( symLinkTarget != null )
{
assertTrue( next.getName() + " must be symlink", next.isSymbolicLink() );
assertTrue( next instanceof SymlinkDestinationSupplier );
assertEquals( symLinkTarget,
( (SymlinkDestinationSupplier) next ).getSymlinkDestination() );
}
else
{
assertFalse( next.getName() + " must not be symlink", next.isSymbolicLink() );
}
}

assertTrue( symLinks.isEmpty() );
}

}