/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Lachlan Dowding
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package permafrost.tundra.io;
import com.wm.app.b2b.server.MimeTypes;
import com.wm.data.IData;
import com.wm.data.IDataCursor;
import com.wm.data.IDataFactory;
import com.wm.data.IDataUtil;
import permafrost.tundra.io.filter.RegularExpressionFilenameFilter;
import permafrost.tundra.io.filter.WildcardFilenameFilter;
import permafrost.tundra.lang.BooleanHelper;
import permafrost.tundra.lang.CharsetHelper;
import permafrost.tundra.lang.StringHelper;
import permafrost.tundra.math.LongHelper;
import permafrost.tundra.mime.MIMETypeHelper;
import permafrost.tundra.net.uri.URIHelper;
import permafrost.tundra.time.DateTimeHelper;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* A collection of convenience methods for working with files.
*/
public final class FileHelper {
/**
* Disallow instantiation of this class.
*/
private FileHelper() {}
/**
* @return true if the file system is case insensitive.
*/
public static boolean isCaseInsensitive() {
return (new File("TUNDRA")).equals(new File("tundra"));
}
/**
* @return true if the file system is case sensitive.
*/
public static boolean isCaseSensitive() {
return !isCaseInsensitive();
}
/**
* Returns the MIME media type that describes the content of the given file.
*
* @param file The file whose MIME type is to be returned.
* @return The MIME media type that describes the content of the given file.
*/
public static String getMIMEType(File file) {
String type = null;
if (file != null) type = MimeTypes.getTypeFromName(file.getName());
if (type == null) type = MIMETypeHelper.DEFAULT_MIME_TYPE_STRING;
return type;
}
/**
* Returns the MIME media type that describes the content of the given file.
*
* @param filename The file whose MIME type is to be returned.
* @return The MIME media type that describes the content of the given file.
*/
public static String getMIMEType(String filename) {
return getMIMEType(construct(filename));
}
/**
* Returns true if the given file exists and is a file.
*
* @param file The file to check existence of.
* @return true if the given file exists and is a file.
*/
public static boolean exists(File file) {
return file == null ? false : file.exists() && file.isFile();
}
/**
* Returns true if the given file exists and is a file.
*
* @param filename The file to check existence of.
* @return true if the given file exists and is a file.
*/
public static boolean exists(String filename) {
return exists(construct(filename));
}
/**
* Creates a new, empty temporary file.
*
* @return The file which was created.
* @throws IOException If the file already exists.
*/
public static File create() throws IOException {
return create((File)null);
}
/**
* Creates a new, empty file; if file is null, a temporary file is created.
*
* @param file The file to be created.
* @return The file which was created.
* @throws IOException If the file already exists.
*/
public static File create(File file) throws IOException {
if (file == null) {
file = File.createTempFile("tundra", null);
} else {
File parent = file.getParentFile();
if (parent != null) parent.mkdirs(); // automatically create directories if required
if (!file.createNewFile()) {
throw new IOException("Unable to create file because it already exists: " + normalize(file));
}
}
return file;
}
/**
* Creates a new, empty file; if filename is null, a temporary file is created.
*
* @param filename The name of the file to be created.
* @return The name of the file which was created.
* @throws IOException If the filename is unparseable or the file already exists.
*/
public static String create(String filename) throws IOException {
return normalize(create(construct(filename)));
}
/**
* Deletes the given file.
*
* @param file The file to be deleted.
* @throws IOException If the file cannot be deleted.
*/
public static void remove(File file) throws IOException {
if (file != null && exists(file) && !file.delete()) {
throw new IOException("Unable to remove file: " + normalize(file));
}
}
/**
* Deletes the given file.
*
* @param filename The name of the file to be deleted.
* @throws IOException If the filename is unparseable or the file cannot be deleted.
*/
public static void remove(String filename) throws IOException {
remove(construct(filename));
}
/**
* Update the modified time of the given file to the current time, or create it if it does not exist.
*
* @param file The file to be touched.
* @throws IOException If the file cannot be created.
*/
public static void touch(File file) throws IOException {
if (file.exists()) {
file.setLastModified((new Date()).getTime());
} else {
create(file);
}
}
/**
* Update the modified time of the given file to the current time, or create it if it does not exist.
*
* @param filename The name of the file to be touched.
* @throws IOException If the filename is unparseable.
*/
public static void touch(String filename) throws IOException {
touch(construct(filename));
}
/**
* Renames the source file to the target name.
*
* @param source The file to be renamed.
* @param target The new name of the file.
* @throws IOException If the file cannot be renamed.
*/
public static void rename(File source, File target) throws IOException {
if (source != null && target != null) {
if (!exists(source) || exists(target) || !source.renameTo(target)) {
throw new IOException("Unable to rename file " + normalize(source) + " to " + normalize(target));
}
}
}
/**
* Renames the source file to the target name.
*
* @param source The file to be renamed.
* @param target The new name of the file.
* @throws IOException If file cannot be renamed.
*/
public static void rename(String source, String target) throws IOException {
rename(construct(source), construct(target));
}
/**
* Reads the given file completely, returning the file's content as a byte[].
*
* @param filename The name of the file to be read.
* @return A byte[] containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static byte[] readToBytes(String filename) throws IOException {
return readToBytes(construct(filename));
}
/**
* Reads the given file completely, returning the file's content as a byte[].
*
* @param file The file to be read.
* @return A byte[] containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static byte[] readToBytes(File file) throws IOException {
byte[] content = null;
if (file != null) {
InputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
try {
inputStream = new FileInputStream(file);
outputStream = new ByteArrayOutputStream(InputOutputHelper.DEFAULT_BUFFER_SIZE);
InputOutputHelper.copy(inputStream, outputStream);
content = outputStream.toByteArray();
} finally {
CloseableHelper.close(inputStream, outputStream);
}
}
return content;
}
/**
* Reads the given file completely, returning the file's content as a String.
*
* @param filename The name of the file to be read.
* @return A String containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static String readToString(String filename) throws IOException {
return readToString(filename, CharsetHelper.DEFAULT_CHARSET);
}
/**
* Reads the given file completely, returning the file's content as a String.
*
* @param filename The name of the file to be read.
* @param charsetName The character set the file's content is encoded with.
* @return A String containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static String readToString(String filename, String charsetName) throws IOException {
return readToString(filename, CharsetHelper.normalize(charsetName));
}
/**
* Reads the given file completely, returning the file's content as a String.
*
* @param filename The name of the file to be read.
* @param charset The character set the file's content is encoded with.
* @return A String containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static String readToString(String filename, Charset charset) throws IOException {
return readToString(construct(filename), CharsetHelper.normalize(charset));
}
/**
* Reads the given file completely, returning the file's content as a String.
*
* @param file The file to be read.
* @return A String containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static String readToString(File file) throws IOException {
return readToString(file, CharsetHelper.DEFAULT_CHARSET);
}
/**
* Reads the given file completely, returning the file's content as a String.
*
* @param file The file to be read.
* @param charsetName The character set the file's content is encoded with.
* @return A String containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static String readToString(File file, String charsetName) throws IOException {
return readToString(file, CharsetHelper.normalize(charsetName));
}
/**
* Reads the given file completely, returning the file's content as a String.
*
* @param file The file to be read.
* @param charset The character set the file's content is encoded with.
* @return A String containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static String readToString(File file, Charset charset) throws IOException {
return StringHelper.normalize(readToBytes(file), CharsetHelper.normalize(charset));
}
/**
* Reads the given file completely, returning the file's content as a java.io.InputStream.
*
* @param filename The name of the file to be read.
* @return A java.io.InputStream containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static InputStream readToStream(String filename) throws IOException {
return readToStream(construct(filename));
}
/**
* Reads the given file completely, returning the file's content as a java.io.InputStream.
*
* @param file The file to be read.
* @return A java.io.InputStream containing the file's content.
* @throws IOException If there is a problem reading the file.
*/
public static InputStream readToStream(File file) throws IOException {
return new ByteArrayInputStream(readToBytes(file));
}
/**
* Writes content to a file; if the given file is null, a new temporary file is automatically created.
*
* @param file The file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The file which the content was written to.
* @throws IOException If there is a problem writing to the file.
*/
public static File writeFromStream(File file, InputStream content, boolean append) throws IOException {
if (file == null || !exists(file)) file = create(file);
if (content != null) InputOutputHelper.copy(content, new FileOutputStream(file, append));
return file;
}
/**
* Writes content to a file; if the given filename is null, a new temporary file is automatically created.
*
* @param filename The name of the file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The name of the file which the content was written to.
* @throws IOException If there is a problem writing to the file.
*/
public static String writeFromStream(String filename, InputStream content, boolean append) throws IOException {
return normalize(writeFromStream(construct(filename), content, append));
}
/**
* Writes content to a file; if the given file is null, a new temporary file is automatically created.
*
* @param file The file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The file which the content was written to.
* @throws IOException If there is a problem writing to the file.
*/
public static File writeFromBytes(File file, byte[] content, boolean append) throws IOException {
return writeFromStream(file, InputStreamHelper.normalize(content), append);
}
/**
* Writes content to a file; if the given filename is null, a new temporary file is automatically created.
*
* @param filename The name of the file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The name of the file which the content was written to.
* @throws IOException If the filename is unparseable or there is a problem writing to the file.
*/
public static String writeFromBytes(String filename, byte[] content, boolean append) throws IOException {
return normalize(writeFromBytes(construct(filename), content, append));
}
/**
* Writes content to a file; if the given file is null, a new temporary file is automatically created.
*
* @param file The file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param charsetName The character set to encode the content with.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The file which the content was written to.
* @throws IOException If there is a problem writing to the file.
*/
public static File writeFromString(File file, String content, String charsetName, boolean append) throws IOException {
return writeFromString(file, content, CharsetHelper.normalize(charsetName), append);
}
/**
* Writes content to a file; if the given file is null, a new temporary file is automatically created.
*
* @param file The file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param charset The character set to encode the content with.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The file which the content was written to.
* @throws IOException If there is a problem writing to the file.
*/
public static File writeFromString(File file, String content, Charset charset, boolean append) throws IOException {
return writeFromStream(file, InputStreamHelper.normalize(content, charset), append);
}
/**
* Writes content to a file; if the given filename is null, a new temporary file is automatically created.
*
* @param filename The name of the file to be written to; if null, a new temporary file is automatically
* created.
* @param content The content to be written.
* @param charsetName The character set to encode the content with.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The name of the file which the content was written to.
* @throws IOException If the filename is unparseable or there is a problem writing to the file.
*/
public static String writeFromString(String filename, String content, String charsetName, boolean append) throws IOException {
return writeFromString(filename, content, CharsetHelper.normalize(charsetName), append);
}
/**
* Writes content to a file; if the given filename is null, a new temporary file is automatically created.
*
* @param filename The name of the file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param charset The character set to encode the content with.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The name of the file which the content was written to.
* @throws IOException If the filename is unparseable or there is a problem writing to the file.
*/
public static String writeFromString(String filename, String content, Charset charset, boolean append) throws IOException {
return normalize(writeFromString(construct(filename), content, charset, append));
}
/**
* Writes content to a file; if the given file is null, a new temporary file is automatically created.
*
* @param file The file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The file which the content was written to.
* @throws IOException If there is a problem writing to the file.
*/
public static File writeFromString(File file, String content, boolean append) throws IOException {
return writeFromString(file, content, CharsetHelper.DEFAULT_CHARSET, append);
}
/**
* Writes content to a file; if the given filename is null, a new temporary file is automatically created.
*
* @param filename The name of the file to be written to; if null, a new temporary file is automatically created.
* @param content The content to be written.
* @param append If true, the content will be appended to the file, otherwise the content will overwrite any
* previous content in the file.
* @return The name of the file which the content was written to.
* @throws IOException If there is a problem writing to the file.
*/
public static String writeFromString(String filename, String content, boolean append) throws IOException {
return normalize(writeFromString(construct(filename), content, append));
}
/**
* Copies the content in the source file to the target file.
*
* @param source The file from which content will be copied.
* @param target The file to which content will be copied.
* @param append If true, the target content will be appended to, otherwise any previous content will be
* overwritten.
* @throws IOException If the source file does not exist or there is a problem copying it.
*/
public static void copy(File source, File target, boolean append) throws IOException {
if (source != null && target != null) {
InputStream input = new FileInputStream(source);
OutputStream output = new FileOutputStream(target, append);
InputOutputHelper.copy(input, output);
}
}
/**
* Copies the content in the source file to the target file.
*
* @param source The file from which content will be copied.
* @param target The file to which content will be copied.
* @param append If true, the target content will be appended to, otherwise any previous content will be
* overwritten.
* @throws IOException If the source file does not exist or there is a problem copying it.
*/
public static void copy(String source, String target, boolean append) throws IOException {
copy(construct(source), construct(target), append);
}
/**
* GZips the given file as a new file in the same directory with the same name suffixed with ".gz".
*
* @param source The file to be gzipped.
* @param replace Whether the source file should be deleted once compressed.
* @return The resulting gzipped file.
* @throws IOException If an IO error occurs.
*/
public static String gzip(String source, boolean replace) throws IOException {
return normalize(gzip(construct(source), replace));
}
/**
* Gzips the given file as a new file in the same directory with the same name suffixed with ".gz".
*
* @param source The file to be gzipped.
* @param replace Whether the source file should be deleted once compressed.
* @return The resulting gzipped file.
* @throws IOException If an IO error occurs.
*/
public static File gzip(File source, boolean replace) throws IOException {
return gzip(source, null, replace);
}
/**
* Gzips the given file as a new file with the given target name.
*
* @param source The file to be gzipped.
* @param target The file to write the gzipped content to.
* @param replace Whether the source file should be deleted once compressed.*
* @return The resulting gzipped file.
* @throws IOException If an IO error occurs.
*/
public static String gzip(String source, String target, boolean replace) throws IOException {
return normalize(gzip(construct(source), construct(target), replace));
}
/**
* Gzips the given file as a new file with the given target name.
*
* @param source The file to be gzipped.
* @param target The file to write the gzipped content to.
* @param replace Whether the source file should be deleted once compressed.
* @return The resulting gzipped file.
* @throws IOException If an IO error occurs.
*/
public static File gzip(File source, File target, boolean replace) throws IOException {
if (source == null) throw new NullPointerException("source must not be null");
if (target == null) target = new File(source.getParentFile(), source.getName() + ".gz");
if (source.exists()) {
if (source.isFile()) {
if (source.canRead() && (!replace || source.canWrite())) {
if (target.exists()) {
throw new IOException("Unable to create file because it already exists: " + normalize(target));
} else {
InputOutputHelper.copy(new FileInputStream(source), new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(target), InputOutputHelper.DEFAULT_BUFFER_SIZE)));
target.setLastModified(source.lastModified());
if (replace) source.delete();
return target;
}
} else {
throw new IOException("Unable to gzip file because access is denied: " + normalize(source));
}
} else {
throw new IOException("Unable to gzip file because it is a directory: " + normalize(source));
}
} else {
throw new IOException("Unable to gzip file because it does not exist: " + normalize(source));
}
}
/**
* Zips the given file as a new file in the same directory with the same name suffixed with ".zip".
*
* @param source The file to be zipped.
* @param replace Whether the source file should be deleted once compressed.
* @return The resulting zipped file.
* @throws IOException If an IO error occurs.
*/
public static String zip(String source, boolean replace) throws IOException {
return normalize(zip(construct(source), replace));
}
/**
* Zips the given file as a new file in the same directory with the same name suffixed with ".zip".
*
* @param source The file to be zipped.
* @param replace Whether the source file should be deleted once compressed.
* @return The resulting zipped file.
* @throws IOException If an IO error occurs.
*/
public static File zip(File source, boolean replace) throws IOException {
return zip(source, null, replace);
}
/**
* Zips the given file as a new file with the given name.
*
* @param source The file to be zipped.
* @param target The file to write the zipped content to.
* @param replace Whether the source file should be deleted once compressed.
* @return The resulting zipped file.
* @throws IOException If an IO error occurs.
*/
public static String zip(String source, String target, boolean replace) throws IOException {
return normalize(zip(construct(source), construct(target), replace));
}
/**
* Zips the given file as a new file with the given target name.
*
* @param source The file to be zipped.
* @param target The file to write the zipped content to. If not specified, defaults to a file with
* the same name as source suffixed with ".zip".
* @param replace Whether the source file should be deleted once compressed.
* @return The resulting zipped file.
* @throws IOException If an IO error occurs.
*/
public static File zip(File source, File target, boolean replace) throws IOException {
if (source == null) throw new NullPointerException("source must not be null");
if (target == null) target = new File(source.getParentFile(), source.getName() + ".zip");
if (source.exists()) {
if (source.isFile()) {
if (source.canRead() && (!replace || source.canWrite())) {
if (target.exists()) {
throw new IOException("Unable to create file because it already exists: " + normalize(target));
} else {
InputStream inputStream = null;
ZipOutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(source), InputOutputHelper.DEFAULT_BUFFER_SIZE);
outputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(target), InputOutputHelper.DEFAULT_BUFFER_SIZE));
outputStream.putNextEntry(new ZipEntry(source.getName()));
InputOutputHelper.copy(inputStream, outputStream, false);
} finally {
if (outputStream != null) outputStream.closeEntry();
CloseableHelper.close(inputStream, outputStream);
target.setLastModified(source.lastModified());
if (replace) source.delete();
}
return target;
}
} else {
throw new IOException("Unable to zip file because access is denied: " + normalize(source));
}
} else {
throw new IOException("Unable to zip file because it is a directory: " + normalize(source));
}
} else {
throw new IOException("Unable to zip file because it does not exist: " + normalize(source));
}
}
/**
* Returns a File object given a file name.
*
* @param filename The name of the file, specified as a path or file:// URI.
* @return The file representing the given name.
*/
public static File construct(String filename) {
File file = null;
if (filename != null) {
if (filename.toLowerCase().startsWith("file:")) {
try {
file = new File(new URI(filename));
} catch (IllegalArgumentException ex) {
// work around java's weird handling of file://server/path style URIs on Windows, by changing the URI
// to be file:////server/path
if (filename.toLowerCase().startsWith("file://") && !filename.toLowerCase().startsWith("file:///")) {
file = construct("file:////" + filename.substring(6, filename.length()));
} else {
throw ex;
}
} catch (URISyntaxException ex) {
throw new IllegalArgumentException(ex);
}
} else {
file = new File(filename);
}
}
return file;
}
/**
* Returns the canonical file:// URI representation of the given file.
*
* @param file The file to be normalized.
* @return The canonical file:// URI representation of the given file.
*/
public static String normalize(File file) {
String filename = null;
try {
if (file != null) filename = URIHelper.normalize(file.getCanonicalFile().toURI().toString());
} catch (IOException ex) {
throw new RuntimeException(ex);
} catch (URISyntaxException ex) {
throw new RuntimeException(ex);
}
return filename;
}
/**
* Returns the canonical file:// URI representation of the given file.
*
* @param filename The name of the file to be normalized.
* @return The canonical file:// URI representation of the given file.
*/
public static String normalize(String filename) {
return normalize(construct(filename));
}
/**
* Returns true if the given file matches the given pattern.
*
* @param filename The name of the file to check against the pattern.
* @param pattern Either a regular expression or wildcard pattern.
* @param patternIsRegularExpression Boolean indicating if the given pattern is a regular expression or wildcard
* pattern.
* @return True if the given file matches the given pattern.
*/
public static boolean match(String filename, String pattern, boolean patternIsRegularExpression) {
return match(construct(filename), pattern, patternIsRegularExpression);
}
/**
* Returns true if the given file matches the given pattern.
*
* @param file The file to check against the pattern.
* @param pattern Either a regular expression or wildcard pattern.
* @param patternIsRegularExpression Boolean indicating if the given pattern is a regular expression or wildcard
* pattern.
* @return True if the given file matches the given pattern.
*/
public static boolean match(File file, String pattern, boolean patternIsRegularExpression) {
boolean match = false;
if (file != null && pattern != null) {
java.io.FilenameFilter filter;
if (patternIsRegularExpression) {
filter = new RegularExpressionFilenameFilter(pattern);
} else {
filter = new WildcardFilenameFilter(pattern);
}
match = filter.accept(file.getParentFile(), file.getName());
}
return match;
}
/**
* Returns whether the given file can be written to by this process.
*
* @param file The file to check the permissions of.
* @return Whether the given file is writable by this process.
*/
public static boolean isWritable(File file) {
if (file == null) return false;
return file.canWrite();
}
/**
* Returns whether the given file can be written to by this process.
*
* @param filename The file to check the permissions of.
* @return Whether the given file is writable by this process.
*/
public static boolean isWritable(String filename) {
return isWritable(construct(filename));
}
/**
* Returns whether the given file can be read by this process.
*
* @param file The file to check the permissions of.
* @return Whether the given file is readable by this process.
*/
public static boolean isReadable(File file) {
if (file == null) return false;
return file.canRead();
}
/**
* Returns whether the given file can be read by this process.
*
* @param filename The file to check the permissions of.
* @return Whether the given file is readable by this process.
*/
public static boolean isReadable(String filename) {
return isReadable(construct(filename));
}
/**
* Returns whether the given file can be executed by this process.
*
* @param file The file to check the permissions of.
* @return Whether the given file is executable by this process.
*/
public static boolean isExecutable(File file) {
if (file == null) return false;
return file.canExecute();
}
/**
* Returns whether the given file can be executed by this process.
*
* @param filename The file to check the permissions of.
* @return Whether the given file is executable by this process.
*/
public static boolean isExecutable(String filename) {
return isExecutable(construct(filename));
}
/**
* Returns the length of the given file in bytes.
*
* @param file The file to check the length of.
* @return The length in bytes of the given file.
*/
public static long length(File file) {
if (file == null) return 0;
return file.length();
}
/**
* Returns the length of the given file in bytes.
*
* @param filename The file to check the length of.
* @return The length in bytes of the given file.
*/
public static long length(String filename) {
return length(construct(filename));
}
/**
* Returns only the name component of the given file.
*
* @param file The file to return the name of.
* @return The name component only of the given file.
*/
public static String getName(File file) {
if (file == null || file.equals("")) return null;
return file.getName();
}
/**
* Returns only the name component of the given file.
*
* @param filename The file to return the name of.
* @return The name component only of the given file.
*/
public static String getName(String filename) {
return getName(construct(filename));
}
/**
* Returns the base and extension parts of the given file's name.
*
* @param file The file to get the name parts of.
* @return The parts of the given file's name.
*/
public static String[] getNameParts(File file) {
String[] parts = null;
String name = getName(file);
if (name != null) {
parts = name.split("\\.(?=[^\\.]+$)");
}
return parts;
}
/**
* Returns the filename extension for the given file.
*
* @param file The file whose extension is to be returned.
* @return The filename extension for the given file.
*/
public static String getExtension(File file) {
return file == null ? null : MimeTypes.getExtensionFromName(file.getName());
}
/**
* Returns the base and extension parts of the given file's name.
*
* @param filename The file to get the name parts of.
* @return The parts of the given file's name.
*/
public static String[] getNameParts(String filename) {
return getNameParts(construct(filename));
}
/**
* Returns the parent directory containing the given file.
*
* @param file The file to return the parent directory of.
* @return The parent directory of the given file.
*/
public static File getParentDirectory(File file) {
if (file == null) return null;
return file.getParentFile();
}
/**
* Returns the parent directory containing the given file.
*
* @param filename The file to return the parent directory of.
* @return The parent directory of the given file.
*/
public static File getParentDirectory(String filename) {
return getParentDirectory(construct(filename));
}
/**
* Returns the parent directory containing the given file as a string.
*
* @param file The file to return the parent directory of.
* @return The parent directory of the given file.
*/
public static String getParentDirectoryAsString(File file) {
return normalize(getParentDirectory(file));
}
/**
* Returns the parent directory containing the given file as a string.
*
* @param filename The file to return the parent directory of.
* @return The parent directory of the given file.
*/
public static String getParentDirectoryAsString(String filename) {
return getParentDirectoryAsString(construct(filename));
}
/**
* Returns the last modified datetime of the given file.
*
* @param file The file to return the last modified datetime of.
* @return The last modified datetime of the given file.
*/
public static Date getLastModifiedDate(File file) {
if (file == null) return null;
return new Date(file.lastModified());
}
/**
* Returns the last modified datetime of the given file.
*
* @param filename The file to return the last modified datetime of.
* @return The last modified datetime of the given file.
*/
public static Date getLastModifiedDate(String filename) {
return getLastModifiedDate(construct(filename));
}
/**
* Returns the last modified datetime of the given file as an ISO8601 formatted datetime string.
*
* @param file The file to return the last modified datetime of.
* @return The last modified datetime of the given file.
*/
public static String getLastModifiedDateTimeString(File file) {
return DateTimeHelper.emit(getLastModifiedDate(file));
}
/**
* Returns the last modified datetime of the given file as an ISO8601 formatted datetime string.
*
* @param filename The file to return the last modified datetime of.
* @return The last modified datetime of the given file.
*/
public static String getLastModifiedDateTimeString(String filename) {
return getLastModifiedDateTimeString(construct(filename));
}
/**
* Returns an IData document containing the properties of the given file.
*
* @param filename The file to return the properties for.
* @return The properties of the given file as an IData document.
*/
public static IData getPropertiesAsIData(String filename) {
return getPropertiesAsIData(construct(filename));
}
/**
* Returns an IData document containing the properties of the given file.
*
* @param file The file to return the properties for.
* @return The properties of the given file as an IData document.
*/
public static IData getPropertiesAsIData(File file) {
IData output = IDataFactory.create();
IDataCursor cursor = output.getCursor();
boolean isFile = file.isFile();
boolean exists = exists(file);
IDataUtil.put(cursor, "exists?", BooleanHelper.emit(exists));
String parent = getParentDirectoryAsString(file);
if (parent != null) IDataUtil.put(cursor, "parent", parent);
String name = getName(file);
if (name != null) IDataUtil.put(cursor, "name", name);
String[] parts = getNameParts(file);
if (parts != null) {
if (parts.length > 0) IDataUtil.put(cursor, "base", parts[0]);
if (parts.length > 1) IDataUtil.put(cursor, "extension", parts[1]);
}
if (isFile) IDataUtil.put(cursor, "type", getMIMEType(file));
if (exists) {
IDataUtil.put(cursor, "length", LongHelper.emit(length(file)));
IDataUtil.put(cursor, "modified", getLastModifiedDateTimeString(file));
IDataUtil.put(cursor, "executable?", BooleanHelper.emit(isExecutable(file)));
IDataUtil.put(cursor, "readable?", BooleanHelper.emit(isReadable(file)));
IDataUtil.put(cursor, "writable?", BooleanHelper.emit(isWritable(file)));
}
IDataUtil.put(cursor, "uri", normalize(file));
cursor.destroy();
return output;
}
}