As discussed on https://git.eclipse.org/r/53836 it does not make sense to have two similar utility classes in same package with intersecting functionality. To not break the API, all methods from FileUtil are copied to FileUtils, all FileUtil API is made deprecated and redirecting now to FileUtils. Moved simple methods which are available in Java 7 API are made package private and can be removed at any point later entirely (right now they are in use). Bug: 475070 Change-Id: Idffcf9840496c448173af7c052d8898ada68e27b Signed-off-by: Andrey Loskutov <loskutov@gmx.de> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v4.1.0.201509280440-r
@@ -168,7 +168,7 @@ public class FS_POSIX extends FS { | |||
@Override | |||
public boolean canExecute(File f) { | |||
return FileUtil.canExecute(f); | |||
return FileUtils.canExecute(f); | |||
} | |||
@Override | |||
@@ -247,42 +247,42 @@ public class FS_POSIX extends FS { | |||
@Override | |||
public boolean isSymLink(File path) throws IOException { | |||
return FileUtil.isSymlink(path); | |||
return FileUtils.isSymlink(path); | |||
} | |||
@Override | |||
public long lastModified(File path) throws IOException { | |||
return FileUtil.lastModified(path); | |||
return FileUtils.lastModified(path); | |||
} | |||
@Override | |||
public void setLastModified(File path, long time) throws IOException { | |||
FileUtil.setLastModified(path, time); | |||
FileUtils.setLastModified(path, time); | |||
} | |||
@Override | |||
public long length(File f) throws IOException { | |||
return FileUtil.getLength(f); | |||
return FileUtils.getLength(f); | |||
} | |||
@Override | |||
public boolean exists(File path) { | |||
return FileUtil.exists(path); | |||
return FileUtils.exists(path); | |||
} | |||
@Override | |||
public boolean isDirectory(File path) { | |||
return FileUtil.isDirectory(path); | |||
return FileUtils.isDirectory(path); | |||
} | |||
@Override | |||
public boolean isFile(File path) { | |||
return FileUtil.isFile(path); | |||
return FileUtils.isFile(path); | |||
} | |||
@Override | |||
public boolean isHidden(File path) throws IOException { | |||
return FileUtil.isHidden(path); | |||
return FileUtils.isHidden(path); | |||
} | |||
@Override | |||
@@ -295,7 +295,7 @@ public class FS_POSIX extends FS { | |||
*/ | |||
@Override | |||
public Attributes getAttributes(File path) { | |||
return FileUtil.getFileAttributesPosix(this, path); | |||
return FileUtils.getFileAttributesPosix(this, path); | |||
} | |||
/** | |||
@@ -303,7 +303,7 @@ public class FS_POSIX extends FS { | |||
*/ | |||
@Override | |||
public File normalize(File file) { | |||
return FileUtil.normalize(file); | |||
return FileUtils.normalize(file); | |||
} | |||
/** | |||
@@ -311,7 +311,7 @@ public class FS_POSIX extends FS { | |||
*/ | |||
@Override | |||
public String normalize(String name) { | |||
return FileUtil.normalize(name); | |||
return FileUtils.normalize(name); | |||
} | |||
/** |
@@ -185,47 +185,47 @@ public class FS_Win32 extends FS { | |||
@Override | |||
public boolean isSymLink(File path) throws IOException { | |||
return FileUtil.isSymlink(path); | |||
return FileUtils.isSymlink(path); | |||
} | |||
@Override | |||
public long lastModified(File path) throws IOException { | |||
return FileUtil.lastModified(path); | |||
return FileUtils.lastModified(path); | |||
} | |||
@Override | |||
public void setLastModified(File path, long time) throws IOException { | |||
FileUtil.setLastModified(path, time); | |||
FileUtils.setLastModified(path, time); | |||
} | |||
@Override | |||
public long length(File f) throws IOException { | |||
return FileUtil.getLength(f); | |||
return FileUtils.getLength(f); | |||
} | |||
@Override | |||
public boolean exists(File path) { | |||
return FileUtil.exists(path); | |||
return FileUtils.exists(path); | |||
} | |||
@Override | |||
public boolean isDirectory(File path) { | |||
return FileUtil.isDirectory(path); | |||
return FileUtils.isDirectory(path); | |||
} | |||
@Override | |||
public boolean isFile(File path) { | |||
return FileUtil.isFile(path); | |||
return FileUtils.isFile(path); | |||
} | |||
@Override | |||
public boolean isHidden(File path) throws IOException { | |||
return FileUtil.isHidden(path); | |||
return FileUtils.isHidden(path); | |||
} | |||
@Override | |||
public void setHidden(File path, boolean hidden) throws IOException { | |||
FileUtil.setHidden(path, hidden); | |||
FileUtils.setHidden(path, hidden); | |||
} | |||
/** | |||
@@ -233,6 +233,6 @@ public class FS_Win32 extends FS { | |||
*/ | |||
@Override | |||
public Attributes getAttributes(File path) { | |||
return FileUtil.getFileAttributesBasic(this, path); | |||
return FileUtils.getFileAttributesBasic(this, path); | |||
} | |||
} |
@@ -170,47 +170,47 @@ public class FS_Win32_Cygwin extends FS_Win32 { | |||
@Override | |||
public boolean isSymLink(File path) throws IOException { | |||
return FileUtil.isSymlink(path); | |||
return FileUtils.isSymlink(path); | |||
} | |||
@Override | |||
public long lastModified(File path) throws IOException { | |||
return FileUtil.lastModified(path); | |||
return FileUtils.lastModified(path); | |||
} | |||
@Override | |||
public void setLastModified(File path, long time) throws IOException { | |||
FileUtil.setLastModified(path, time); | |||
FileUtils.setLastModified(path, time); | |||
} | |||
@Override | |||
public long length(File f) throws IOException { | |||
return FileUtil.getLength(f); | |||
return FileUtils.getLength(f); | |||
} | |||
@Override | |||
public boolean exists(File path) { | |||
return FileUtil.exists(path); | |||
return FileUtils.exists(path); | |||
} | |||
@Override | |||
public boolean isDirectory(File path) { | |||
return FileUtil.isDirectory(path); | |||
return FileUtils.isDirectory(path); | |||
} | |||
@Override | |||
public boolean isFile(File path) { | |||
return FileUtil.isFile(path); | |||
return FileUtils.isFile(path); | |||
} | |||
@Override | |||
public boolean isHidden(File path) throws IOException { | |||
return FileUtil.isHidden(path); | |||
return FileUtils.isHidden(path); | |||
} | |||
@Override | |||
public void setHidden(File path, boolean hidden) throws IOException { | |||
FileUtil.setHidden(path, hidden); | |||
FileUtils.setHidden(path, hidden); | |||
} | |||
/** | |||
@@ -218,7 +218,7 @@ public class FS_Win32_Cygwin extends FS_Win32 { | |||
*/ | |||
@Override | |||
public Attributes getAttributes(File path) { | |||
return FileUtil.getFileAttributesBasic(this, path); | |||
return FileUtils.getFileAttributesBasic(this, path); | |||
} | |||
/** |
@@ -46,22 +46,13 @@ package org.eclipse.jgit.util; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.nio.file.Files; | |||
import java.nio.file.LinkOption; | |||
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 org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.util.FS.Attributes; | |||
/** | |||
* File utilities using Java 7 NIO2 | |||
*/ | |||
@Deprecated | |||
public class FileUtil { | |||
/** | |||
@@ -92,102 +83,116 @@ public class FileUtil { | |||
/** | |||
* @param path | |||
* @return {@code true} if the passed path is a symlink | |||
* @deprecated Use {@link Files#isSymbolicLink(java.nio.file.Path)} instead | |||
*/ | |||
@Deprecated | |||
public static boolean isSymlink(File path) { | |||
Path nioPath = path.toPath(); | |||
return Files.isSymbolicLink(nioPath); | |||
return FileUtils.isSymlink(path); | |||
} | |||
/** | |||
* @param path | |||
* @return lastModified attribute for given path | |||
* @throws IOException | |||
* @deprecated Use | |||
* {@link Files#getLastModifiedTime(java.nio.file.Path, java.nio.file.LinkOption...)} | |||
* instead | |||
*/ | |||
@Deprecated | |||
public static long lastModified(File path) throws IOException { | |||
Path nioPath = path.toPath(); | |||
return Files.getLastModifiedTime(nioPath, LinkOption.NOFOLLOW_LINKS) | |||
.toMillis(); | |||
return FileUtils.lastModified(path); | |||
} | |||
/** | |||
* @param path | |||
* @param time | |||
* @throws IOException | |||
* @deprecated Use | |||
* {@link Files#setLastModifiedTime(java.nio.file.Path, java.nio.file.attribute.FileTime)} | |||
* instead | |||
*/ | |||
@Deprecated | |||
public static void setLastModified(File path, long time) throws IOException { | |||
Path nioPath = path.toPath(); | |||
Files.setLastModifiedTime(nioPath, FileTime.fromMillis(time)); | |||
FileUtils.setLastModified(path, time); | |||
} | |||
/** | |||
* @param path | |||
* @return {@code true} if the given path exists | |||
* @deprecated Use | |||
* {@link Files#exists(java.nio.file.Path, java.nio.file.LinkOption...)} | |||
* instead | |||
*/ | |||
@Deprecated | |||
public static boolean exists(File path) { | |||
Path nioPath = path.toPath(); | |||
return Files.exists(nioPath, LinkOption.NOFOLLOW_LINKS); | |||
return FileUtils.exists(path); | |||
} | |||
/** | |||
* @param path | |||
* @return {@code true} if the given path is hidden | |||
* @throws IOException | |||
* @deprecated Use {@link Files#isHidden(java.nio.file.Path)} instead | |||
*/ | |||
@Deprecated | |||
public static boolean isHidden(File path) throws IOException { | |||
Path nioPath = path.toPath(); | |||
return Files.isHidden(nioPath); | |||
return FileUtils.isHidden(path); | |||
} | |||
/** | |||
* @param path | |||
* @param hidden | |||
* @throws IOException | |||
* @deprecated Use {@link FileUtils#setHidden(File,boolean)} instead | |||
*/ | |||
@Deprecated | |||
public static void setHidden(File path, boolean hidden) throws IOException { | |||
Path nioPath = path.toPath(); | |||
Files.setAttribute(nioPath, "dos:hidden", Boolean.valueOf(hidden), //$NON-NLS-1$ | |||
LinkOption.NOFOLLOW_LINKS); | |||
FileUtils.setHidden(path, hidden); | |||
} | |||
/** | |||
* @param path | |||
* @return length of the given file | |||
* @throws IOException | |||
* @deprecated Use {@link FileUtils#getLength(File)} instead | |||
*/ | |||
@Deprecated | |||
public static long getLength(File path) throws IOException { | |||
Path nioPath = path.toPath(); | |||
if (Files.isSymbolicLink(nioPath)) | |||
return Files.readSymbolicLink(nioPath).toString() | |||
.getBytes(Constants.CHARSET).length; | |||
return Files.size(nioPath); | |||
return FileUtils.getLength(path); | |||
} | |||
/** | |||
* @param path | |||
* @return {@code true} if the given file a directory | |||
* @deprecated Use | |||
* {@link Files#isDirectory(java.nio.file.Path, java.nio.file.LinkOption...)} | |||
* instead | |||
*/ | |||
@Deprecated | |||
public static boolean isDirectory(File path) { | |||
Path nioPath = path.toPath(); | |||
return Files.isDirectory(nioPath, LinkOption.NOFOLLOW_LINKS); | |||
return FileUtils.isDirectory(path); | |||
} | |||
/** | |||
* @param path | |||
* @return {@code true} if the given file is a file | |||
* @deprecated Use | |||
* {@link Files#isRegularFile(java.nio.file.Path, java.nio.file.LinkOption...)} | |||
* instead | |||
*/ | |||
@Deprecated | |||
public static boolean isFile(File path) { | |||
Path nioPath = path.toPath(); | |||
return Files.isRegularFile(nioPath, LinkOption.NOFOLLOW_LINKS); | |||
return FileUtils.isFile(path); | |||
} | |||
/** | |||
* @param path | |||
* @return {@code true} if the given file can be executed | |||
* @deprecated Use {@link FileUtils#canExecute(File)} instead | |||
*/ | |||
@Deprecated | |||
public static boolean canExecute(File path) { | |||
if (!isFile(path)) | |||
return false; | |||
return path.canExecute(); | |||
return FileUtils.canExecute(path); | |||
} | |||
/** | |||
@@ -200,90 +205,35 @@ public class FileUtil { | |||
FileUtils.delete(path); | |||
} | |||
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 Attributes(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 (IOException e) { | |||
return new Attributes(path, fs); | |||
} | |||
} | |||
/** | |||
* @param fs | |||
* @param path | |||
* @return file system attributes for the given file | |||
* @deprecated Use {@link FileUtils#getFileAttributesPosix(FS,File)} instead | |||
*/ | |||
@Deprecated | |||
public 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 Attributes( | |||
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 (IOException e) { | |||
return new Attributes(path, fs); | |||
} | |||
return FileUtils.getFileAttributesPosix(fs, path); | |||
} | |||
/** | |||
* @param file | |||
* @return on Mac: NFC normalized {@link File}, otherwise the passed file | |||
* @deprecated Use {@link FileUtils#normalize(File)} instead | |||
*/ | |||
@Deprecated | |||
public static File normalize(File file) { | |||
if (SystemReader.getInstance().isMacOS()) { | |||
// TODO: Would it be faster to check with isNormalized first | |||
// assuming normalized paths are much more common | |||
String normalized = Normalizer.normalize(file.getPath(), | |||
Normalizer.Form.NFC); | |||
return new File(normalized); | |||
} | |||
return file; | |||
return FileUtils.normalize(file); | |||
} | |||
/** | |||
* @param name | |||
* @return on Mac: NFC normalized form of given name | |||
* @deprecated Use {@link FileUtils#normalize(String)} instead | |||
*/ | |||
@Deprecated | |||
public static String normalize(String name) { | |||
if (SystemReader.getInstance().isMacOS()) { | |||
if (name == null) | |||
return null; | |||
return Normalizer.normalize(name, Normalizer.Form.NFC); | |||
} | |||
return name; | |||
return FileUtils.normalize(name); | |||
} | |||
} |
@@ -54,6 +54,12 @@ import java.nio.file.Files; | |||
import java.nio.file.LinkOption; | |||
import java.nio.file.Path; | |||
import java.nio.file.StandardCopyOption; | |||
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.MessageFormat; | |||
import java.text.Normalizer; | |||
import java.text.Normalizer.Form; | |||
@@ -62,6 +68,8 @@ import java.util.List; | |||
import java.util.regex.Pattern; | |||
import org.eclipse.jgit.internal.JGitText; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.util.FS.Attributes; | |||
/** | |||
* File Utilities | |||
@@ -527,4 +535,199 @@ public class FileUtils { | |||
return msg != null | |||
&& msg.toLowerCase().matches("stale .*file .*handle"); //$NON-NLS-1$ | |||
} | |||
/** | |||
* @param file | |||
* @return {@code true} if the passed file is a symbolic link | |||
*/ | |||
static boolean isSymlink(File file) { | |||
return Files.isSymbolicLink(file.toPath()); | |||
} | |||
/** | |||
* @param file | |||
* @return lastModified attribute for given file, not following symbolic | |||
* links | |||
* @throws IOException | |||
*/ | |||
static long lastModified(File file) throws IOException { | |||
return Files.getLastModifiedTime(file.toPath(), LinkOption.NOFOLLOW_LINKS) | |||
.toMillis(); | |||
} | |||
/** | |||
* @param file | |||
* @param time | |||
* @throws IOException | |||
*/ | |||
static void setLastModified(File file, long time) throws IOException { | |||
Files.setLastModifiedTime(file.toPath(), FileTime.fromMillis(time)); | |||
} | |||
/** | |||
* @param file | |||
* @return {@code true} if the given file exists, not following symbolic | |||
* links | |||
*/ | |||
static boolean exists(File file) { | |||
return Files.exists(file.toPath(), LinkOption.NOFOLLOW_LINKS); | |||
} | |||
/** | |||
* @param file | |||
* @return {@code true} if the given file is hidden | |||
* @throws IOException | |||
*/ | |||
static boolean isHidden(File file) throws IOException { | |||
return Files.isHidden(file.toPath()); | |||
} | |||
/** | |||
* @param file | |||
* @param hidden | |||
* @throws IOException | |||
* @since 4.1 | |||
*/ | |||
public static void setHidden(File file, boolean hidden) throws IOException { | |||
Files.setAttribute(file.toPath(), "dos:hidden", Boolean.valueOf(hidden), //$NON-NLS-1$ | |||
LinkOption.NOFOLLOW_LINKS); | |||
} | |||
/** | |||
* @param file | |||
* @return length of the given file | |||
* @throws IOException | |||
* @since 4.1 | |||
*/ | |||
public static long getLength(File file) throws IOException { | |||
Path nioPath = file.toPath(); | |||
if (Files.isSymbolicLink(nioPath)) | |||
return Files.readSymbolicLink(nioPath).toString() | |||
.getBytes(Constants.CHARSET).length; | |||
return Files.size(nioPath); | |||
} | |||
/** | |||
* @param file | |||
* @return {@code true} if the given file is a directory, not following | |||
* symbolic links | |||
*/ | |||
static boolean isDirectory(File file) { | |||
return Files.isDirectory(file.toPath(), LinkOption.NOFOLLOW_LINKS); | |||
} | |||
/** | |||
* @param file | |||
* @return {@code true} if the given file is a file, not following symbolic | |||
* links | |||
*/ | |||
static boolean isFile(File file) { | |||
return Files.isRegularFile(file.toPath(), LinkOption.NOFOLLOW_LINKS); | |||
} | |||
/** | |||
* @param file | |||
* @return {@code true} if the given file can be executed | |||
* @since 4.1 | |||
*/ | |||
public static boolean canExecute(File file) { | |||
if (!isFile(file)) { | |||
return false; | |||
} | |||
return Files.isExecutable(file.toPath()); | |||
} | |||
/** | |||
* @param fs | |||
* @param file | |||
* @return non null attributes object | |||
*/ | |||
static Attributes getFileAttributesBasic(FS fs, File file) { | |||
try { | |||
Path nioPath = file.toPath(); | |||
BasicFileAttributes readAttributes = nioPath | |||
.getFileSystem() | |||
.provider() | |||
.getFileAttributeView(nioPath, | |||
BasicFileAttributeView.class, | |||
LinkOption.NOFOLLOW_LINKS).readAttributes(); | |||
Attributes attributes = new Attributes(fs, file, | |||
true, | |||
readAttributes.isDirectory(), | |||
fs.supportsExecute() ? file.canExecute() : false, | |||
readAttributes.isSymbolicLink(), | |||
readAttributes.isRegularFile(), // | |||
readAttributes.creationTime().toMillis(), // | |||
readAttributes.lastModifiedTime().toMillis(), | |||
readAttributes.isSymbolicLink() ? Constants | |||
.encode(readSymLink(file)).length | |||
: readAttributes.size()); | |||
return attributes; | |||
} catch (IOException e) { | |||
return new Attributes(file, fs); | |||
} | |||
} | |||
/** | |||
* @param fs | |||
* @param file | |||
* @return file system attributes for the given file | |||
* @since 4.1 | |||
*/ | |||
public static Attributes getFileAttributesPosix(FS fs, File file) { | |||
try { | |||
Path nioPath = file.toPath(); | |||
PosixFileAttributes readAttributes = nioPath | |||
.getFileSystem() | |||
.provider() | |||
.getFileAttributeView(nioPath, | |||
PosixFileAttributeView.class, | |||
LinkOption.NOFOLLOW_LINKS).readAttributes(); | |||
Attributes attributes = new Attributes( | |||
fs, | |||
file, | |||
true, // | |||
readAttributes.isDirectory(), // | |||
readAttributes.permissions().contains( | |||
PosixFilePermission.OWNER_EXECUTE), | |||
readAttributes.isSymbolicLink(), | |||
readAttributes.isRegularFile(), // | |||
readAttributes.creationTime().toMillis(), // | |||
readAttributes.lastModifiedTime().toMillis(), | |||
readAttributes.size()); | |||
return attributes; | |||
} catch (IOException e) { | |||
return new Attributes(file, fs); | |||
} | |||
} | |||
/** | |||
* @param file | |||
* @return on Mac: NFC normalized {@link File}, otherwise the passed file | |||
* @since 4.1 | |||
*/ | |||
public static File normalize(File file) { | |||
if (SystemReader.getInstance().isMacOS()) { | |||
// TODO: Would it be faster to check with isNormalized first | |||
// assuming normalized paths are much more common | |||
String normalized = Normalizer.normalize(file.getPath(), | |||
Normalizer.Form.NFC); | |||
return new File(normalized); | |||
} | |||
return file; | |||
} | |||
/** | |||
* @param name | |||
* @return on Mac: NFC normalized form of given name | |||
* @since 4.1 | |||
*/ | |||
public static String normalize(String name) { | |||
if (SystemReader.getInstance().isMacOS()) { | |||
if (name == null) | |||
return null; | |||
return Normalizer.normalize(name, Normalizer.Form.NFC); | |||
} | |||
return name; | |||
} | |||
} |