blob: 92a11b15c4201d699eac9b422ccf9204792a1ee7 [file] [log] [blame]
package org.freemarker.docgen;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.charset.Charset;
final class FileUtil {
private static final int READ_BUFFER_SIZE = 4096;
// Can't be instantiated
private FileUtil() {
// nop
}
private static final int COPY_BUFFER_SIZE = 64 * 1024;
/**
* Copies a class-loader resource into a plain file of the same name.
* The path of the source resource is calculated as
* {@link srcDirClass}'s package path +
* {@link srcDirFurtherPath} +
* {@link srcRelativePath}.
* The path of the destination file is calculated as
* {@link destDir} + {@link srcRelativePath}.
*
* @param srcBaseDir Possibly {@code null}.
*/
static void copyResourceIntoFile(
Class<?> srcBaseClass, String srcBaseDir,
String srcRelativePath, File destDir)
throws IOException {
File dstFile = new File(
destDir,
srcRelativePath.replace('/', File.separatorChar));
File curDestDir = dstFile.getParentFile();
if (!curDestDir.isDirectory() && !curDestDir.mkdirs()) {
throw new IOException("Failed to create destination directory: "
+ curDestDir.getAbsolutePath());
}
byte[] buffer = new byte[COPY_BUFFER_SIZE];
String finalResourcePath;
if (srcBaseDir == null || srcBaseDir.length() == 0) {
finalResourcePath = srcRelativePath;
} else {
finalResourcePath = srcBaseDir + "/" + srcRelativePath;
}
InputStream in = srcBaseClass.getResourceAsStream(finalResourcePath);
if (in == null) {
throw new IOException("Failed to open class-loader resource: "
+ finalResourcePath + " relatively to "
+ Transform.class.getPackage().getName());
}
try {
OutputStream out = new FileOutputStream(dstFile);
try {
int ln;
while ((ln = in.read(buffer)) != -1) {
out.write(buffer, 0, ln);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
static int copyDir(
File srcDir, File destDir) throws IOException {
return copyDir(srcDir, destDir, false);
}
/**
* @return the number of files copied.
*/
static int copyDir(
File srcDir, File destDir, boolean skipTopLevelXMLs)
throws IOException {
int fileCounter = 0;
destDir = destDir.getAbsoluteFile();
srcDir = srcDir.getAbsoluteFile();
if (!destDir.isDirectory()) {
if (destDir.exists()) {
throw new IOException("Can't create directory, because a "
+ "file with the same name already exists: "
+ destDir.getAbsolutePath());
}
if (!destDir.mkdir()) {
throw new IOException("Failed to create directory: "
+ destDir.getAbsolutePath());
}
}
File[] ls = srcDir.listFiles();
if (ls == null) {
throw new IOException("Failed to list directory: "
+ srcDir.getAbsolutePath());
}
for (File f : srcDir.listFiles()) {
String fName = f.getName();
if (isUsualIgnorableFileOrDirectory(fName) || isDocgenFile(fName)) {
continue;
}
File dest = new File(destDir, fName);
if (f.isFile()) {
if (!(skipTopLevelXMLs
&& fName.toLowerCase().endsWith(".xml"))) {
copyFile(f, dest);
fileCounter++;
}
} else if (f.isDirectory()) {
fileCounter += copyDir(f, dest);
} else {
throw new IOException(
"Failed decide if it's a file or a directory: "
+ f.getAbsolutePath());
}
}
return fileCounter;
}
private static void copyFile(File src, File dst) throws IOException {
byte[] buffer = new byte[COPY_BUFFER_SIZE];
InputStream in = new FileInputStream(src);
try {
long srcLMD = 0L;
srcLMD = src.lastModified();
if (srcLMD == 0) {
throw new IOException("Failed to get the last modification "
+ "time of " + src.getAbsolutePath());
}
OutputStream out = new FileOutputStream(dst);
try {
int ln;
while ((ln = in.read(buffer)) != -1) {
out.write(buffer, 0, ln);
}
} finally {
out.close();
}
if (srcLMD != 0L) {
if (!dst.setLastModified(srcLMD)) {
throw new IOException(
"Failed to set last-modification-date for: "
+ dst.getAbsolutePath());
}
}
} finally {
in.close();
}
}
static boolean isDocgenFile(String fName) {
fName = fName.toLowerCase();
return fName.startsWith("docgen-") || fName.startsWith("docgen.")
|| fName.equals("docgen");
}
static boolean isUsualIgnorableFileOrDirectory(String fName) {
fName = fName.toLowerCase();
int i = fName.lastIndexOf(".");
String fExt;
if (i == -1) {
fExt = "";
} else {
fExt = fName.substring(i + 1);
}
// CVS files:
if (fName.equals(".cvsignore")
|| fName.equals("cvs")
|| (fName.length() > 2 && fName.startsWith(".#"))) {
return true;
}
// SVN files:
if (fName.equals(".svn")) {
return true;
}
// Temporary/backup files:
if (
(
fExt.equals("bak")
|| fExt.equals("lock")
|| fExt.startsWith("~"))
|| (fName.length() > 2 && (
(fName.startsWith("#") && fName.endsWith("#"))
|| (fName.startsWith("%") && fName.endsWith("%"))
|| fName.startsWith("._")))
|| (fName.length() > 1 && (
fName.endsWith("~")
|| fName.startsWith("~")))
) {
return true;
}
return false;
}
public static String loadString(File f, Charset charset) throws IOException {
FileInputStream in = new FileInputStream(f);
try {
return loadString(in, charset);
} finally {
in.close();
}
}
public static String loadString(InputStream in, Charset charset)
throws IOException {
Reader r = new InputStreamReader(in, charset);
StringBuilder sb = new StringBuilder(256);
try {
char[] buf = new char[READ_BUFFER_SIZE];
int ln;
while ((ln = r.read(buf)) != -1) {
sb.append(buf, 0, ln);
}
} finally {
r.close();
}
return sb.toString();
}
}