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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.eclipse.jgit.util.FS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FS implementation for Java7 on unix like systems
|
* 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 {
|
public void createSymLink(File path, String target) throws IOException {
|
||||||
FileUtil.createSymLink(path, target);
|
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 {
|
public void createSymLink(File path, String target) throws IOException {
|
||||||
FileUtil.createSymLink(path, target);
|
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 {
|
public void createSymLink(File path, String target) throws IOException {
|
||||||
FileUtil.createSymLink(path, target);
|
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.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.LinkOption;
|
import java.nio.file.LinkOption;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.nio.file.Path;
|
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.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;
|
||||||
import java.text.Normalizer.Form;
|
import java.text.Normalizer.Form;
|
||||||
|
|
||||||
import org.eclipse.jgit.lib.Constants;
|
import org.eclipse.jgit.lib.Constants;
|
||||||
|
import org.eclipse.jgit.util.FS.Attributes;
|
||||||
|
|
||||||
class FileUtil {
|
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 {
|
static String readSymlink(File path) throws IOException {
|
||||||
Path nioPath = path.toPath();
|
Path nioPath = path.toPath();
|
||||||
Path target = Files.readSymbolicLink(nioPath);
|
Path target = Files.readSymbolicLink(nioPath);
|
||||||
|
@ -145,4 +163,63 @@ public static void delete(File path) throws IOException {
|
||||||
Files.delete(nioPath);
|
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
|
@Override
|
||||||
public AbstractTreeIterator createSubtreeIterator(final ObjectReader reader) {
|
public AbstractTreeIterator createSubtreeIterator(final ObjectReader reader) {
|
||||||
return new FileTreeIteratorWithTimeControl(this,
|
return new FileTreeIteratorWithTimeControl(this,
|
||||||
((FileEntry) current()).file, fs, modTimes);
|
((FileEntry) current()).getFile(), fs, modTimes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -132,7 +132,7 @@ protected FileTreeIterator(final WorkingTreeIterator p, final File root,
|
||||||
@Override
|
@Override
|
||||||
public AbstractTreeIterator createSubtreeIterator(final ObjectReader reader)
|
public AbstractTreeIterator createSubtreeIterator(final ObjectReader reader)
|
||||||
throws IncorrectObjectTypeException, IOException {
|
throws IncorrectObjectTypeException, IOException {
|
||||||
return new FileTreeIterator(this, ((FileEntry) current()).file, fs);
|
return new FileTreeIterator(this, ((FileEntry) current()).getFile(), fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entry[] entries() {
|
private Entry[] entries() {
|
||||||
|
@ -149,13 +149,9 @@ private Entry[] entries() {
|
||||||
* Wrapper for a standard Java IO file
|
* Wrapper for a standard Java IO file
|
||||||
*/
|
*/
|
||||||
static public class FileEntry extends Entry {
|
static public class FileEntry extends Entry {
|
||||||
final File file;
|
|
||||||
|
|
||||||
private final FileMode mode;
|
private final FileMode mode;
|
||||||
|
|
||||||
private long length = -1;
|
private FS.Attributes attributes;
|
||||||
|
|
||||||
private long lastModified;
|
|
||||||
|
|
||||||
private FS fs;
|
private FS fs;
|
||||||
|
|
||||||
|
@ -168,27 +164,17 @@ static public class FileEntry extends Entry {
|
||||||
* file system
|
* file system
|
||||||
*/
|
*/
|
||||||
public FileEntry(final File f, FS fs) {
|
public FileEntry(final File f, FS fs) {
|
||||||
file = f;
|
|
||||||
this.fs = fs;
|
this.fs = fs;
|
||||||
|
attributes = fs.getAttributes(f);
|
||||||
@SuppressWarnings("hiding")
|
if (attributes.isDirectory()) {
|
||||||
FileMode mode = null;
|
if (new File(f, Constants.DOT_GIT).exists())
|
||||||
try {
|
mode = FileMode.GITLINK;
|
||||||
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;
|
|
||||||
else
|
else
|
||||||
mode = FileMode.REGULAR_FILE;
|
mode = FileMode.TREE;
|
||||||
} catch (IOException e) {
|
} else if (attributes.isExecutable())
|
||||||
mode = FileMode.MISSING;
|
mode = FileMode.EXECUTABLE_FILE;
|
||||||
}
|
else
|
||||||
this.mode = mode;
|
mode = FileMode.REGULAR_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -198,40 +184,27 @@ public FileMode getMode() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return file.getName();
|
return attributes.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
if (length < 0) {
|
return attributes.getLength();
|
||||||
try {
|
|
||||||
length = fs.length(file);
|
|
||||||
} catch (IOException e) {
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLastModified() {
|
public long getLastModified() {
|
||||||
if (lastModified == 0) {
|
return attributes.getLastModifiedTime();
|
||||||
try {
|
|
||||||
lastModified = fs.lastModified(file);
|
|
||||||
} catch (IOException e) {
|
|
||||||
lastModified = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lastModified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream openInputStream() throws IOException {
|
public InputStream openInputStream() throws IOException {
|
||||||
if (fs.isSymLink(file))
|
if (fs.isSymLink(getFile()))
|
||||||
return new ByteArrayInputStream(fs.readSymLink(file).getBytes(
|
return new ByteArrayInputStream(fs.readSymLink(getFile())
|
||||||
|
.getBytes(
|
||||||
Constants.CHARACTER_ENCODING));
|
Constants.CHARACTER_ENCODING));
|
||||||
else
|
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
|
* @return the underlying file of this entry
|
||||||
*/
|
*/
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
return file;
|
return attributes.getFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -634,4 +634,150 @@ private static class Holder<V> {
|
||||||
this.value = value;
|
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