package org.jbake.app;
import org.apache.commons.configuration.CompositeConfiguration;
import org.jbake.app.ConfigUtil.Keys;
import org.jbake.parser.Engines;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.security.MessageDigest;
/**
* Provides File related functions
*
* @author Jonathan Bullock <a href="mailto:jonbullock@gmail.com">jonbullock@gmail.com</a>
*/
public class FileUtil {
/**
* Filters files based on their file extension.
*
* @return Object for filtering files
*/
public static FileFilter getFileFilter() {
return new FileFilter() {
@Override
public boolean accept(File pathname) {
return !pathname.isFile()
|| Engines.getRecognizedExtensions().contains(fileExt(pathname));
}
};
}
public static boolean isExistingFolder(File f) {
return null != f && f.exists() && f.isDirectory();
}
/**
* Works out the folder where JBake is running from.
*
* @return File referencing folder JBake is running from
* @throws Exception when application is not able to work out where is JBake running from
*/
public static File getRunningLocation() throws Exception {
String codePath = FileUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(codePath, "UTF-8");
File codeFile = new File(decodedPath);
if (!codeFile.exists()) {
throw new Exception("Cannot locate running location of JBake!");
}
File codeFolder = codeFile.getParentFile().getParentFile();
if (!codeFolder.exists()) {
throw new Exception("Cannot locate running location of JBake!");
}
return codeFolder;
}
public static String fileExt(File src) {
String name = src.getName();
return fileExt(name);
}
public static String fileExt(String name) {
int idx = name.lastIndexOf('.');
if (idx > 0) {
return name.substring(idx + 1);
} else {
return "";
}
}
/**
* Computes the hash of a file or directory.
*
* @param sourceFile the original file or directory
* @return an hex string representing the SHA1 hash of the file or directory.
* @throws Exception if any IOException of SecurityException occured
*/
public static String sha1(File sourceFile) throws Exception {
byte[] buffer = new byte[1024];
MessageDigest complete = MessageDigest.getInstance("SHA-1");
updateDigest(complete, sourceFile, buffer);
byte[] bytes = complete.digest();
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
private static void updateDigest(final MessageDigest digest, final File sourceFile, final byte[] buffer) throws IOException {
if (sourceFile.isFile()) {
InputStream fis = new FileInputStream(sourceFile);
int numRead;
do {
numRead = fis.read(buffer);
if (numRead > 0) {
digest.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
} else if (sourceFile.isDirectory()) {
File[] files = sourceFile.listFiles();
if (files!=null) {
for (File file : files) {
updateDigest(digest, file, buffer);
}
}
}
}
public static String findExtension(CompositeConfiguration config, String docType) {
String extension = config.getString("template."+docType+".extension");
if (extension != null) {
return extension;
} else {
return config.getString(Keys.OUTPUT_EXTENSION);
}
}
/**
* platform independent file.getPath()
*
* @param file the file to transform, or {@code null}
* @return The result of file.getPath() with all path Separators beeing a "/", or {@code null}
* Needed to transform Windows path separators into slashes.
*/
public static String asPath(File file) {
if(file == null) {
return null;
}
return asPath(file.getPath());
}
/**
* platform independent file.getPath()
*
* @param path the path to transform, or {@code null}
* @return The result will have alle platform path separators replaced by "/".
*/
public static String asPath(String path) {
if(path == null) {
return null;
}
return path.replace(File.separator, "/");
}
}