package org.sf.mustru.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Properties;
import org.apache.log4j.Logger;
/**
* Tools to scan filesystem directories
*
*/
public class DirTools
{
private RandomAccessFile tfile;
protected Properties p = null;
static Logger logger = Logger.getLogger(DirTools.class.getName() );
public DirTools() { }
public ArrayList dirScan( String dir, String filterFile, boolean skipHidden)
{ return dirScan (dir, filterFile, null, skipHidden, false); }
public ArrayList dirScan( String dir, boolean skipHidden )
{ return dirScan (dir, null, null, skipHidden, false); }
/**
* Accept the directory to scan, the name of filter properties file and the
* task file to save the names of matching files.
*
* @param dir Directory to scan
* @param filterFile Name of the filter properties file
* @param taskFile Name of the output task file that will be appended
* @param skipHidden Boolean flag to scan hidden directories
* @return ArrayList of file names
*
*/
public ArrayList dirScan( String dir, String filterFile, String taskFile,
boolean skipHidden, boolean followLinks )
{
ArrayList flist = new ArrayList();
try
{
// *-- load the filters properties file
if (filterFile != null)
{ logger.info("Loading the filters file");
p = new Properties();
FileInputStream is = new FileInputStream(new File(filterFile));
p.load(is);
}
// *-- open the task file for appending file names
if (taskFile != null)
{ tfile = new RandomAccessFile(taskFile, "rw");
tfile.seek(tfile.length());
}
// *-- recursively scan the directory
flist = filescan(dir, skipHidden, followLinks);
if (taskFile != null) tfile.close();
}
catch (FileNotFoundException e)
{ logger.error("Could not find filter file" + filterFile); return(flist); }
catch (IOException e)
{ logger.error("Could not load filter file" + filterFile); return(flist); }
return (flist);
}
protected void setProperties() { p = new Properties(); }
protected Properties getProperties() { return(p); }
/**
* Scan the directory and write (append) matching files to the task file.
* Call recursively for sub-directories.
*
* @param dir Name of the directory
* @param skipHidden directories flag
*/
protected ArrayList filescan(String dir, boolean skipHidden, boolean followLinks)
{
ArrayList<String> flist = new ArrayList<String>();
//*-- verify that the directory exists
File d = new File(dir);
if (!d.canRead() || !d.isDirectory()) return(flist);
//*-- skip hidden directories
//if (skipHidden && d.isHidden()) { return(flist); }
if (skipHidden && d.getName().startsWith(".") ) return (flist);
// *-- get the list of files that have handlers
String[] files = d.list(new OnlyFilterable(this)); String fname = "";
try
{
//*-- use the slash separator consistently across Windows and Linux
String prefix = (dir.endsWith("/") ) ? dir: dir + "/";
// *-- recursively scan the directory
for (int i = 0; i < files.length; i++)
{
fname = prefix + files[i];
File mdir = new File(fname);
// *-- optionally skip symbolic links
File mdir_full = mdir.getCanonicalFile();
if (!followLinks && !mdir_full.equals(mdir)) { continue; }
if (mdir.isDirectory())
{ filescan(fname, skipHidden, followLinks); continue; }
// *-- append the file name
if (tfile != null)
{ tfile.writeBytes(fname + System.getProperty("line.separator")); }
flist.add(fname);
}
}
catch (NullPointerException e) { logger.error("Problem with file " + fname); }
catch (IOException e) { logger.error("Could not print to taskfile"); }
return(flist);
} // *-- end of filescan
} //*-- end of DirTools
/**
* Implement the FileFilter class and only return files that can be filtered
*/
class OnlyFilterable implements FilenameFilter
{
public DirTools dirTools;
public OnlyFilterable(DirTools d) { dirTools = d; }
/**
* Return a boolean depending on whether the file can converted to plain text or not.
* @param dir The name of the directory
* @param fname The name of the file
* @return boolean A true or false indicating if the file has a valid extension and can be handled.
*/
public boolean accept(File dir, String fname)
{
//*-- check if it is a directory and return true
File f = new File("" + dir + File.separator + fname);
if (f.isDirectory()) { return true; }
//*-- All files accepted, if no properties file
Properties p = dirTools.getProperties();
if (p == null) return true;
//*-- extract the extension and check if it is valid
String extension = StringTools.getSuffix(fname);
if ( (extension == null) || (extension.length() == 0) ) { return false; }
// *-- Check if there is a handler for the extension
String handler = p.getProperty(extension);
if ((handler == null) || (handler.equals(""))) { return false; }
return true;
}
} // *-- end of OnlyFilterable