package com.evanhoffman.fileorganizer;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;
/**
* Moves a bunch of files from their current locations to an arbitrary
* target directory.
* @author Evan Hoffman
* @since 2007-03-28
*/
public abstract class FileOrganizer {
protected static Logger logger = Logger.getLogger("something");
private File sourceDir = null;
private boolean recurseSubdirs = true;
private List workFiles = null;
public FileOrganizer(File sourceDir, boolean recurse) {
this.sourceDir = sourceDir;
this.recurseSubdirs = recurse;
}
/**
* Does stuff.
*
*/
public void run() {
workFiles = getFileList(sourceDir);
moveFiles(workFiles);
}
/**
* Builds a list of files that match the criteria specified in {@link #accept(File)},
* recursing into subdirectories {@link #recurseSubdirs} is set to true.
* @param dir The starting directory.
* @return
*/
protected List getFileList(File dir) {
List list = new LinkedList();
File dirList[] = dir.listFiles();
for (File f : dirList) {
if (f.isDirectory()) {
if (recurseSubdirs) {
logger.info("Recursing into subdirectory "+f);
list.addAll(getFileList(f));
}
} else {
if (accept(f)) {
list.add(f);
logger.info("Added file "+f);
}
}
}
return list;
}
/**
* Moves the files from their current location to the target locations
* returned by {@link #getTargetDirForFile(File)}.
* @param files
*/
protected void moveFiles(Iterable files) {
for (File f : files) {
File targetDir = getTargetDirForFile(f);
if (targetDir != null) {
if (targetDir.exists()) {
if (!targetDir.isDirectory()){
throw new RuntimeException("'"+f+"' exists but is not a directory");
}
} else {
if (!targetDir.mkdirs()) {
throw new RuntimeException("Unable to create directory: "+f);
}
}
File targetFile = new File(targetDir,f.getName());
if (targetFile.exists()) {
logger.info("Attempting to move "+f+" to "+targetFile+", but target already exists!");
} else {
if (!f.renameTo(targetFile)) {
throw new RuntimeException("Unable to move "+f+" to "+targetFile);
}
}
} else {
logger.info("Null directory returned for file "+f);
}
}
}
/**
* Returns the directory to which the specified file should be moved, or null
* if the file should not be moved.
* @param f The file to be evaluated.
* @return
*/
protected abstract File getTargetDirForFile(File f);
/**
* Returns true if the specified file is a candidate to be moved,
* false if it should be ignored.
* @param f The file to be evaluated.
* @return
*/
protected abstract boolean accept(File f);
}