1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.config.exclusion;
20
21 import java.io.File;
22 import java.io.FileFilter;
23 import java.io.FileNotFoundException;
24 import java.io.FileReader;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Objects;
31 import java.util.function.Predicate;
32
33 import org.apache.commons.io.IOUtils;
34 import org.apache.commons.io.LineIterator;
35 import org.apache.commons.lang3.StringUtils;
36 import org.apache.rat.ConfigurationException;
37 import org.apache.rat.api.EnvVar;
38 import org.apache.rat.config.exclusion.plexus.MatchPattern;
39 import org.apache.rat.config.exclusion.plexus.SelectorUtils;
40 import org.apache.rat.document.DocumentName;
41 import org.apache.rat.document.DocumentNameMatcher;
42 import org.apache.rat.utils.ExtendedIterator;
43
44 import static java.lang.String.format;
45
46
47
48
49 public final class ExclusionUtils {
50
51
52 public static final List<String> COMMENT_PREFIXES = Arrays.asList("#", "##", "//", "/**", "/*");
53
54
55 public static final String NEGATION_PREFIX = "!";
56
57
58 public static final Predicate<String> NOT_MATCH_FILTER = s -> s.startsWith(NEGATION_PREFIX);
59
60
61 public static final Predicate<String> MATCH_FILTER = NOT_MATCH_FILTER.negate();
62
63 private ExclusionUtils() {
64
65 }
66
67
68
69
70
71
72
73
74 public static Predicate<String> commentFilter(final Iterable<String> commentPrefixes) {
75 return s -> {
76 if (StringUtils.isNotBlank(s)) {
77 int i = 1;
78 while (StringUtils.isBlank(s.substring(0, i))) {
79 i++;
80 }
81 String trimmed = i > 0 ? s.substring(i - 1) : s;
82 for (String prefix : commentPrefixes) {
83 if (trimmed.startsWith(prefix)) {
84 return false;
85 }
86 }
87 return true;
88 }
89 return false;
90 };
91 }
92
93
94
95
96
97
98
99
100 public static Predicate<String> commentFilter(final String commentPrefix) {
101 return s -> {
102 if (StringUtils.isNotBlank(s)) {
103 int i = 1;
104 while (StringUtils.isBlank(s.substring(0, i))) {
105 i++;
106 }
107 String trimmed = i > 0 ? s.substring(i - 1) : s;
108 return !trimmed.startsWith(commentPrefix);
109 }
110 return false;
111 };
112 }
113
114
115
116
117
118
119
120 public static FileFilter asFileFilter(final DocumentName parent, final DocumentNameMatcher nameMatcher) {
121 return file -> {
122 DocumentName candidate = DocumentName.builder(file).setBaseName(parent.getBaseName()).build();
123 return EnvVar.RAT_DECOMPOSE_MATCHER_ON_USE.isSet() ? nameMatcher.logDecompositionWhileMatching(candidate) :
124 nameMatcher.matches(candidate);
125 };
126 }
127
128
129
130
131
132
133
134
135 public static ExtendedIterator<String> asIterator(final File patternFile, final Predicate<String> commentFilters) {
136 verifyFile(patternFile);
137 Objects.requireNonNull(commentFilters, "commentFilters");
138 try {
139 return ExtendedIterator.create(IOUtils.lineIterator(new FileReader(patternFile))).filter(commentFilters);
140 } catch (FileNotFoundException e) {
141 throw new ConfigurationException(format("%s is not a valid file.", patternFile));
142 }
143 }
144
145
146
147
148
149
150
151
152 public static Iterable<String> asIterable(final File patternFile, final String commentPrefix) {
153 return asIterable(patternFile, commentFilter(commentPrefix));
154 }
155
156
157
158
159
160
161
162
163 public static Iterable<String> asIterable(final File patternFile, final Predicate<String> commentFilters) {
164 verifyFile(patternFile);
165 Objects.requireNonNull(commentFilters, "commentFilters");
166
167
168 try (FileReader reader = new FileReader(patternFile)) {
169 List<String> result = new ArrayList<>();
170 Iterator<String> iter = new LineIterator(reader) {
171 @Override
172 protected boolean isValidLine(final String line) {
173 return commentFilters.test(line);
174 }
175 };
176 iter.forEachRemaining(result::add);
177 return result;
178 } catch (IOException e) {
179 throw new ConfigurationException("Unable to read file " + patternFile, e);
180 }
181 }
182
183
184
185
186
187
188 public static boolean isHidden(final String fileName) {
189 return fileName.startsWith(".") && !(fileName.equals(".") || fileName.equals(".."));
190 }
191
192 private static void verifyFile(final File file) {
193 if (file == null || !file.exists() || !file.isFile()) {
194 throw new ConfigurationException(format("%s is not a valid file.", file));
195 }
196 }
197
198
199
200
201
202
203
204
205 public static String qualifyPattern(final DocumentName documentName, final String pattern) {
206 boolean prefix = pattern.startsWith(NEGATION_PREFIX);
207 String workingPattern = prefix ? pattern.substring(1) : pattern;
208 String normalizedPattern = SelectorUtils.extractPattern(workingPattern, documentName.getDirectorySeparator());
209
210 StringBuilder sb = new StringBuilder(prefix ? NEGATION_PREFIX : "");
211 if (SelectorUtils.isRegexPrefixedPattern(workingPattern)) {
212 sb.append(SelectorUtils.REGEX_HANDLER_PREFIX)
213 .append("\\Q").append(documentName.getBaseName())
214 .append(documentName.getDirectorySeparator())
215 .append("\\E").append(normalizedPattern)
216 .append(SelectorUtils.PATTERN_HANDLER_SUFFIX);
217 } else {
218 sb.append(documentName.getBaseDocumentName().resolve(normalizedPattern).getName());
219 }
220 return sb.toString();
221 }
222
223
224
225
226
227
228
229
230 public static String convertSeparator(final String source, final String from, final String to) {
231 if (StringUtils.isEmpty(source) || from.equals(to)) {
232 return source;
233 }
234 return String.join(to, source.split("\\Q" + from + "\\E"));
235 }
236 }