View Javadoc

    1   package net.sourceforge.pmd.util.filter;
    2
    3   import java.io.File;
    4   import java.io.FilenameFilter;
    5   import java.util.ArrayList;
    6   import java.util.Collection;
    7   import java.util.List;
    8
    9   /**
    10   * Utility class for working with Filters.  Contains builder style methods,
    11   * apply methods, as well as mechanisms for adapting Filters and FilenameFilters.
    12   */
    13  public class Filters {
    14
    15  	/**
    16  	 * Filter a given Collection.
    17  	 * @param <T> Type of the Collection.
    18  	 * @param filter A Filter upon the Type of objects in the Collection.
    19  	 * @param collection The Collection to filter.
    20  	 * @return A List containing only those objects for which the Filter returned <code>true</code>.
    21  	 */
    22  	public static <T> List<T> filter(Filter<T> filter, Collection<T> collection) {
    23  		List<T> list = new ArrayList<T>();
    24  		for (T obj : collection) {
    25  			if (filter.filter(obj)) {
    26  				list.add(obj);
    27  			}
    28  		}
    29  		return list;
    30  	}
    31
    32  	/**
    33  	 * Get a File Filter for files with the given extensions, ignoring case.
    34  	 * @param extensions The extensions to filter.
    35  	 * @return A File Filter.
    36  	 */
    37  	public static Filter<File> getFileExtensionFilter(String... extensions) {
    38  		return new FileExtensionFilter(extensions);
    39  	}
    40
    41  	/**
    42  	 * Get a File Filter for directories.
    43  	 * @return A File Filter.
    44  	 */
    45  	public static Filter<File> getDirectoryFilter() {
    46  		return DirectoryFilter.INSTANCE;
    47  	}
    48
    49  	/**
    50  	 * Get a File Filter for directories or for files with the given extensions, ignoring case.
    51  	 * @param extensions The extensions to filter.
    52  	 * @return A File Filter.
    53  	 */
    54  	public static Filter<File> getFileExtensionOrDirectoryFilter(String... extensions) {
    55  		return new OrFilter<File>(getFileExtensionFilter(extensions), getDirectoryFilter());
    56  	}
    57
    58  	/**
    59  	 * Given a String Filter, expose as a File Filter.  The File paths are
    60  	 * normalized to a standard pattern using <code>/</code> as a path separator
    61  	 * which can be used cross platform easily in a regular expression based
    62  	 * String Filter.
    63  	 *
    64  	 * @param filter A String Filter.
    65  	 * @return A File Filter.
    66  	 */
    67  	public static Filter<File> toNormalizedFileFilter(final Filter<String> filter) {
    68  		return new Filter<File>() {
    69  			public boolean filter(File file) {
    70  				String path = file.getPath();
    71  				path = path.replace('\\', '/');
    72  				return filter.filter(path);
    73  			}
    74
    75  			public String toString() {
    76  				return filter.toString();
    77  			}
    78  		};
    79  	}
    80
    81  	/**
    82  	 * Given a String Filter, expose as a Filter on another type.  The
    83  	 * <code>toString()</code> method is called on the objects of the other
    84  	 * type and delegated to the String Filter.
    85  	 * @param <T> The desired type.
    86  	 * @param filter The existing String Filter.
    87  	 * @return A Filter on the desired type.
    88  	 */
    89  	public static <T> Filter<T> fromStringFilter(final Filter<String> filter) {
    90  		return new Filter<T>() {
    91  			public boolean filter(T obj) {
    92  				return filter.filter(obj.toString());
    93  			}
    94
    95  			public String toString() {
    96  				return filter.toString();
    97  			}
    98  		};
    99  	}
    100
    101 	/**
    102 	 * Given a File Filter, expose as a FilenameFilter.
    103 	 * @param filter The File Filter.
    104 	 * @return A FilenameFilter.
    105 	 */
    106 	public static FilenameFilter toFilenameFilter(final Filter<File> filter) {
    107 		return new FilenameFilter() {
    108 			public boolean accept(File dir, String name) {
    109 				return filter.filter(new File(dir, name));
    110 			}
    111
    112 			public String toString() {
    113 				return filter.toString();
    114 			}
    115 		};
    116 	}
    117
    118 	/**
    119 	 * Given a FilenameFilter, expose as a File Filter.
    120 	 * @param filter The FilenameFilter.
    121 	 * @return A File Filter.
    122 	 */
    123 	public static Filter<File> toFileFilter(final FilenameFilter filter) {
    124 		return new Filter<File>() {
    125 			public boolean filter(File file) {
    126 				return filter.accept(file.getParentFile(), file.getName());
    127 			}
    128
    129 			public String toString() {
    130 				return filter.toString();
    131 			}
    132 		};
    133 	}
    134
    135 	/**
    136 	 * Construct a String Filter using set of include and exclude regular
    137 	 * expressions.  If there are no include regular expressions provide, then
    138 	 * a regular expression is added which matches every String by default.
    139 	 * A String is included as long as it matches an include regular expression
    140 	 * and does not match an exclude regular expression.
    141 	 * <p>
    142 	 * In other words, exclude patterns override include patterns.
    143 	 *
    144 	 * @param includeRegexes The include regular expressions.  May be <code>null</code>.
    145 	 * @param excludeRegexes The exclude regular expressions.  May be <code>null</code>.
    146 	 * @return A String Filter.
    147 	 */
    148 	public static Filter<String> buildRegexFilterExcludeOverInclude(List<String> includeRegexes,
    149 			List<String> excludeRegexes) {
    150 		OrFilter<String> includeFilter = new OrFilter<String>();
    151 		if (includeRegexes == null || includeRegexes.isEmpty()) {
    152 			includeFilter.addFilter(new RegexStringFilter(".*"));
    153 		} else {
    154 			for (String includeRegex : includeRegexes) {
    155 				includeFilter.addFilter(new RegexStringFilter(includeRegex));
    156 			}
    157 		}
    158
    159 		OrFilter<String> excludeFilter = new OrFilter<String>();
    160 		if (excludeRegexes != null) {
    161 			for (String excludeRegex : excludeRegexes) {
    162 				excludeFilter.addFilter(new RegexStringFilter(excludeRegex));
    163 			}
    164 		}
    165
    166 		return new AndFilter<String>(includeFilter, new NotFilter<String>(excludeFilter));
    167 	}
    168
    169 	/**
    170 	 * Construct a String Filter using set of include and exclude regular
    171 	 * expressions.  If there are no include regular expressions provide, then
    172 	 * a regular expression is added which matches every String by default.
    173 	 * A String is included as long as the case that there is an include which
    174 	 * matches or there is not an exclude which matches.
    175 	 * <p>
    176 	 * In other words, include patterns override exclude patterns.
    177 	 *
    178 	 * @param includeRegexes The include regular expressions.  May be <code>null</code>.
    179 	 * @param excludeRegexes The exclude regular expressions.  May be <code>null</code>.
    180 	 * @return A String Filter.
    181 	 */
    182 	public static Filter<String> buildRegexFilterIncludeOverExclude(List<String> includeRegexes,
    183 			List<String> excludeRegexes) {
    184 		OrFilter<String> includeFilter = new OrFilter<String>();
    185 		if (includeRegexes != null) {
    186 			for (String includeRegex : includeRegexes) {
    187 				includeFilter.addFilter(new RegexStringFilter(includeRegex));
    188 			}
    189 		}
    190
    191 		OrFilter<String> excludeFilter = new OrFilter<String>();
    192 		if (excludeRegexes != null) {
    193 			for (String excludeRegex : excludeRegexes) {
    194 				excludeFilter.addFilter(new RegexStringFilter(excludeRegex));
    195 			}
    196 		}
    197
    198 		return new OrFilter<String>(includeFilter, new NotFilter<String>(excludeFilter));
    199 	}
    200 }