]> source.dussan.org Git - jgit.git/commitdiff
Use fileAttributes to get more attributes in one go 42/9642/30
authorRobin Rosenberg <robin.rosenberg@dewire.com>
Thu, 23 Jan 2014 05:07:12 +0000 (06:07 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Wed, 12 Feb 2014 00:35:25 +0000 (01:35 +0100)
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>
org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FS_POSIX_Java7.java
org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FS_Win32_Java7.java
org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FS_Win32_Java7Cygwin.java
org.eclipse.jgit.java7/src/org/eclipse/jgit/util/FileUtil.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorWithTimeControl.java
org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java

index 6a98481797e494e7955dcb31c3598ce3f28f3ea3..e8307fc2b09bb45a5e0b0b6ce651de49dfc2a582 100644 (file)
@@ -46,8 +46,6 @@ package org.eclipse.jgit.util;
 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 class FS_POSIX_Java7 extends FS_POSIX {
        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);
+       }
 }
index 5551632228ea882b5d512beae6beac9991d82fe8..4a9d5f0bb7bbe3d3f68955e44beadf87bb9dd381 100644 (file)
@@ -151,4 +151,12 @@ public class FS_Win32_Java7 extends FS_Win32 {
        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);
+       }
 }
index 3db2e53e424630689b69e8566338c2b5dc8fb337..e40d7cf0b569989ca4752daa1098c5fd5ea263a4 100644 (file)
@@ -127,4 +127,12 @@ public class FS_Win32_Java7Cygwin extends FS_Win32_Cygwin {
        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);
+       }
 }
index 0fd19bcdd17c5d6dc8df626936fb1f4c76939247..78dc2c3934ee49659bedf2d09f842c398e8e8dc7 100644 (file)
@@ -47,15 +47,33 @@ import java.io.File;
 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 @@ class FileUtil {
                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);
+               }
+       }
+
 }
index 8ea1fd9e98b6b36c09408e728339dcbf4ae134ed..ff5730e72f392278923f31774db467fb95b1dc90 100644 (file)
@@ -95,7 +95,7 @@ public class FileTreeIteratorWithTimeControl extends FileTreeIterator {
        @Override
        public AbstractTreeIterator createSubtreeIterator(final ObjectReader reader) {
                return new FileTreeIteratorWithTimeControl(this,
-                               ((FileEntry) current()).file, fs, modTimes);
+                               ((FileEntry) current()).getFile(), fs, modTimes);
        }
 
        @Override
index cb919ecbcde1f39aa2ce7e4e26b901b945d7d0c5..9e89791b849b2fd094fe3fc8fc577b772b0da333 100644 (file)
@@ -132,7 +132,7 @@ public class FileTreeIterator extends WorkingTreeIterator {
        @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 @@ public class FileTreeIterator extends WorkingTreeIterator {
         * 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 @@ public class FileTreeIterator extends WorkingTreeIterator {
                 *            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 class FileTreeIterator extends WorkingTreeIterator {
 
                @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 class FileTreeIterator extends WorkingTreeIterator {
                 * @return the underlying file of this entry
                 */
                public File getFile() {
-                       return file;
+                       return attributes.getFile();
                }
        }
 
index a5642f149a042d80f311c43c1e9f79dfac01ea03..9e964fc363d5279f95957d45f0b5afc73aecbfa4 100644 (file)
@@ -634,4 +634,150 @@ public abstract class FS {
                        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);
+       }
 }