Use fileAttributes to get more attributes in one go
On Windows the length reported by FileAttributes is the size of the target file (a bug, I guess) rather than the link, so we read the linke and look at the length of the link instead. Bug: 353771 Change-Id: I834b06d0447f84379612b8c9190fa77093617595 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
parent
2852b6a07d
commit
14cd43e6df
|
@ -46,8 +46,6 @@
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jgit.util.FS;
|
||||
|
||||
/**
|
||||
* FS implementation for Java7 on unix like systems
|
||||
*/
|
||||
|
@ -150,4 +148,12 @@ public String readSymLink(File path) throws IOException {
|
|||
public void createSymLink(File path, String target) throws IOException {
|
||||
FileUtil.createSymLink(path, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.3
|
||||
*/
|
||||
@Override
|
||||
public Attributes getAttributes(File path) {
|
||||
return FileUtil.getFileAttributesPosix(this, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,4 +151,12 @@ public String readSymLink(File path) throws IOException {
|
|||
public void createSymLink(File path, String target) throws IOException {
|
||||
FileUtil.createSymLink(path, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.3
|
||||
*/
|
||||
@Override
|
||||
public Attributes getAttributes(File path) {
|
||||
return FileUtil.getFileAttributesBasic(this, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,4 +127,12 @@ public String readSymLink(File path) throws IOException {
|
|||
public void createSymLink(File path, String target) throws IOException {
|
||||
FileUtil.createSymLink(path, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.3
|
||||
*/
|
||||
@Override
|
||||
public Attributes getAttributes(File path) {
|
||||
return FileUtil.getFileAttributesBasic(this, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,15 +47,33 @@
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributeView;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.nio.file.attribute.PosixFileAttributeView;
|
||||
import java.nio.file.attribute.PosixFileAttributes;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.text.Normalizer;
|
||||
import java.text.Normalizer.Form;
|
||||
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.util.FS.Attributes;
|
||||
|
||||
class FileUtil {
|
||||
|
||||
static class Java7BasicAttributes extends Attributes {
|
||||
|
||||
Java7BasicAttributes(FS fs, File fPath, boolean exists,
|
||||
boolean isDirectory, boolean isExecutable,
|
||||
boolean isSymbolicLink, boolean isRegularFile,
|
||||
long creationTime, long lastModifiedTime, long length) {
|
||||
super(fs, fPath, exists, isDirectory, isExecutable, isSymbolicLink,
|
||||
isRegularFile, creationTime, lastModifiedTime, length);
|
||||
}
|
||||
}
|
||||
|
||||
static String readSymlink(File path) throws IOException {
|
||||
Path nioPath = path.toPath();
|
||||
Path target = Files.readSymbolicLink(nioPath);
|
||||
|
@ -145,4 +163,63 @@ public static void delete(File path) throws IOException {
|
|||
Files.delete(nioPath);
|
||||
}
|
||||
|
||||
static Attributes getFileAttributesBasic(FS fs, File path) {
|
||||
try {
|
||||
Path nioPath = path.toPath();
|
||||
BasicFileAttributes readAttributes = nioPath
|
||||
.getFileSystem()
|
||||
.provider()
|
||||
.getFileAttributeView(nioPath,
|
||||
BasicFileAttributeView.class,
|
||||
LinkOption.NOFOLLOW_LINKS).readAttributes();
|
||||
Attributes attributes = new FileUtil.Java7BasicAttributes(fs, path,
|
||||
true,
|
||||
readAttributes.isDirectory(),
|
||||
fs.supportsExecute() ? path.canExecute() : false,
|
||||
readAttributes.isSymbolicLink(),
|
||||
readAttributes.isRegularFile(), //
|
||||
readAttributes.creationTime().toMillis(), //
|
||||
readAttributes.lastModifiedTime().toMillis(),
|
||||
readAttributes.isSymbolicLink() ? Constants
|
||||
.encode(FileUtils.readSymLink(path)).length
|
||||
: readAttributes.size());
|
||||
return attributes;
|
||||
} catch (NoSuchFileException e) {
|
||||
return new FileUtil.Java7BasicAttributes(fs, path, false, false,
|
||||
false, false, false, 0L, 0L, 0L);
|
||||
} catch (IOException e) {
|
||||
return new Attributes(path, fs);
|
||||
}
|
||||
}
|
||||
|
||||
static Attributes getFileAttributesPosix(FS fs, File path) {
|
||||
try {
|
||||
Path nioPath = path.toPath();
|
||||
PosixFileAttributes readAttributes = nioPath
|
||||
.getFileSystem()
|
||||
.provider()
|
||||
.getFileAttributeView(nioPath,
|
||||
PosixFileAttributeView.class,
|
||||
LinkOption.NOFOLLOW_LINKS).readAttributes();
|
||||
Attributes attributes = new FileUtil.Java7BasicAttributes(
|
||||
fs,
|
||||
path,
|
||||
true, //
|
||||
readAttributes.isDirectory(), //
|
||||
readAttributes.permissions().contains(
|
||||
PosixFilePermission.OWNER_EXECUTE),
|
||||
readAttributes.isSymbolicLink(),
|
||||
readAttributes.isRegularFile(), //
|
||||
readAttributes.creationTime().toMillis(), //
|
||||
readAttributes.lastModifiedTime().toMillis(),
|
||||
readAttributes.size());
|
||||
return attributes;
|
||||
} catch (NoSuchFileException e) {
|
||||
return new FileUtil.Java7BasicAttributes(fs, path, false, false,
|
||||
false, false, false, 0L, 0L, 0L);
|
||||
} catch (IOException e) {
|
||||
return new Attributes(path, fs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ public FileTreeIteratorWithTimeControl(File f, FS fs,
|
|||
@Override
|
||||
public AbstractTreeIterator createSubtreeIterator(final ObjectReader reader) {
|
||||
return new FileTreeIteratorWithTimeControl(this,
|
||||
((FileEntry) current()).file, fs, modTimes);
|
||||
((FileEntry) current()).getFile(), fs, modTimes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -132,7 +132,7 @@ protected FileTreeIterator(final WorkingTreeIterator p, final File root,
|
|||
@Override
|
||||
public AbstractTreeIterator createSubtreeIterator(final ObjectReader reader)
|
||||
throws IncorrectObjectTypeException, IOException {
|
||||
return new FileTreeIterator(this, ((FileEntry) current()).file, fs);
|
||||
return new FileTreeIterator(this, ((FileEntry) current()).getFile(), fs);
|
||||
}
|
||||
|
||||
private Entry[] entries() {
|
||||
|
@ -149,13 +149,9 @@ private Entry[] entries() {
|
|||
* Wrapper for a standard Java IO file
|
||||
*/
|
||||
static public class FileEntry extends Entry {
|
||||
final File file;
|
||||
|
||||
private final FileMode mode;
|
||||
|
||||
private long length = -1;
|
||||
|
||||
private long lastModified;
|
||||
private FS.Attributes attributes;
|
||||
|
||||
private FS fs;
|
||||
|
||||
|
@ -168,27 +164,17 @@ static public class FileEntry extends Entry {
|
|||
* file system
|
||||
*/
|
||||
public FileEntry(final File f, FS fs) {
|
||||
file = f;
|
||||
this.fs = fs;
|
||||
|
||||
@SuppressWarnings("hiding")
|
||||
FileMode mode = null;
|
||||
try {
|
||||
if (fs.isSymLink(f)) {
|
||||
mode = FileMode.SYMLINK;
|
||||
} else if (fs.isDirectory(f)) {
|
||||
if (fs.exists(new File(f, Constants.DOT_GIT)))
|
||||
mode = FileMode.GITLINK;
|
||||
else
|
||||
mode = FileMode.TREE;
|
||||
} else if (fs.canExecute(file))
|
||||
mode = FileMode.EXECUTABLE_FILE;
|
||||
attributes = fs.getAttributes(f);
|
||||
if (attributes.isDirectory()) {
|
||||
if (new File(f, Constants.DOT_GIT).exists())
|
||||
mode = FileMode.GITLINK;
|
||||
else
|
||||
mode = FileMode.REGULAR_FILE;
|
||||
} catch (IOException e) {
|
||||
mode = FileMode.MISSING;
|
||||
}
|
||||
this.mode = mode;
|
||||
mode = FileMode.TREE;
|
||||
} else if (attributes.isExecutable())
|
||||
mode = FileMode.EXECUTABLE_FILE;
|
||||
else
|
||||
mode = FileMode.REGULAR_FILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -198,40 +184,27 @@ public FileMode getMode() {
|
|||
|
||||
@Override
|
||||
public String getName() {
|
||||
return file.getName();
|
||||
return attributes.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
if (length < 0) {
|
||||
try {
|
||||
length = fs.length(file);
|
||||
} catch (IOException e) {
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
return attributes.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified() {
|
||||
if (lastModified == 0) {
|
||||
try {
|
||||
lastModified = fs.lastModified(file);
|
||||
} catch (IOException e) {
|
||||
lastModified = 0;
|
||||
}
|
||||
}
|
||||
return lastModified;
|
||||
return attributes.getLastModifiedTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
if (fs.isSymLink(file))
|
||||
return new ByteArrayInputStream(fs.readSymLink(file).getBytes(
|
||||
if (fs.isSymLink(getFile()))
|
||||
return new ByteArrayInputStream(fs.readSymLink(getFile())
|
||||
.getBytes(
|
||||
Constants.CHARACTER_ENCODING));
|
||||
else
|
||||
return new FileInputStream(file);
|
||||
return new FileInputStream(getFile());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -240,7 +213,7 @@ public InputStream openInputStream() throws IOException {
|
|||
* @return the underlying file of this entry
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
return attributes.getFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -634,4 +634,150 @@ private static class Holder<V> {
|
|||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* File attributes we typically care for.
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
public static class Attributes {
|
||||
|
||||
/**
|
||||
* @return true if this are the attributes of a directory
|
||||
*/
|
||||
public boolean isDirectory() {
|
||||
return isDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this are the attributes of an executable file
|
||||
*/
|
||||
public boolean isExecutable() {
|
||||
return isExecutable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this are the attributes of a symbolic link
|
||||
*/
|
||||
public boolean isSymbolicLink() {
|
||||
return isSymbolicLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this are the attributes of a regular file
|
||||
*/
|
||||
public boolean isRegularFile() {
|
||||
return isRegularFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time when the file was created
|
||||
*/
|
||||
public long getCreationTime() {
|
||||
return creationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time (milliseconds since 1970-01-01) when this object was
|
||||
* last modified
|
||||
*/
|
||||
public long getLastModifiedTime() {
|
||||
return lastModifiedTime;
|
||||
}
|
||||
|
||||
private boolean isDirectory;
|
||||
|
||||
private boolean isSymbolicLink;
|
||||
|
||||
private boolean isRegularFile;
|
||||
|
||||
private long creationTime;
|
||||
|
||||
private long lastModifiedTime;
|
||||
|
||||
private boolean isExecutable;
|
||||
|
||||
private File file;
|
||||
|
||||
private boolean exists;
|
||||
|
||||
/**
|
||||
* file length
|
||||
*/
|
||||
protected long length = -1;
|
||||
|
||||
FS fs;
|
||||
|
||||
Attributes(FS fs, File file, boolean exists, boolean isDirectory,
|
||||
boolean isExecutable, boolean isSymbolicLink,
|
||||
boolean isRegularFile, long creationTime,
|
||||
long lastModifiedTime, long length) {
|
||||
this.fs = fs;
|
||||
this.file = file;
|
||||
this.exists = exists;
|
||||
this.isDirectory = isDirectory;
|
||||
this.isExecutable = isExecutable;
|
||||
this.isSymbolicLink = isSymbolicLink;
|
||||
this.isRegularFile = isRegularFile;
|
||||
this.creationTime = creationTime;
|
||||
this.lastModifiedTime = lastModifiedTime;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor when there are issues with reading
|
||||
*
|
||||
* @param fs
|
||||
* @param path
|
||||
*/
|
||||
public Attributes(File path, FS fs) {
|
||||
this.file = path;
|
||||
this.fs = fs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return length of this file object
|
||||
*/
|
||||
public long getLength() {
|
||||
if (length == -1)
|
||||
return length = file.length();
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the filename
|
||||
*/
|
||||
public String getName() {
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the file the attributes apply to
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
boolean exists() {
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return the file attributes we care for
|
||||
* @since 3.3
|
||||
*/
|
||||
public Attributes getAttributes(File path) {
|
||||
boolean isDirectory = isDirectory(path);
|
||||
boolean isFile = !isDirectory && path.isFile();
|
||||
assert path.exists() == isDirectory || isFile;
|
||||
boolean exists = isDirectory || isFile;
|
||||
boolean canExecute = exists && !isDirectory && canExecute(path);
|
||||
boolean isSymlink = false;
|
||||
long lastModified = exists ? path.lastModified() : 0L;
|
||||
long createTime = 0L;
|
||||
return new Attributes(this, path, exists, isDirectory, canExecute,
|
||||
isSymlink, isFile, createTime, lastModified, -1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue