1 package org.codehaus.mojo.jaxb2.shared.filters.pattern; 2 3 import org.apache.maven.plugin.logging.Log; 4 import org.codehaus.mojo.jaxb2.shared.FileSystemUtilities; 5 import org.codehaus.mojo.jaxb2.shared.Validate; 6 import org.codehaus.mojo.jaxb2.shared.filters.Filter; 7 import org.codehaus.mojo.jaxb2.shared.filters.Filters; 8 9 import java.io.File; 10 import java.io.FileFilter; 11 import java.util.ArrayList; 12 import java.util.Arrays; 13 import java.util.List; 14 import java.util.regex.Pattern; 15 16 /** 17 * <p>AbstractPatternFilter and FileFilter combination, using a set of Regular expressions 18 * to accept the canonical absolute paths to Files.</p> 19 * 20 * @author <a href="mailto:lj@jguru.se">Lennart Jörelid</a>, jGuru Europe AB 21 * @since 2.0 22 */ 23 public class PatternFileFilter extends AbstractPatternFilter<File> implements FileFilter { 24 25 /** 26 * Java RegExp pattern matching one or more letters/digits/punctuation characters. 27 * It can be flexibly used to separate normative text in a pattern: 28 * <ol> 29 * <li>Pattern matching <strong>ends of strings</strong>. <code>PATTERN_LETTER_DIGIT_PUNCT + "txt"</code> 30 * matches all file paths ending in "txt", such as "some/foobar.txt"</li> 31 * <li>Pattern matching <strong>strings containing patterns</strong>. <code>PATTERN_LETTER_DIGIT_PUNCT + 32 * "foobar" + PATTERN_LETTER_DIGIT_PUNCT</code> matches all file paths containing "foobar" such as 33 * "the/file/in/directory/foobar/blah.java"</li> 34 * <li>Pattern matching <strong>start of strings</strong>. <code>"/some/prefix" 35 * + PATTERN_LETTER_DIGIT_PUNCT</code> matches all file paths starting in "/some/prefix", such as 36 * "some/prefix/another/specification.xsd"</li> 37 * </ol> 38 */ 39 public static final String PATTERN_LETTER_DIGIT_PUNCT = "(\\p{javaLetterOrDigit}|\\p{Punct})+"; 40 41 /** 42 * Converter returning the canonical and absolute path for a File. 43 */ 44 public static final StringConverter<File> FILE_PATH_CONVERTER = new StringConverter<File>() { 45 @Override 46 public String convert(final File toConvert) { 47 return FileSystemUtilities.getCanonicalPath(toConvert.getAbsoluteFile()); 48 } 49 }; 50 51 /** 52 * Compound constructor creating an PatternFileFilter from the supplied parameters. 53 * 54 * @param processNullValues if {@code true}, this PatternFileFilter process null candidate values. 55 * @param patternPrefix a prefix to be prepended to any patterns submitted to 56 * this PatternFileFilter 57 * @param patterns The non-null list of Patters which should be applied within this 58 * PatternFileFilter. 59 * @param converter The StringConverter which converts Files to Strings for Pattern matching. 60 * @param acceptCandidateOnPatternMatch if {@code true}, this PatternFileFilter will matchAtLeastOnce 61 * candidate objects that match at least one of the supplied patterns. 62 * if {@code false}, this PatternFileFilter will noFilterMatches 63 * candidates that match at least one of the supplied patterns. 64 */ 65 public PatternFileFilter(final boolean processNullValues, 66 final String patternPrefix, 67 final List<String> patterns, 68 final StringConverter<File> converter, 69 final boolean acceptCandidateOnPatternMatch) { 70 super(); 71 72 // Assign internal state 73 setProcessNullValues(processNullValues); 74 setAcceptCandidateOnPatternMatch(acceptCandidateOnPatternMatch); 75 setPatternPrefix(patternPrefix); 76 setPatterns(patterns); 77 setConverter(converter); 78 } 79 80 /** 81 * Creates a new PatternFileFilter using the supplied patternStrings which are interpreted as file suffixes. 82 * (I.e. prepended with {@code PATTERN_LETTER_DIGIT_PUNCT} and compiled to Patterns). 83 * The {@code FILE_PATH_CONVERTER} is used to convert Files to strings. 84 * The supplied {@code acceptCandidateOnPatternMatch} parameter indicates if this 85 * PatternFileFilter accepts or rejects candidates that match any of the supplied patternStrings. 86 * 87 * @param patternStrings The list of patternStrings to be used as file path suffixes. 88 * @param acceptCandidateOnPatternMatch if {@code true}, this PatternFileFilter will matchAtLeastOnce 89 * candidate objects that match at least one of the supplied patterns. 90 * if {@code false}, this PatternFileFilter will noFilterMatches 91 * candidates that match at least one of the supplied patterns. 92 * @see #FILE_PATH_CONVERTER 93 * @see #PATTERN_LETTER_DIGIT_PUNCT 94 * @see #convert(java.util.List, String) 95 */ 96 public PatternFileFilter(final List<String> patternStrings, final boolean acceptCandidateOnPatternMatch) { 97 this(false, PATTERN_LETTER_DIGIT_PUNCT, patternStrings, FILE_PATH_CONVERTER, acceptCandidateOnPatternMatch); 98 } 99 100 /** 101 * Creates a new PatternFileFilter using the supplied patternStrings which are interpreted as file suffixes. 102 * (I.e. prepended with {@code PATTERN_LETTER_DIGIT_PUNCT} and compiled to Patterns). 103 * The {@code FILE_PATH_CONVERTER} is used to convert Files to strings. 104 * The retrieved PatternFileFilter accepts candidates that match any of the supplied patternStrings. 105 * 106 * @param patterns The list of patternStrings to be used as file path suffixes. 107 */ 108 public PatternFileFilter(final List<String> patterns) { 109 this(false, PATTERN_LETTER_DIGIT_PUNCT, patterns, FILE_PATH_CONVERTER, true); 110 } 111 112 /** 113 * <p>Creates a new PatternFileFilter with no patternStrings List, implying that calling this constructor must be 114 * followed by a call to the {@code #setPatterns} method.</p> 115 * <p>The default prefix is {@code PATTERN_LETTER_DIGIT_PUNCT}, the default StringConverter is 116 * {@code FILE_PATH_CONVERTER} and this PatternFileFilter does by default accept candidates that match any of 117 * the supplied PatternStrings (i.e. an include-mode filter)</p> 118 */ 119 public PatternFileFilter() { 120 this(false, PATTERN_LETTER_DIGIT_PUNCT, new ArrayList<String>(), FILE_PATH_CONVERTER, true); 121 } 122 123 /** 124 * Creates a new List containing an exclude-mode PatternFileFilter using the supplied patternStrings which 125 * are interpreted as file suffixes. (I.e. prepended with {@code PATTERN_LETTER_DIGIT_PUNCT} and compiled to 126 * Patterns). The {@code FILE_PATH_CONVERTER} is used to convert Files to strings. 127 * 128 * @param patterns A List of suffix patterns to be used in creating a new ExclusionRegularExpressionFileFilter. 129 * @param log The active Maven Log. 130 * @return A List containing a PatternFileFilter using the supplied suffix patterns to match Files. 131 * @see PatternFileFilter 132 */ 133 public static List<Filter<File>> createExcludeFilterList(final Log log, 134 final String... patterns) { 135 return createFilterList(log, false, patterns); 136 } 137 138 /** 139 * Creates a new List containing an include-mode PatternFileFilter using the supplied patternStrings which 140 * are interpreted as file suffixes. (I.e. prepended with {@code PATTERN_LETTER_DIGIT_PUNCT} and compiled to 141 * Patterns). The {@code FILE_PATH_CONVERTER} is used to convert Files to strings. 142 * 143 * @param patterns A List of suffix patterns to be used in creating a new ExclusionRegularExpressionFileFilter. 144 * @param log The active Maven Log. 145 * @return A List containing a PatternFileFilter using the supplied suffix patterns to match Files. 146 * @see PatternFileFilter 147 */ 148 public static List<Filter<File>> createIncludeFilterList(final Log log, 149 final String... patterns) { 150 return createFilterList(log, true, patterns); 151 } 152 153 // 154 // Private helpers 155 // 156 157 private static List<Filter<File>> createFilterList(final Log log, 158 final boolean includeOperation, 159 final String... patterns) { 160 161 // Check sanity 162 Validate.notNull(patterns, "patterns"); 163 Validate.notNull(log, "log"); 164 165 // Convert and return. 166 final List<Filter<File>> toReturn = new ArrayList<Filter<File>>(); 167 final List<String> patternStrings = Arrays.asList(patterns); 168 toReturn.add(new PatternFileFilter(patternStrings, includeOperation)); 169 170 // Initialize the filters. 171 Filters.initialize(log, toReturn); 172 return toReturn; 173 } 174 }