org.codehaus.plexus.archiver.ArchiveEntry Maven / Gradle / Ivy
The newest version!
/**
*
* Copyright 2004 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;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.codehaus.plexus.archiver.resources.PlexusIoVirtualSymlinkResource;
import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes;
import org.codehaus.plexus.components.io.functions.ResourceAttributeSupplier;
import org.codehaus.plexus.components.io.resources.PlexusIoFileResource;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.components.io.resources.PlexusIoResourceCollection;
import org.codehaus.plexus.components.io.resources.ResourceFactory;
import static org.codehaus.plexus.components.io.resources.ResourceFactory.createResource;
public class ArchiveEntry {
public static final String ROLE = ArchiveEntry.class.getName();
public static final int FILE = 1;
public static final int DIRECTORY = 2;
public static final int SYMLINK = 3;
@Nonnull
private final PlexusIoResource resource;
private final String name;
private final int type;
private final int mode;
private final int defaultDirMode; // Sometimes a directory needs to be created. Which mode should it be ?
// this mode is at the time of the creation of the archive entry, which is an important distinction
private PlexusIoResourceAttributes attributes;
private final boolean addSynchronously;
/**
* @param name the filename as it will appear in the archive. This is platform-specific
* normalized with File.separatorChar
* @param resource original filename
* @param type FILE or DIRECTORY
* @param mode octal unix style permissions
* @param collection
* @param defaultDirMode
*/
private ArchiveEntry(
String name,
@Nonnull PlexusIoResource resource,
int type,
int mode,
PlexusIoResourceCollection collection,
int defaultDirMode) {
try {
this.name = name;
this.defaultDirMode = defaultDirMode;
this.resource = collection != null ? collection.resolve(resource) : resource;
this.attributes = (resource instanceof ResourceAttributeSupplier)
? ((ResourceAttributeSupplier) resource).getAttributes()
: null;
this.type = type;
int permissions = mode;
if (mode == PlexusIoResourceAttributes.UNKNOWN_OCTAL_MODE && this.attributes == null) {
permissions = resource.isFile()
? Archiver.DEFAULT_FILE_MODE
: resource.isSymbolicLink() ? Archiver.DEFAULT_SYMLILNK_MODE : Archiver.DEFAULT_DIR_MODE;
}
this.mode = permissions == PlexusIoResourceAttributes.UNKNOWN_OCTAL_MODE
? permissions
: (permissions & UnixStat.PERM_MASK)
| (type == FILE
? UnixStat.FILE_FLAG
: type == SYMLINK ? UnixStat.LINK_FLAG : UnixStat.DIR_FLAG);
this.addSynchronously = (collection != null && !collection.isConcurrentAccessSupported());
} catch (IOException e) {
throw new ArchiverException("Error resolving resource " + resource.getName(), e);
}
}
/**
* @return the filename of this entry in the archive.
*/
public String getName() {
return name;
}
/**
* @return The original file that will be stored in the archive.
*
* @deprecated As of 1.0-alpha-10, file entries are no longer backed
* by files, but by instances of {@link PlexusIoResource}.
* Consequently, you should use {@link #getInputStream()}-
*/
@Deprecated
public File getFile() {
if (resource instanceof PlexusIoFileResource) {
return ((PlexusIoFileResource) resource).getFile();
}
return null;
}
/**
* @return The resource contents.
*/
public InputStream getInputStream() throws IOException {
return resource.getContents();
}
/**
* @return FILE or DIRECTORY
*/
public int getType() {
return type;
}
/**
* @return octal user/group/other unix like permissions.
*/
public int getMode() {
if (mode != -1) {
return mode;
}
if (attributes != null && attributes.getOctalMode() > -1) {
return attributes.getOctalMode();
}
return ((type == FILE
? Archiver.DEFAULT_FILE_MODE
: type == SYMLINK ? Archiver.DEFAULT_SYMLILNK_MODE : Archiver.DEFAULT_DIR_MODE)
& UnixStat.PERM_MASK)
| (type == FILE ? UnixStat.FILE_FLAG : type == SYMLINK ? UnixStat.LINK_FLAG : UnixStat.DIR_FLAG);
}
/**
* Indicates if this entry should be added to the archive synchronously
* before adding the next entry and/or accessing the next entry of {@link ResourceIterator}.
*
* @return {@code true} if this entry should be added synchronously
*/
public boolean shouldAddSynchronously() {
return addSynchronously;
}
public static ArchiveEntry createFileEntry(
String target,
PlexusIoResource resource,
int permissions,
PlexusIoResourceCollection collection,
int defaultDirectoryPermissions)
throws ArchiverException {
if (resource.isDirectory()) {
throw new ArchiverException("Not a file: " + resource.getName());
}
final int type = resource.isSymbolicLink() ? SYMLINK : FILE;
return new ArchiveEntry(target, resource, type, permissions, collection, defaultDirectoryPermissions);
}
public static ArchiveEntry createFileEntry(
String target, File file, int permissions, int defaultDirectoryPermissions)
throws ArchiverException, IOException {
if (!file.isFile()) {
throw new ArchiverException("Not a file: " + file);
}
final PlexusIoResource res = ResourceFactory.createResource(file);
final int type;
if (res.isSymbolicLink()) {
type = SYMLINK;
permissions = permissions & ~(UnixStat.FILE_FLAG); // remove file flag again .doh.
} else {
type = FILE; // File flag was there already. This is a bit of a mess !
}
return new ArchiveEntry(target, res, type, permissions, null, defaultDirectoryPermissions);
}
public static ArchiveEntry createDirectoryEntry(
String target, @Nonnull PlexusIoResource resource, int permissions, int defaultDirectoryPermissions)
throws ArchiverException {
if (!resource.isDirectory()) {
throw new ArchiverException("Not a directory: " + resource.getName());
}
final int type;
if (resource.isSymbolicLink()) {
type = SYMLINK;
permissions = permissions & ~(UnixStat.DIR_FLAG); // remove dir flag again .doh.
} else {
type = DIRECTORY; // Dir flag was there already. This is a bit of a mess !
}
return new ArchiveEntry(target, resource, type, permissions, null, defaultDirectoryPermissions);
}
public static ArchiveEntry createDirectoryEntry(
String target, final File file, int permissions, int defaultDirMode1)
throws ArchiverException, IOException {
if (!file.isDirectory()) {
throw new ArchiverException("Not a directory: " + file);
}
final PlexusIoResource res = createResource(file);
return new ArchiveEntry(target, res, DIRECTORY, permissions, null, defaultDirMode1);
}
public static ArchiveEntry createSymlinkEntry(
String symlinkName, int permissions, String symlinkDestination, int defaultDirectoryPermissions) {
final ArchiveEntry archiveEntry = new ArchiveEntry(
symlinkName,
new PlexusIoVirtualSymlinkResource(new File(symlinkName), symlinkDestination),
SYMLINK,
permissions,
null,
defaultDirectoryPermissions);
return archiveEntry;
}
public PlexusIoResourceAttributes getResourceAttributes() {
return attributes;
}
public void setResourceAttributes(PlexusIoResourceAttributes attributes) {
this.attributes = attributes;
}
public @Nonnull PlexusIoResource getResource() {
return resource;
}
public int getDefaultDirMode() {
return defaultDirMode;
}
}