View Javadoc

    1   package net.sourceforge.pmd.util;
    2
    3   import java.io.File;
    4   import java.io.FilenameFilter;
    5   import java.io.IOException;
    6   import java.util.ArrayList;
    7   import java.util.Collections;
    8   import java.util.Enumeration;
    9   import java.util.List;
    10  import java.util.regex.Matcher;
    11  import java.util.regex.Pattern;
    12  import java.util.zip.ZipEntry;
    13  import java.util.zip.ZipFile;
    14
    15  import net.sourceforge.pmd.util.datasource.DataSource;
    16  import net.sourceforge.pmd.util.datasource.FileDataSource;
    17  import net.sourceforge.pmd.util.datasource.ZipDataSource;
    18  import net.sourceforge.pmd.util.filter.AndFilter;
    19  import net.sourceforge.pmd.util.filter.Filter;
    20  import net.sourceforge.pmd.util.filter.Filters;
    21  import net.sourceforge.pmd.util.filter.OrFilter;
    22
    23  /**
    24   * This is a utility class for working with Files.
    25   */
    26  public final class FileUtil {
    27
    28      private FileUtil() {}
    29
    30      /**
    31       * Helper method to get a filename without its extension
    32       * @param fileName String
    33       * @return String
    34       */
    35      public static String getFileNameWithoutExtension(String fileName) {
    36          String name = fileName;
    37
    38          int index = fileName.lastIndexOf('.');
    39          if (index != -1) {
    40              name = fileName.substring(0, index);
    41          }
    42
    43          return name;
    44      }
    45
    46      /**
    47       * Collects a list of DataSources using a comma separated list of input file
    48       * locations to process.  If a file location is a directory, the directory
    49       * hierarchy will be traversed to look for files.  If a file location is a
    50       * ZIP or Jar the archive will be scanned looking for files.  If a file
    51       * location is a file, it will be used.  For each located file, a
    52       * FilenameFilter is used to decide whether to return a DataSource.
    53       *
    54       * @param fileLocations A comma-separated list of file locations.
    55       * @param filenameFilter  The FilenameFilter to apply to files.
    56       * @return A list of DataSources, one for each file collected.
    57       */
    58      public static List<DataSource> collectFiles(String fileLocations, FilenameFilter filenameFilter) {
    59  	List<DataSource> dataSources = new ArrayList<DataSource>();
    60  	for (String fileLocation : fileLocations.split(",")) {
    61  	    collect(dataSources, fileLocation, filenameFilter);
    62  	}
    63  	return dataSources;
    64      }
    65
    66      private static List<DataSource> collect(List<DataSource> dataSources, String fileLocation,
    67  	    FilenameFilter filenameFilter) {
    68  	File file = new File(fileLocation);
    69  	if (!file.exists()) {
    70  	    throw new RuntimeException("File " + file.getName() + " doesn't exist");
    71  	}
    72  	if (!file.isDirectory()) {
    73  	    if (fileLocation.endsWith(".zip") || fileLocation.endsWith(".jar")) {
    74  		ZipFile zipFile;
    75  		try {
    76  		    zipFile = new ZipFile(fileLocation);
    77  		    Enumeration<? extends ZipEntry> e = zipFile.entries();
    78  		    while (e.hasMoreElements()) {
    79  			ZipEntry zipEntry = e.nextElement();
    80  			if (filenameFilter.accept(null, zipEntry.getName())) {
    81  			    dataSources.add(new ZipDataSource(zipFile, zipEntry));
    82  			}
    83  		    }
    84  		} catch (IOException ze) {
    85  		    throw new RuntimeException("Archive file " + file.getName() + " can't be opened");
    86  		}
    87  	    } else {
    88  		dataSources.add(new FileDataSource(file));
    89  	    }
    90  	} else {
    91  	    // Match files, or directories which are not excluded.
    92  	    // FUTURE Make the excluded directories be some configurable option
    93  	    Filter<File> filter = new OrFilter<File>(Filters.toFileFilter(filenameFilter), new AndFilter<File>(Filters
    94  		    .getDirectoryFilter(), Filters.toNormalizedFileFilter(Filters.buildRegexFilterExcludeOverInclude(
    95  		    null, Collections.singletonList("SCCS")))));
    96  	    FileFinder finder = new FileFinder();
    97  	    List<File> files = finder.findFilesFrom(file.getAbsolutePath(), Filters.toFilenameFilter(filter), true);
    98  	    for (File f : files) {
    99  		dataSources.add(new FileDataSource(f));
    100 	    }
    101 	}
    102 	return dataSources;
    103     }
    104
    105     /**
    106      * Handy method to find a certain pattern into a file. While this method lives in the FileUtils, it was
    107      * designed with with unit test in mind (to check result redirected into a file)
    108      *
    109      * @param file
    110      * @param pattern
    111      * @return
    112      */
    113     public static boolean findPatternInFile( final File file, final String pattern ) {
    114
    115     	Pattern regexp = Pattern.compile(pattern);
    116     	Matcher matcher = regexp.matcher("");
    117
    118     	FileIterable it = new FileIterable(file);
    119     	for ( String line : it ){
    120     		matcher.reset( line ); //reset the input
    121     		if ( matcher.find() )
    122     			return true;
    123     	}
    124     	return false;
    125     }
    126 }