Skip to content

Commit

Permalink
Add an handy public method to search for a pattern in a file
Browse files Browse the repository at this point in the history
  • Loading branch information
rpelisse committed Aug 3, 2012
1 parent 30281b7 commit 42ba881
Showing 1 changed file with 126 additions and 102 deletions.
228 changes: 126 additions & 102 deletions pmd/src/main/java/net/sourceforge/pmd/util/FileUtil.java
Original file line number Diff line number Diff line change
@@ -1,102 +1,126 @@
package net.sourceforge.pmd.util;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import net.sourceforge.pmd.util.datasource.DataSource;
import net.sourceforge.pmd.util.datasource.FileDataSource;
import net.sourceforge.pmd.util.datasource.ZipDataSource;
import net.sourceforge.pmd.util.filter.AndFilter;
import net.sourceforge.pmd.util.filter.Filter;
import net.sourceforge.pmd.util.filter.Filters;
import net.sourceforge.pmd.util.filter.OrFilter;

/**
* This is a utility class for working with Files.
*/
public final class FileUtil {

private FileUtil() {}

/**
* Helper method to get a filename without its extension
* @param fileName String
* @return String
*/
public static String getFileNameWithoutExtension(String fileName) {
String name = fileName;

int index = fileName.lastIndexOf('.');
if (index != -1) {
name = fileName.substring(0, index);
}

return name;
}

/**
* Collects a list of DataSources using a comma separated list of input file
* locations to process. If a file location is a directory, the directory
* hierarchy will be traversed to look for files. If a file location is a
* ZIP or Jar the archive will be scanned looking for files. If a file
* location is a file, it will be used. For each located file, a
* FilenameFilter is used to decide whether to return a DataSource.
*
* @param fileLocations A comma-separated list of file locations.
* @param filenameFilter The FilenameFilter to apply to files.
* @return A list of DataSources, one for each file collected.
*/
public static List<DataSource> collectFiles(String fileLocations, FilenameFilter filenameFilter) {
List<DataSource> dataSources = new ArrayList<DataSource>();
for (String fileLocation : fileLocations.split(",")) {
collect(dataSources, fileLocation, filenameFilter);
}
return dataSources;
}

private static List<DataSource> collect(List<DataSource> dataSources, String fileLocation,
FilenameFilter filenameFilter) {
File file = new File(fileLocation);
if (!file.exists()) {
throw new RuntimeException("File " + file.getName() + " doesn't exist");
}
if (!file.isDirectory()) {
if (fileLocation.endsWith(".zip") || fileLocation.endsWith(".jar")) {
ZipFile zipFile;
try {
zipFile = new ZipFile(fileLocation);
Enumeration<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
ZipEntry zipEntry = e.nextElement();
if (filenameFilter.accept(null, zipEntry.getName())) {
dataSources.add(new ZipDataSource(zipFile, zipEntry));
}
}
} catch (IOException ze) {
throw new RuntimeException("Archive file " + file.getName() + " can't be opened");
}
} else {
dataSources.add(new FileDataSource(file));
}
} else {
// Match files, or directories which are not excluded.
// FUTURE Make the excluded directories be some configurable option
Filter<File> filter = new OrFilter<File>(Filters.toFileFilter(filenameFilter), new AndFilter<File>(Filters
.getDirectoryFilter(), Filters.toNormalizedFileFilter(Filters.buildRegexFilterExcludeOverInclude(
null, Collections.singletonList("SCCS")))));
FileFinder finder = new FileFinder();
List<File> files = finder.findFilesFrom(file.getAbsolutePath(), Filters.toFilenameFilter(filter), true);
for (File f : files) {
dataSources.add(new FileDataSource(f));
}
}
return dataSources;
}
}
package net.sourceforge.pmd.util;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import net.sourceforge.pmd.util.datasource.DataSource;
import net.sourceforge.pmd.util.datasource.FileDataSource;
import net.sourceforge.pmd.util.datasource.ZipDataSource;
import net.sourceforge.pmd.util.filter.AndFilter;
import net.sourceforge.pmd.util.filter.Filter;
import net.sourceforge.pmd.util.filter.Filters;
import net.sourceforge.pmd.util.filter.OrFilter;

/**
* This is a utility class for working with Files.
*/
public final class FileUtil {

private FileUtil() {}

/**
* Helper method to get a filename without its extension
* @param fileName String
* @return String
*/
public static String getFileNameWithoutExtension(String fileName) {
String name = fileName;

int index = fileName.lastIndexOf('.');
if (index != -1) {
name = fileName.substring(0, index);
}

return name;
}

/**
* Collects a list of DataSources using a comma separated list of input file
* locations to process. If a file location is a directory, the directory
* hierarchy will be traversed to look for files. If a file location is a
* ZIP or Jar the archive will be scanned looking for files. If a file
* location is a file, it will be used. For each located file, a
* FilenameFilter is used to decide whether to return a DataSource.
*
* @param fileLocations A comma-separated list of file locations.
* @param filenameFilter The FilenameFilter to apply to files.
* @return A list of DataSources, one for each file collected.
*/
public static List<DataSource> collectFiles(String fileLocations, FilenameFilter filenameFilter) {
List<DataSource> dataSources = new ArrayList<DataSource>();
for (String fileLocation : fileLocations.split(",")) {
collect(dataSources, fileLocation, filenameFilter);
}
return dataSources;
}

private static List<DataSource> collect(List<DataSource> dataSources, String fileLocation,
FilenameFilter filenameFilter) {
File file = new File(fileLocation);
if (!file.exists()) {
throw new RuntimeException("File " + file.getName() + " doesn't exist");
}
if (!file.isDirectory()) {
if (fileLocation.endsWith(".zip") || fileLocation.endsWith(".jar")) {
ZipFile zipFile;
try {
zipFile = new ZipFile(fileLocation);
Enumeration<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
ZipEntry zipEntry = e.nextElement();
if (filenameFilter.accept(null, zipEntry.getName())) {
dataSources.add(new ZipDataSource(zipFile, zipEntry));
}
}
} catch (IOException ze) {
throw new RuntimeException("Archive file " + file.getName() + " can't be opened");
}
} else {
dataSources.add(new FileDataSource(file));
}
} else {
// Match files, or directories which are not excluded.
// FUTURE Make the excluded directories be some configurable option
Filter<File> filter = new OrFilter<File>(Filters.toFileFilter(filenameFilter), new AndFilter<File>(Filters
.getDirectoryFilter(), Filters.toNormalizedFileFilter(Filters.buildRegexFilterExcludeOverInclude(
null, Collections.singletonList("SCCS")))));
FileFinder finder = new FileFinder();
List<File> files = finder.findFilesFrom(file.getAbsolutePath(), Filters.toFilenameFilter(filter), true);
for (File f : files) {
dataSources.add(new FileDataSource(f));
}
}
return dataSources;
}

/**
* Handy method to find a certain pattern into a file. While this method lives in the FileUtils, it was
* designed with with unit test in mind (to check result redirected into a file)
*
* @param file
* @param pattern
* @return
*/
public static boolean findPatternInFile( final File file, final String pattern ) {

Pattern regexp = Pattern.compile(pattern);
Matcher matcher = regexp.matcher("");

FileIterable it = new FileIterable(file);
for ( String line : it ){
matcher.reset( line ); //reset the input
if ( matcher.find() )
return true;
}
return false;
}
}

0 comments on commit 42ba881

Please sign in to comment.