Skip to content

Commit 271ba64

Browse files
committed
[PLXCOMP-117/PLXCOMP-64/PLXCOMP-113] Symlink support
Based on patch Zuhayr Khan, heavily modified and extended by me
1 parent d05a777 commit 271ba64

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+750
-636
lines changed

pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@
5050
<dependency>
5151
<groupId>org.codehaus.plexus</groupId>
5252
<artifactId>plexus-utils</artifactId>
53-
<version>3.0.15</version>
53+
<version>3.0.18</version>
5454
</dependency>
5555
<dependency>
5656
<groupId>org.codehaus.plexus</groupId>
5757
<artifactId>plexus-io</artifactId>
58-
<version>2.0.12</version>
58+
<version>2.1</version>
5959
</dependency>
6060
<dependency>
6161
<groupId>org.apache.commons</groupId>

src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java

+25-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
3737
import org.codehaus.plexus.archiver.util.FilterSupport;
3838
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
39+
import org.codehaus.plexus.components.io.attributes.Java7Reflector;
3940
import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes;
4041
import org.codehaus.plexus.components.io.resources.PlexusIoArchivedResourceCollection;
4142
import org.codehaus.plexus.components.io.resources.PlexusIoFileResourceCollection;
@@ -50,6 +51,7 @@
5051
import org.codehaus.plexus.logging.console.ConsoleLogger;
5152
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
5253
import org.codehaus.plexus.util.IOUtil;
54+
import org.codehaus.plexus.util.Os;
5355

5456
import static org.codehaus.plexus.archiver.util.DefaultArchivedFileSet.archivedFileSet;
5557
import static org.codehaus.plexus.archiver.util.DefaultFileSet.fileSet;
@@ -294,6 +296,7 @@ public void addFileSet( final FileSet fileSet )
294296
// The PlexusIoFileResourceCollection contains platform-specific File.separatorChar which
295297
// is an interesting cause of grief, see PLXCOMP-192
296298
final PlexusIoFileResourceCollection collection = new PlexusIoFileResourceCollection( getLogger() );
299+
collection.setFollowingSymLinks( !isSymlinkSupported() );
297300

298301
collection.setIncludes( fileSet.getIncludes() );
299302
collection.setExcludes( fileSet.getExcludes() );
@@ -317,12 +320,32 @@ public void addFileSet( final FileSet fileSet )
317320
addResources( collection );
318321
}
319322

323+
private boolean isSymlinkSupported()
324+
{
325+
return Os.isFamily( Os.FAMILY_UNIX ) &&
326+
Java7Reflector.isAtLeastJava7();
327+
}
328+
320329
public void addFile( final File inputFile, final String destFileName )
321330
throws ArchiverException
322331
{
323332
final int fileMode = getOverrideFileMode();
324333

325-
addFile(inputFile, destFileName, fileMode);
334+
addFile( inputFile, destFileName, fileMode );
335+
}
336+
337+
public void addSymlink(String symlinkName, String symlinkDestination)
338+
throws ArchiverException
339+
{
340+
final int fileMode = getOverrideFileMode();
341+
342+
addSymlink(symlinkName, fileMode, symlinkDestination);
343+
}
344+
345+
public void addSymlink(String symlinkName, int permissions, String symlinkDestination)
346+
throws ArchiverException
347+
{
348+
resources.add( ArchiveEntry.createSymlinkEntry( symlinkName, permissions, symlinkDestination ) );
326349
}
327350

328351
protected ArchiveEntry asArchiveEntry( final PlexusIoResource resource, final String destFileName,
@@ -458,7 +481,6 @@ public boolean hasNext()
458481
{
459482
nextEntry = (ArchiveEntry) o;
460483
}
461-
// TODO: Kr. Make iteartor handle commons compress archive entry. Maybe make
462484
else if ( o instanceof PlexusIoResourceCollection )
463485
{
464486
currentResourceCollection = (PlexusIoResourceCollection) o;
@@ -656,9 +678,8 @@ protected PlexusIoResourceCollection asResourceCollection( final ArchivedFileSet
656678
+ resources.getClass().getName() );
657679
}
658680

659-
final PlexusIoProxyResourceCollection proxy = new PlexusIoProxyResourceCollection();
681+
final PlexusIoProxyResourceCollection proxy = new PlexusIoProxyResourceCollection(resources);
660682

661-
proxy.setSrc( resources );
662683
proxy.setExcludes( fileSet.getExcludes() );
663684
proxy.setIncludes( fileSet.getIncludes() );
664685
proxy.setIncludingEmptyDirectories( fileSet.isIncludingEmptyDirectories() );

src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919

2020
import org.codehaus.plexus.archiver.util.ArchiveEntryUtils;
2121
import org.codehaus.plexus.archiver.util.FilterSupport;
22+
import org.codehaus.plexus.components.io.attributes.SymlinkUtils;
2223
import org.codehaus.plexus.components.io.fileselectors.FileSelector;
2324
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
2425
import org.codehaus.plexus.logging.AbstractLogEnabled;
2526
import org.codehaus.plexus.util.FileUtils;
2627
import org.codehaus.plexus.util.IOUtil;
28+
import org.codehaus.plexus.util.StringUtils;
2729

2830
import java.io.File;
2931
import java.io.FileNotFoundException;
@@ -290,9 +292,10 @@ public void setIgnorePermissions( final boolean ignorePermissions )
290292

291293
protected void extractFile( final File srcF, final File dir, final InputStream compressedInputStream,
292294
final String entryName, final Date entryDate, final boolean isDirectory,
293-
final Integer mode )
295+
final Integer mode, String symlinkDestination )
294296
throws IOException, ArchiverException
295297
{
298+
// Hmm. Symlinks re-evaluate back to the original file here. Unsure if this is a good thing...
296299
final File f = FileUtils.resolveFile( dir, entryName );
297300

298301
try
@@ -309,7 +312,10 @@ protected void extractFile( final File srcF, final File dir, final InputStream c
309312
dirF.mkdirs();
310313
}
311314

312-
if ( isDirectory )
315+
if ( !StringUtils.isEmpty( symlinkDestination )){
316+
SymlinkUtils.createSymbolicLink( f, new File( symlinkDestination) );
317+
}
318+
else if ( isDirectory )
313319
{
314320
f.mkdirs();
315321
}

src/main/java/org/codehaus/plexus/archiver/ArchiveEntry.java

+34-32
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@
1717
* limitations under the License.
1818
*/
1919

20-
import java.io.File;
21-
import java.io.IOException;
22-
import java.io.InputStream;
23-
20+
import org.codehaus.plexus.archiver.resources.PlexusIoVirtualSymlinkResource;
21+
import org.codehaus.plexus.archiver.util.ArchiverAttributeUtils;
2422
import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributeUtils;
2523
import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes;
2624
import org.codehaus.plexus.components.io.resources.PlexusIoFileResource;
2725
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
2826
import org.codehaus.plexus.components.io.resources.PlexusIoResourceWithAttributes;
27+
import org.codehaus.plexus.components.io.resources.PlexusIoSymlinkResource;
28+
29+
import java.io.File;
30+
import java.io.IOException;
31+
import java.io.InputStream;
2932

3033
/**
3134
* @version $Revision: 1502 $ $Date$
@@ -38,6 +41,7 @@ public class ArchiveEntry
3841

3942
public static final int DIRECTORY = 2;
4043

44+
public static final int SYMLINK = 3;
4145
private final PlexusIoResource resource;
4246

4347
private final String name;
@@ -51,27 +55,27 @@ public class ArchiveEntry
5155
/**
5256
* @param name the filename as it will appear in the archive. This is platform-specific
5357
* normalized with File.separatorChar
54-
* @param original original filename
58+
* @param resource original filename
5559
* @param type FILE or DIRECTORY
5660
* @param mode octal unix style permissions
5761
*/
5862
private ArchiveEntry( String name, PlexusIoResource resource, int type, int mode )
5963
{
6064
this.name = name;
6165
this.resource = resource;
62-
this.attributes =
63-
( resource instanceof PlexusIoResourceWithAttributes ) ? ( (PlexusIoResourceWithAttributes) resource ).getAttributes()
64-
: null;
66+
this.attributes = ( resource instanceof PlexusIoResourceWithAttributes )
67+
? ( (PlexusIoResourceWithAttributes) resource ).getAttributes() : null;
6568
this.type = type;
6669
int permissions = mode;
67-
70+
6871
if ( mode == -1 && this.attributes == null )
6972
{
70-
permissions = resource.isFile() ? Archiver.DEFAULT_FILE_MODE : Archiver.DEFAULT_DIR_MODE;
73+
permissions = resource.isFile() ? Archiver.DEFAULT_FILE_MODE
74+
: resource.isSymbolicLink() ? Archiver.DEFAULT_SYMLILNK_MODE : Archiver.DEFAULT_DIR_MODE;
7175
}
72-
76+
7377
this.mode = permissions == -1 ? permissions : ( permissions & UnixStat.PERM_MASK ) |
74-
( type == FILE ? UnixStat.FILE_FLAG : UnixStat.DIR_FLAG );
78+
( type == FILE ? UnixStat.FILE_FLAG : type == SYMLINK ? UnixStat.LINK_FLAG : UnixStat.DIR_FLAG );
7579
}
7680

7781
/**
@@ -85,8 +89,8 @@ public String getName()
8589
/**
8690
* @return The original file that will be stored in the archive.
8791
* @deprecated As of 1.0-alpha-10, file entries are no longer backed
88-
* by files, but by instances of {@link PlexusIoResource}.
89-
* Consequently, you should use {@link #getInputStream()}-
92+
* by files, but by instances of {@link PlexusIoResource}.
93+
* Consequently, you should use {@link #getInputStream()}-
9094
*/
9195
public File getFile()
9296
{
@@ -107,8 +111,6 @@ public InputStream getInputStream()
107111
}
108112

109113
/**
110-
* TODO: support for SYMLINK?
111-
*
112114
* @return FILE or DIRECTORY
113115
*/
114116
public int getType()
@@ -131,8 +133,9 @@ public int getMode()
131133
return attributes.getOctalMode();
132134
}
133135

134-
return ( ( type == FILE ? Archiver.DEFAULT_FILE_MODE : Archiver.DEFAULT_DIR_MODE ) & UnixStat.PERM_MASK )
135-
| ( type == FILE ? UnixStat.FILE_FLAG : UnixStat.DIR_FLAG );
136+
return ( ( type == FILE ? Archiver.DEFAULT_FILE_MODE
137+
: type == SYMLINK ? Archiver.DEFAULT_SYMLILNK_MODE : Archiver.DEFAULT_DIR_MODE ) & UnixStat.PERM_MASK ) |
138+
( type == FILE ? UnixStat.FILE_FLAG : type == SYMLINK ? UnixStat.LINK_FLAG : UnixStat.DIR_FLAG );
136139
}
137140

138141
public static ArchiveEntry createFileEntry( String target, PlexusIoResource resource, int permissions )
@@ -142,7 +145,8 @@ public static ArchiveEntry createFileEntry( String target, PlexusIoResource reso
142145
{
143146
throw new ArchiverException( "Not a file: " + resource.getName() );
144147
}
145-
return new ArchiveEntry( target, resource, FILE, permissions );
148+
final int type = resource.isSymbolicLink() ? SYMLINK : FILE;
149+
return new ArchiveEntry( target, resource, type, permissions );
146150
}
147151

148152
public static ArchiveEntry createFileEntry( String target, File file, int permissions )
@@ -174,7 +178,8 @@ public static ArchiveEntry createDirectoryEntry( String target, PlexusIoResource
174178
{
175179
throw new ArchiverException( "Not a directory: " + resource.getName() );
176180
}
177-
return new ArchiveEntry( target, resource, DIRECTORY, permissions );
181+
final int type = resource.isSymbolicLink() ? SYMLINK : DIRECTORY;
182+
return new ArchiveEntry( target, resource, type, permissions );
178183
}
179184

180185
public static ArchiveEntry createDirectoryEntry( String target, final File file, int permissions )
@@ -184,18 +189,8 @@ public static ArchiveEntry createDirectoryEntry( String target, final File file,
184189
{
185190
throw new ArchiverException( "Not a directory: " + file );
186191
}
187-
188-
PlexusIoResourceAttributes attrs;
189-
try
190-
{
191-
attrs = PlexusIoResourceAttributeUtils.getFileAttributes( file );
192-
}
193-
catch ( IOException e )
194-
{
195-
throw new ArchiverException( "Failed to read filesystem attributes for: " + file, e );
196-
}
197-
198-
final PlexusIoFileResource res = new PlexusIoFileResource( file, attrs );
192+
193+
final PlexusIoFileResource res = new PlexusIoFileResource( file, ArchiverAttributeUtils.getFileAttributes(file));
199194
return new ArchiveEntry( target, res, DIRECTORY, permissions );
200195
}
201196

@@ -216,6 +211,13 @@ else if ( file.isFile() )
216211
}
217212
}
218213

214+
public static ArchiveEntry createSymlinkEntry(String symlinkName, int permissions, String symlinkDestination)
215+
{
216+
File symlinkFile = new File(symlinkName);
217+
final ArchiveEntry archiveEntry = new ArchiveEntry(symlinkName, new PlexusIoVirtualSymlinkResource(symlinkFile, symlinkDestination), SYMLINK, permissions);
218+
return archiveEntry;
219+
}
220+
219221
public PlexusIoResourceAttributes getResourceAttributes()
220222
{
221223
return attributes;

src/main/java/org/codehaus/plexus/archiver/Archiver.java

+11
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ public interface Archiver
4141
*/
4242
int DEFAULT_FILE_MODE = UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM;
4343

44+
/**
45+
* Default value for the symlinkmode attribute.
46+
*/
47+
int DEFAULT_SYMLILNK_MODE = UnixStat.LINK_FLAG | UnixStat.DEFAULT_LINK_PERM;
48+
4449
String ROLE = Archiver.class.getName();
4550

4651
public static final String DUPLICATES_ADD = "add";
@@ -118,6 +123,12 @@ void addDirectory( File directory, String prefix, String[] includes, String[] ex
118123
void addFileSet( FileSet fileSet )
119124
throws ArchiverException;
120125

126+
void addSymlink(String symlinkName, String symlinkDestination)
127+
throws ArchiverException;
128+
129+
void addSymlink(String symlinkName, int permissions, String symlinkDestination)
130+
throws ArchiverException;
131+
121132
void addFile( File inputFile, String destFileName )
122133
throws ArchiverException;
123134

src/main/java/org/codehaus/plexus/archiver/bzip2/PlexusIoBzip2ResourceCollection.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
import java.io.FileInputStream;
55
import java.io.IOException;
66
import java.io.InputStream;
7+
import java.nio.file.attribute.PosixFileAttributes;
8+
import java.util.HashMap;
79

10+
import org.codehaus.plexus.components.io.attributes.Java7AttributeUtils;
11+
import org.codehaus.plexus.components.io.attributes.Java7FileAttributes;
12+
import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes;
813
import org.codehaus.plexus.components.io.resources.PlexusIoCompressedFileResourceCollection;
914
import org.codehaus.plexus.components.io.resources.PlexusIoResourceCollection;
1015
import org.codehaus.plexus.util.IOUtil;
@@ -38,7 +43,14 @@ protected InputStream getInputStream( File file )
3843
}
3944
}
4045

41-
protected String getDefaultExtension()
46+
47+
@Override protected PlexusIoResourceAttributes getAttributes(File file) throws IOException {
48+
final PosixFileAttributes posixFileAttributes = Java7AttributeUtils.getPosixFileAttributes(file);
49+
PlexusIoResourceAttributes attrs = new Java7FileAttributes(file, posixFileAttributes, new HashMap<Integer, String>(), new HashMap<Integer, String>());
50+
return attrs;
51+
}
52+
53+
protected String getDefaultExtension()
4254
{
4355
return ".bz2";
4456
}

src/main/java/org/codehaus/plexus/archiver/gzip/PlexusIoGzipResourceCollection.java

+11
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44
import java.io.FileInputStream;
55
import java.io.IOException;
66
import java.io.InputStream;
7+
import java.nio.file.attribute.PosixFileAttributes;
8+
import java.util.HashMap;
79
import java.util.zip.GZIPInputStream;
810

11+
import org.codehaus.plexus.components.io.attributes.Java7AttributeUtils;
12+
import org.codehaus.plexus.components.io.attributes.Java7FileAttributes;
13+
import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes;
914
import org.codehaus.plexus.components.io.resources.PlexusIoCompressedFileResourceCollection;
1015
import org.codehaus.plexus.util.IOUtil;
1116

@@ -37,4 +42,10 @@ protected InputStream getInputStream( File file )
3742
IOUtil.close( fis );
3843
}
3944
}
45+
46+
@Override protected PlexusIoResourceAttributes getAttributes(File file) throws IOException {
47+
final PosixFileAttributes posixFileAttributes = Java7AttributeUtils.getPosixFileAttributes(file);
48+
PlexusIoResourceAttributes attrs = new Java7FileAttributes(file, posixFileAttributes, new HashMap<Integer, String>(), new HashMap<Integer, String>());
49+
return attrs;
50+
}
4051
}

0 commit comments

Comments
 (0)