blob: 7be6425f04b375ba8698704bab1af4f4a8f8cf7d [file]
package tools;
import java.io.*;
import java.util.*;
import java.util.regex.*;
/**
* Simple helper class that can be used to modify bunch of files (recursively)
* by matching start and end regexps, and replacing content between
* first instance of such a pair.
*/
public final class FileMunger
{
final static int MAX_REGEX_LEN = 500;
String _encoding = "UTF-8";
int _filesChecked;
int _filesModified;
private FileMunger() { }
public boolean munge(String[] args)
throws Exception
{
_filesChecked = _filesModified = 0;
if (args.length != 4) {
System.err.println("Usage: java "+getClass()+" [input-dir] [start-marker-re-file] [end-marker-re-file] [inject-file]");
return false;
}
File dir = new File(args[0]);
if (!dir.isDirectory()) {
System.err.println("Argument #1 not a directory");
return false;
}
File[] files = new File[3];
for (int i = 0; i < 3; ++i) {
String fstr = args[1+i];
File f = new File(fstr);
files[i] = f;
if (!f.isFile()) {
System.err.println("Argument '"+fstr+"' is not a file");
return false;
}
}
Pattern startRE = getRegex(files[0]);
Pattern endRE = getRegex(files[1]);
String content = readFile(files[2]);
mungeDir(dir, startRE, endRE, content);
System.out.println("Complete: files checked: "+_filesChecked+"; modified: "+_filesModified);
return true;
}
private void mungeDir(File dir, Pattern startRE, Pattern endRE, String inclContent)
throws IOException
{
System.out.println("Checking directory '"+dir.getName()+"': ");
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
mungeDir(file, startRE, endRE, inclContent);
continue;
}
++_filesChecked;
mungeFile(file, startRE, endRE, inclContent);
}
System.out.println("Finished directory '"+dir.getName()+"': ");
}
private void mungeFile(File file, Pattern startRE, Pattern endRE, String inclContent)
throws IOException
{
System.out.print("Checking file '"+file.getName()+"': ");
String origContent = readFile(file);
Matcher m = startRE.matcher(origContent);
if (m.find()) {
int startStart = m.start();
int startEnd = m.end();
Matcher m2 = endRE.matcher(origContent);
if (m2.find(startEnd)) {
++_filesModified;
int endStart = m2.start();
int endEnd = m2.end();
// Good: let's replace!
Writer w = new OutputStreamWriter(new FileOutputStream(file), _encoding);
w.write(origContent, 0, startEnd);
w.write(inclContent);
w.write(origContent.substring(endStart));
w.close();
System.out.println("MATCH: replaced content");
return;
}
System.out.println("WARN: start matched, end not");
return;
}
System.out.println("(no match)");
}
private Pattern getRegex(File input)
throws IOException
{
String reStr = readFile(input);
// Let's allow comments in there tho:
BufferedReader br = new BufferedReader(new StringReader(reStr));
StringBuilder sb = new StringBuilder(reStr.length());
String line;
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.length() == 0 || line.startsWith("#")) {
continue;
}
sb.append(line);
}
reStr = sb.toString();
// for now, let's havity sanity check limit...
if (reStr.length() > MAX_REGEX_LEN) {
throw new IllegalArgumentException("File '"+input+"' contains regexp that is too long (max "+MAX_REGEX_LEN+"; got "+reStr.length()+")");
}
System.err.println("RegExp from "+input+": '"+reStr+"'");
try {
return Pattern.compile(reStr);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Failed to parse regex from file '"+input+"': "+iae.getMessage());
}
}
private String readFile(File input)
throws IOException
{
Reader r = new InputStreamReader(new FileInputStream(input), _encoding);
int len = (int) input.length();
char[] buf = new char[Math.min(len, 2000)];
StringBuilder sb = new StringBuilder(len);
int count;
while ((count = r.read(buf)) > 0) {
sb.append(buf, 0, count);
}
r.close();
return sb.toString();
}
public static void main(String[] args)
throws Exception
{
if (!new FileMunger().munge(args)) {
System.exit(1);
}
}
}