|
@@ -14,6 +14,7 @@ import net.ranides.assira.text.Wildcard;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
import java.io.File;
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
|
+import java.net.URI;
|
|
|
import java.net.URISyntaxException;
|
|
import java.net.URISyntaxException;
|
|
|
import java.net.URL;
|
|
import java.net.URL;
|
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Files;
|
|
@@ -25,6 +26,7 @@ import java.util.Locale;
|
|
|
import java.util.function.Supplier;
|
|
import java.util.function.Supplier;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * Utility methods for working with Paths.
|
|
|
*
|
|
*
|
|
|
* @author Ranides Atterwim {@literal <ranides@gmail.com>}
|
|
* @author Ranides Atterwim {@literal <ranides@gmail.com>}
|
|
|
*/
|
|
*/
|
|
@@ -37,6 +39,16 @@ public class PathUtils {
|
|
|
// @todo #56
|
|
// @todo #56
|
|
|
private static final boolean CASE_SENSITIVE_FILES = !new File( "a" ).equals( new File( "A" ) );
|
|
private static final boolean CASE_SENSITIVE_FILES = !new File( "a" ).equals( new File( "A" ) );
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates Path from provided URL.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Method converts URL to URI and then to Path.
|
|
|
|
|
+ * It does not extract "path" part from URL.
|
|
|
|
|
+ * It resolves full URL into Path, trying to use scheme supported by JDK.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param url url
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
public static Path fromURL(URL url) {
|
|
public static Path fromURL(URL url) {
|
|
|
try {
|
|
try {
|
|
|
return Paths.get(url.toURI());
|
|
return Paths.get(url.toURI());
|
|
@@ -44,31 +56,101 @@ public class PathUtils {
|
|
|
throw new IllegalArgumentException(cause);
|
|
throw new IllegalArgumentException(cause);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Extracts long extension part from given path.
|
|
|
|
|
+ * Long extension is fragment of filename after first dot "." separator, including dot.
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example: "c:\\windows\\file.txt.bak" will give ".txt.bak"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
public static String getLongExtension(String path) {
|
|
public static String getLongExtension(String path) {
|
|
|
return getLongExtension(Paths.get(path));
|
|
return getLongExtension(Paths.get(path));
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Extracts long extension part from given path.
|
|
|
|
|
+ * Long extension is fragment of filename after first dot "." separator, including dot.
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example: "c:\\windows\\file.txt.bak" will give ".txt.bak"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
public static String getLongExtension(Path path) {
|
|
public static String getLongExtension(Path path) {
|
|
|
String name = path.getFileName().toString();
|
|
String name = path.getFileName().toString();
|
|
|
int index = name.indexOf(".");
|
|
int index = name.indexOf(".");
|
|
|
return (-1==index) ? "" : name.substring(index);
|
|
return (-1==index) ? "" : name.substring(index);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Extracts short extension part from given path.
|
|
|
|
|
+ * Short extension is fragment of filename after last dot "." separator, including dot.
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example: "c:\\windows\\file.txt.bak" will give ".bak"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
public static String getShortExtension(String path) {
|
|
public static String getShortExtension(String path) {
|
|
|
return getShortExtension(Paths.get(path));
|
|
return getShortExtension(Paths.get(path));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Extracts short extension part from given path.
|
|
|
|
|
+ * Short extension is fragment of filename after last dot "." separator, including dot.
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example: "c:\\windows\\file.txt.bak" will give ".bak"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
public static String getShortExtension(Path path) {
|
|
public static String getShortExtension(Path path) {
|
|
|
String name = path.getFileName().toString();
|
|
String name = path.getFileName().toString();
|
|
|
int index = name.lastIndexOf(".");
|
|
int index = name.lastIndexOf(".");
|
|
|
return (-1==index) ? "" : name.substring(index);
|
|
return (-1==index) ? "" : name.substring(index);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new path, with long extesion replaced by provided one.
|
|
|
|
|
+ * Long extension is fragment of filename after first dot "." separator, including dot.
|
|
|
|
|
+ *
|
|
|
|
|
+ * New extension should include dot, if necessary.
|
|
|
|
|
+ * New extension could be empty, then old extension will just removed.
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example, for path: "c:\\windows\\file.txt.bak"
|
|
|
|
|
+ * replace with ".log" will give "c:\\windows\\file.log"
|
|
|
|
|
+ * replace with "log" will give "c:\\windows\\filelog"
|
|
|
|
|
+ * replace with "\\log" will give "c:\\windows\\file\\log"
|
|
|
|
|
+ * replace with "" will give "c:\\windows\\file"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @param extension extension
|
|
|
|
|
+ * @return path
|
|
|
|
|
+ */
|
|
|
public static Path changeLongExtension(Path path, String extension) {
|
|
public static Path changeLongExtension(Path path, String extension) {
|
|
|
return changeLongExtension(path.toString(), extension);
|
|
return changeLongExtension(path.toString(), extension);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new path, with long extesion replaced by provided one.
|
|
|
|
|
+ * Long extension is fragment of filename after first dot "." separator, including dot.
|
|
|
|
|
+ *
|
|
|
|
|
+ * New extension should include dot, if necessary.
|
|
|
|
|
+ * New extension could be empty, then old extension will be just removed.
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example, for path: "c:\\windows\\file.txt.bak"
|
|
|
|
|
+ * replace with ".log" will give "c:\\windows\\file.log"
|
|
|
|
|
+ * replace with "log" will give "c:\\windows\\filelog"
|
|
|
|
|
+ * replace with "\\log" will give "c:\\windows\\file\\log"
|
|
|
|
|
+ * replace with "" will give "c:\\windows\\file"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @param extension extension
|
|
|
|
|
+ * @return path
|
|
|
|
|
+ */
|
|
|
public static Path changeLongExtension(String path, String extension) {
|
|
public static Path changeLongExtension(String path, String extension) {
|
|
|
int from = Math.max(0, Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')));
|
|
int from = Math.max(0, Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')));
|
|
|
int index = path.substring(from).indexOf(".");
|
|
int index = path.substring(from).indexOf(".");
|
|
@@ -79,10 +161,44 @@ public class PathUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new path, with short extesion replaced by provided one.
|
|
|
|
|
+ * Short extension is fragment of filename after last dot "." separator, including dot.
|
|
|
|
|
+ *
|
|
|
|
|
+ * New extension should include dot, if necessary.
|
|
|
|
|
+ * New extension could be empty, then old extension will be just removed.
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example, for path: "c:\\windows\\file.txt.bak"
|
|
|
|
|
+ * replace with ".log" will give "c:\\windows\\file.txt.log"
|
|
|
|
|
+ * replace with "log" will give "c:\\windows\\file.txtlog"
|
|
|
|
|
+ * replace with "\\log" will give "c:\\windows\\file.txt\\log"
|
|
|
|
|
+ * replace with "" will give "c:\\windows\\file.txt"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @param extension extension
|
|
|
|
|
+ * @return path
|
|
|
|
|
+ */
|
|
|
public static Path changeShortExtension(Path path, String extension) {
|
|
public static Path changeShortExtension(Path path, String extension) {
|
|
|
return changeShortExtension(path.toString(), extension);
|
|
return changeShortExtension(path.toString(), extension);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new path, with short extesion replaced by provided one.
|
|
|
|
|
+ * Short extension is fragment of filename after last dot "." separator, including dot.
|
|
|
|
|
+ *
|
|
|
|
|
+ * New extension should include dot, if necessary.
|
|
|
|
|
+ * New extension could be empty, then old extension will be just removed.
|
|
|
|
|
+ *
|
|
|
|
|
+ * For example, for path: "c:\\windows\\file.txt.bak"
|
|
|
|
|
+ * replace with ".log" will give "c:\\windows\\file.txt.log"
|
|
|
|
|
+ * replace with "log" will give "c:\\windows\\file.txtlog"
|
|
|
|
|
+ * replace with "\\log" will give "c:\\windows\\file.txt\\log"
|
|
|
|
|
+ * replace with "" will give "c:\\windows\\file.txt"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @param extension extension
|
|
|
|
|
+ * @return path
|
|
|
|
|
+ */
|
|
|
public static Path changeShortExtension(String path, String extension) {
|
|
public static Path changeShortExtension(String path, String extension) {
|
|
|
int from = Math.max(0, Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')));
|
|
int from = Math.max(0, Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')));
|
|
|
int index = path.substring(from).lastIndexOf(".");
|
|
int index = path.substring(from).lastIndexOf(".");
|
|
@@ -93,6 +209,16 @@ public class PathUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns true if path ends with provided suffix.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Behaviour is platform dependent:
|
|
|
|
|
+ * if current file system is case sensitive, then this methods is too.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @param extension extension
|
|
|
|
|
+ * @return boolean
|
|
|
|
|
+ */
|
|
|
public static boolean hasExtension(String path, String extension) {
|
|
public static boolean hasExtension(String path, String extension) {
|
|
|
if(CASE_SENSITIVE_FILES) {
|
|
if(CASE_SENSITIVE_FILES) {
|
|
|
return path.endsWith(extension);
|
|
return path.endsWith(extension);
|
|
@@ -101,28 +227,76 @@ public class PathUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns true if path ends with provided suffix.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Behaviour is platform dependent:
|
|
|
|
|
+ * if current file system is case sensitive, then this methods is too.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @param extension extension
|
|
|
|
|
+ * @return boolean
|
|
|
|
|
+ */
|
|
|
public static boolean hasExtension(Path path, String extension) {
|
|
public static boolean hasExtension(Path path, String extension) {
|
|
|
return hasExtension(path.toString(), extension);
|
|
return hasExtension(path.toString(), extension);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Extracts filename without long extension.
|
|
|
|
|
+ * For example: "c:\\windows\\file.txt.bak" will give "file"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
public static String getSimpleName(String path) {
|
|
public static String getSimpleName(String path) {
|
|
|
return getSimpleName(Paths.get(path));
|
|
return getSimpleName(Paths.get(path));
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Extracts filename without long extension.
|
|
|
|
|
+ * For example: "c:\\windows\\file.txt.bak" will give "file"
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
public static String getSimpleName(Path path) {
|
|
public static String getSimpleName(Path path) {
|
|
|
String name = path.getFileName().toString();
|
|
String name = path.getFileName().toString();
|
|
|
int index = name.indexOf(".");
|
|
int index = name.indexOf(".");
|
|
|
return index<0 ? name : name.substring(0, index);
|
|
return index<0 ? name : name.substring(0, index);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns normalized absolute path.
|
|
|
|
|
+ * It uses filesystem calls to compute both absolute path and normalization.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @return Path
|
|
|
|
|
+ */
|
|
|
public static Path normalize(Path path) {
|
|
public static Path normalize(Path path) {
|
|
|
return path.toAbsolutePath().normalize();
|
|
return path.toAbsolutePath().normalize();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns normalized absolute path.
|
|
|
|
|
+ * It uses filesystem calls to compute both absolute path and normalization.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param path path
|
|
|
|
|
+ * @return Path
|
|
|
|
|
+ */
|
|
|
public static String normalize(String path) {
|
|
public static String normalize(String path) {
|
|
|
return normalize(Paths.get(path)).toString();
|
|
return normalize(Paths.get(path)).toString();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns CQuery with all files inside directory.
|
|
|
|
|
+ * Returns both subdirectories and ordinary files.
|
|
|
|
|
+ * It is not recursive.
|
|
|
|
|
+ *
|
|
|
|
|
+ * The Path objects are obtained as if by resolving the name of the directory entry against dir.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param dir dir
|
|
|
|
|
+ * @return query
|
|
|
|
|
+ */
|
|
|
public static CQuery<Path> list(Path dir) {
|
|
public static CQuery<Path> list(Path dir) {
|
|
|
if(WALKER_JDK7) {
|
|
if(WALKER_JDK7) {
|
|
|
return listJDK7(dir);
|
|
return listJDK7(dir);
|
|
@@ -145,29 +319,85 @@ public class PathUtils {
|
|
|
return CQuery.from().stream(() -> Files.list(dir));
|
|
return CQuery.from().stream(() -> Files.list(dir));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns CQuery with all files inside directory matching provided wildcard
|
|
|
|
|
+ * Returns both subdirectories and ordinary files.
|
|
|
|
|
+ * It is not recursive.
|
|
|
|
|
+ *
|
|
|
|
|
+ * The Path objects are obtained as if by resolving the name of the directory entry against dir.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param dir dir
|
|
|
|
|
+ * @param wildcard wildcard
|
|
|
|
|
+ * @return query
|
|
|
|
|
+ */
|
|
|
public static CQuery<Path> list(Path dir, String wildcard) {
|
|
public static CQuery<Path> list(Path dir, String wildcard) {
|
|
|
return list(dir).filter(Wildcard.compile(wildcard).asPathFilter());
|
|
return list(dir).filter(Wildcard.compile(wildcard).asPathFilter());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns CQuery with all files inside directory.
|
|
|
|
|
+ * Returns both subdirectories and ordinary files.
|
|
|
|
|
+ * It is recursive.
|
|
|
|
|
+ * Recursively visited directories are returned too.
|
|
|
|
|
+ *
|
|
|
|
|
+ * The Path objects are obtained as if by resolving the name of the directory entry against dir.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param dir dir
|
|
|
|
|
+ * @return query
|
|
|
|
|
+ */
|
|
|
public static CQuery<Path> walk(Path dir) {
|
|
public static CQuery<Path> walk(Path dir) {
|
|
|
return list(dir).flatIf(Files::isDirectory, file -> {
|
|
return list(dir).flatIf(Files::isDirectory, file -> {
|
|
|
return CQuery.builder().with(file).withQuery(PathUtils.walk(file)).build();
|
|
return CQuery.builder().with(file).withQuery(PathUtils.walk(file)).build();
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns CQuery with all files inside directory matching provided wildcard
|
|
|
|
|
+ * Returns both subdirectories and ordinary files.
|
|
|
|
|
+ * It is recursive.
|
|
|
|
|
+ * Recursively visited directories are returned too.
|
|
|
|
|
+ *
|
|
|
|
|
+ * The Path objects are obtained as if by resolving the name of the directory entry against dir.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param dir dir
|
|
|
|
|
+ * @param wildcard wildcard
|
|
|
|
|
+ * @return query
|
|
|
|
|
+ */
|
|
|
public static CQuery<Path> walk(Path dir, String wildcard) {
|
|
public static CQuery<Path> walk(Path dir, String wildcard) {
|
|
|
return PathUtils.walk(dir).filter(Wildcard.compile(wildcard).asPathFilter());
|
|
return PathUtils.walk(dir).filter(Wildcard.compile(wildcard).asPathFilter());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns current working directory of application
|
|
|
|
|
+ *
|
|
|
|
|
+ * @return path
|
|
|
|
|
+ */
|
|
|
public static Path cwd() {
|
|
public static Path cwd() {
|
|
|
return PathUtils.normalize(Paths.get("."));
|
|
return PathUtils.normalize(Paths.get("."));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns common path part of two specified paths.
|
|
|
|
|
+ * It means: path to directory which contains both arguments.
|
|
|
|
|
+ * Returns empty path if there is no common root.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param a a
|
|
|
|
|
+ * @param b b
|
|
|
|
|
+ * @return path
|
|
|
|
|
+ */
|
|
|
public static Path common(Path a, Path b) {
|
|
public static Path common(Path a, Path b) {
|
|
|
return common0(a,b);
|
|
return common0(a,b);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns common path part of all specified paths.
|
|
|
|
|
+ * It means: path to directory which contains all paths.
|
|
|
|
|
+ * Returns empty path if there is no common root.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param values values
|
|
|
|
|
+ * @return path
|
|
|
|
|
+ */
|
|
|
public static Path common(Collection<Path> values) {
|
|
public static Path common(Collection<Path> values) {
|
|
|
if(values.isEmpty()) {
|
|
if(values.isEmpty()) {
|
|
|
return cwd();
|
|
return cwd();
|