package com.vitco.util.file;
import com.vitco.core.container.HackedObjectInputStream;
import com.vitco.manager.error.ErrorHandlerInterface;
import com.vitco.util.misc.AutoFileCloser;
import java.io.*;
import java.util.HashMap;
/**
* Some basic tools to deal with files and streams.
*/
public class FileTools {
// find all files with a particular ending in folder
public static File[] findFiles(String dirName, final String ext){
File dir = new File(dirName);
return dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename) {
return filename.endsWith("." + ext);
}
});
}
// add a separator to file path if not already present
public static String ensureTrailingSeparator(String path) {
if (path.charAt(path.length()-1) != File.separatorChar) {
path += File.separator;
}
return path;
}
// todo: improve so it only ever erases from "slash to slash"
// shorten a long file path for display purposes
public static String shortenPath(String path, int length) {
int originalLength = path.length();
if (originalLength <= length) {
return path;
}
int toCrop = originalLength - length + 3;
if (toCrop > originalLength) {
toCrop = originalLength;
}
int starting = originalLength/2 - toCrop/2;
int stopping = starting + toCrop;
return path.substring(0, starting) + "..." + path.substring(stopping, originalLength);
}
// remove extension from file and return name without extension
public static String extractNameWithoutExtension(File f) {
// if it's a directory, don't remove the extension
if (f.isDirectory()) return f.getName();
String name = f.getName();
// if it is a hidden file
if (name.startsWith(".")) {
// if there is no extension, do not remove one...
if (name.lastIndexOf('.') == name.indexOf('.')) return name;
}
// if there is no extension, don't do anything
if (!name.contains(".")) return name;
// Otherwise, remove the last 'extension type thing'
return name.substring(0, name.lastIndexOf('.'));
}
// remove extension from file and return file path without extension
public static String removeExtension(File f) {
// if it's a directory, don't remove the extension
if (f.isDirectory()) return f.getAbsolutePath();
String name = f.getName();
// if it is a hidden file
if (name.startsWith(".")) {
// if there is no extension, do not remove one...
if (name.lastIndexOf('.') == name.indexOf('.')) return f.getAbsolutePath();
}
// if there is no extension, don't do anything
if (!name.contains(".")) return f.getAbsolutePath();
// Otherwise, remove the last 'extension type thing'
return f.getAbsolutePath().substring(0, f.getAbsolutePath().lastIndexOf('.'));
}
// reads the content of a file as string
public static String readFileAsString(File file, ErrorHandlerInterface errorHandler){
String result = "";
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
StringBuilder str = new StringBuilder();
String line = br.readLine();
while (line != null)
{
str.append(line).append("\n");
line = br.readLine();
}
result = str.toString();
} catch (FileNotFoundException e) {
errorHandler.handle(e);
} catch (IOException e) {
errorHandler.handle(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
errorHandler.handle(e);
}
}
}
return result;
}
// de-serialize object from file
public static Object loadFromFile(final File file, ErrorHandlerInterface errorHandler) {
final Object[] result = {null};
if (file != null && file.exists()) {
try {
new AutoFileCloser() {
@Override protected void doWork() throws Throwable {
try {
InputStream inputStream = autoClose(new FileInputStream(file));
InputStream buffer = autoClose(new BufferedInputStream(inputStream));
ObjectInput input = autoClose(new HackedObjectInputStream(buffer));
result[0] = input.readObject();
} catch (StreamCorruptedException ignored) {} // caused if the file format is invalid
}
};
} catch (RuntimeException e) {
errorHandler.handle(e);
}
}
return result[0];
}
// serialize object to file
public static boolean saveToFile(final File file, final Object object, ErrorHandlerInterface errorHandler) {
final boolean[] result = {false};
try {
new AutoFileCloser() {
@Override protected void doWork() throws Throwable {
OutputStream outputStream = autoClose(new FileOutputStream( file ));
OutputStream buffer = autoClose(new BufferedOutputStream( outputStream ));
ObjectOutput output = autoClose(new ObjectOutputStream( buffer ));
output.writeObject(object);
result[0] = true;
}
};
} catch (RuntimeException e) {
errorHandler.handle(e);
}
return result[0];
}
// convert inputstream to string
public static String inputStreamToString(InputStream in) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
// remove the last line break (was not in file!)
stringBuilder.deleteCharAt(stringBuilder.length()-1);
bufferedReader.close();
return stringBuilder.toString();
}
// Generic Helper to keep casts safe when de-serializing hash-maps.
// "prevent compiler warning by explicitly casting"
public static <K, V> HashMap<K, V> castHash(HashMap input,
Class<K> keyClass,
Class<V> valueClass) {
HashMap<K, V> output = new HashMap<K, V>();
if (input == null)
return output;
for (Object key: input.keySet().toArray()) {
if ((key == null) || (keyClass.isAssignableFrom(key.getClass()))) {
Object value = input.get(key);
if ((value == null) || (valueClass.isAssignableFrom(value.getClass()))) {
K k = keyClass.cast(key);
V v = valueClass.cast(value);
output.put(k, v);
} else {
throw new AssertionError(
"Cannot cast to HashMap<"+ keyClass.getSimpleName()
+", "+ valueClass.getSimpleName() +">"
+", value "+ value +" is not a "+ valueClass.getSimpleName()
);
}
} else {
throw new AssertionError(
"Cannot cast to HashMap<"+ keyClass.getSimpleName()
+", "+ valueClass.getSimpleName() +">"
+", key "+ key +" is not a " + keyClass.getSimpleName()
);
}
}
return output;
}
// change the extension of a file e.g. "test.txt", ".dat" -> "test.dat"
public static String changeExtension(String originalName, String newExtension) {
int lastDot = originalName.lastIndexOf(".");
if (lastDot != -1) {
return originalName.substring(0, lastDot) + newExtension;
} else {
return originalName + newExtension;
}
}
}