View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.rat.config.exclusion;
20  
21  import java.io.File;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.Collections;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Set;
29  import java.util.function.Predicate;
30  
31  import org.apache.rat.config.exclusion.fileProcessors.AbstractFileProcessorBuilder;
32  import org.apache.rat.config.exclusion.fileProcessors.BazaarIgnoreBuilder;
33  import org.apache.rat.config.exclusion.fileProcessors.CVSIgnoreBuilder;
34  import org.apache.rat.config.exclusion.fileProcessors.GitIgnoreBuilder;
35  import org.apache.rat.config.exclusion.fileProcessors.HgIgnoreBuilder;
36  import org.apache.rat.document.DocumentName;
37  import org.apache.rat.document.DocumentNameMatcher;
38  import org.apache.rat.utils.ExtendedIterator;
39  
40  /**
41   * Collection of standard excludes.
42   * HINT: In order to work recursively each entry is prefixed with {@code "**\/"}.
43   */
44  public enum StandardCollection {
45      /**
46       * All the standard excludes combined.
47       */
48      // see getCollections() for loading
49      ALL("All of the Standard Excludes combined.", null, null, null),
50      /**
51       * The files and directories created by an ARCH source code control based tool.
52       */
53      ARCH("The files and directories created by an ARCH source code control based tool.",
54              Collections.singletonList("**/.arch-ids/**"), null, null),
55      /**
56       * The files and directories created by a Bazaar source code control based tool.
57       */
58      BAZAAR("The files and directories created by a Bazaar source code control based tool.",
59              Arrays.asList("**/.bzr/**", "**/.bzrignore"), null, new BazaarIgnoreBuilder()),
60      /**
61       * The files and directories created by a Bitkeeper source code control based tool.
62       */
63      BITKEEPER("The files and directories created by a Bitkeeper source code control based tool.",
64              Arrays.asList("**/BitKeeper/**", "**/ChangeSet/**"), null, null),
65      /**
66       * The files and directories created by a CVS source code control based tool.
67       * @see <a href="https://www.gnu.org/software/trans-coord/manual/cvs/html_node/cvsignore.html#cvsignore">Ignoring files via cvsignore</a>
68       */
69      CVS("The files and directories created by a CVS source code control based tool.",
70              Arrays.asList("**/.cvsignore",
71                      "**/RCS/**", "**/SCCS/**", "**/CVS/**", "**/CVS.adm/**",
72                      "**/RCSLOG/**", "**/cvslog.*", "**/tags/**", "**/TAGS/**",
73                      "**/.make.state", "**/.nse_depinfo",
74                      "**/*~", "**/#*", "**/.#*", "**/,*", "**/_$*", "**/*$", "**/*.old", "**/*.bak", "**/*.BAK",
75                      "**/*.orig", "**/*.rej", "**/.del-*",
76                      "**/*.a", "**/*.old", "**/*.o", "**/*.obj", "**/*.so", "**/*.exe",
77                      "**/*.Z", "**/*.elc", "**/*.ln", "**/core"),
78              null, new CVSIgnoreBuilder()),
79      /**
80       * The files and directories created by a DARCS source code control based tool.
81       */
82      DARCS("The files and directories created by a DARCS source code control based tool.",
83              Arrays.asList("**/_darcs/**", "**/.darcsrepo/**", "**/-darcs-backup*", "**/.darcs-temp-mail"), null, null),
84      /**
85       * The files and directories created by an Eclipse IDE based tool.
86       */
87      ECLIPSE("The files and directories created by an Eclipse IDE based tool.",
88              Arrays.asList("**/.checkstyle", "**/.classpath", "**/.factorypath",
89                      "**/.project", "**/.settings/**", "**/.externalToolBuilders"),
90              null, null),
91      /**
92       * The files and directories created by GIT source code control to support GIT, also processes files listed in '.gitignore'
93       * and (unless RAT_NO_GIT_GLOBAL_IGNORE is specified) the global gitignore.
94       */
95      GIT("The files and directories created by GIT source code control to support GIT, also processes files listed in '.gitignore' " +
96          "and (unless RAT_NO_GIT_GLOBAL_IGNORE is specified) the global gitignore.",
97              Arrays.asList("**/.git/**", "**/.gitignore"),
98              null,
99              new GitIgnoreBuilder()
100     ),
101     /**
102      * The hidden directories. Directories with names that start with {@code .}
103      */
104     HIDDEN_DIR("The hidden directories. Directories with names that start with '.'",
105             null,
106             new DocumentNameMatcher("HIDDEN_DIR", new Predicate<DocumentName>() {
107                 @Override
108                 public boolean test(final DocumentName documentName) {
109                     File file = documentName.asFile();
110                     return file.isDirectory() && ExclusionUtils.isHidden(documentName.getShortName());
111                 }
112                 @Override
113                 public String toString() {
114                     return "HIDDEN_DIR";
115                 }
116             }), null
117     ),
118     /**
119      * The hidden files. Directories with names that start with {@code .}
120      */
121     HIDDEN_FILE("The hidden files. Directories with names that start with '.'",
122             null,
123             new DocumentNameMatcher("HIDDEN_FILE", new Predicate<DocumentName>() {
124                 @Override
125                 public boolean test(final DocumentName documentName) {
126                     File file = documentName.asFile();
127                     return file.isFile() && ExclusionUtils.isHidden(documentName.getShortName());
128                 }
129                 @Override
130                 public String toString() {
131                     return "HIDDEN_FILE";
132                 }
133             }), null
134     ),
135     /**
136      * The files and directories created by an IDEA IDE based tool.
137      */
138     IDEA("The files and directories created by an IDEA IDE based tool.",
139             Arrays.asList("**/*.iml", "**/*.ipr", "**/*.iws", "**/.idea/**"), null, null),
140     /**
141      * The {@code .DS_Store} files on Mac computers.
142      */
143     MAC("The .DS_Store files on Mac computers.",
144             Collections.singletonList("**/.DS_Store"), null, null),
145     /**
146      * The files and directories created by Maven build system based project.
147      */
148     MAVEN("The files and directories created by Maven build system based project.",
149             Arrays.asList(
150                     "**/target/**", //
151                     "**/cobertura.ser", //
152                     "**/MANIFEST.MF", // a MANIFEST.MF file cannot contain comment lines. In other words: It is not possible, to include a license.
153                     "**/release.properties", //
154                     "**/.repository", // Used by Jenkins when a Maven job uses a private repository that is "Local to the workspace"
155                     "**/build.log", // RAT-160: until now maven-invoker-plugin runs create a build.log that is not part of a release
156                     "**/.mvn/**", // Project configuration since Maven 3.3.1 which contains maven.config, jvm.config, extensions.xml
157                     "**/pom.xml.releaseBackup"), null, null),
158     /**
159      * The files and directories created by a Mercurial source code control based tool.
160      */
161     MERCURIAL("The files and directories created by a Mercurial source code control based tool.",
162             Arrays.asList("**/.hg/**", "**/.hgignore"), null, new HgIgnoreBuilder()),
163     /**
164      * The set of miscellaneous files generally left by editors and the like.
165      */
166     MISC("The set of miscellaneous files generally left by editors and the like.",
167             Arrays.asList("**/*~", "**/#*#", "**/.#*", "**/%*%", "**/._*"),
168             null, null),
169     /**
170      * The files and directories created by an MKS source code control based tool.
171      */
172     MKS("The files and directories created by an MKS source code control based tool.",
173             Collections.singletonList("**/project.pj"), null, null),
174     /**
175      * The files and directories created by an RCS source code control based tool.
176      */
177     RCS("The files and directories created by a RCS source code control based tool.",
178             Collections.singletonList("**/RCS/**"), null, null),
179     /**
180      * The files and directories created by a SCCS source code control based tool.
181      */
182     SCCS("The files and directories created by a SCCS source code control based tool.",
183             Collections.singletonList("**/SCCS/**"), null, null),
184     /**
185      * The files and directories created by a Serena Dimensions V10 change control system based tool.
186      */
187     SERENA_DIMENSIONS_10("The files and directories created by a Serena Dimensions V10 change control system based tool.",
188             Collections.singletonList("**/.metadata/**"), null, null),
189     /**
190      * A standard collection of generally accepted patterns to ignore.
191      */
192     // see getCollections() for loading
193     STANDARD_PATTERNS("A standard collection of generally accepted patterns to ignore.", null, null, null),
194     /**
195      * A standard collection of SCMs.
196      */
197     // see getCollections() for loading
198     STANDARD_SCMS("A standard collection of SCMs", null, null, null),
199     /**
200      * The files and directories created by a Subversion source code control based tool.
201      */
202     SUBVERSION("The files and directories created by a Subversion source code control based tool.",
203             Collections.singletonList("**/.svn/**"), null, null),
204     /**
205      * The files and directories created by a Surround SCM source code control based tool.
206      */
207     SURROUND_SCM("The files and directories created by a Surround SCM source code control based tool.",
208             Collections.singletonList("**/.MySCMServerInfo"), null, null),
209     /**
210      * The files and directories created by a Visual Source Safe source code control based tool.
211      */
212     VSS("The files and directories created by a Visual Source Safe source code control based tool.",
213             Collections.singletonList("**/vssver.scc"), null, null);
214 
215     /** The collections of patterns to be excluded. May be empty.*/
216     private final Collection<String> patterns;
217     /** A document name matcher supplier to create a document name matcher. May be null */
218     private final DocumentNameMatcher staticDocumentNameMatcher;
219     /** The AbstractFileProcessorBuilder to process the exclude file associated with this exclusion. May be {@code null}. */
220     private final AbstractFileProcessorBuilder fileProcessorBuilder;
221     /** The description of this collection */
222     private final String desc;
223 
224     StandardCollection(final String desc, final Collection<String> patterns, final DocumentNameMatcher documentNameMatcher,
225                        final AbstractFileProcessorBuilder fileProcessorBuilder) {
226         this.desc = desc;
227         this.patterns = patterns == null ? Collections.emptyList() : new HashSet<>(patterns);
228         this.staticDocumentNameMatcher = documentNameMatcher;
229         this.fileProcessorBuilder = fileProcessorBuilder;
230     }
231 
232     /**
233      * @return the description of the given collection.
234      */
235     public String desc() {
236         return desc;
237     }
238 
239     /**
240      * Handles aggregate StandardCollections (e.g. ALL) by generating the set of StandardCollection objects that
241      * comprise this StandardCollection.
242      * @return the set of StandardCollection objects that comprise this StandardCollection.
243      */
244     private Set<StandardCollection> getCollections() {
245         Set<StandardCollection> result = new HashSet<>();
246         switch (this) {
247             case ALL:
248                 for (StandardCollection sc : StandardCollection.values()) {
249                     if (sc != ALL) {
250                         result.add(sc);
251                     }
252                 }
253                 break;
254             case STANDARD_PATTERNS:
255                 result.addAll(Arrays.asList(MISC, CVS, RCS, SCCS, VSS, MKS, SUBVERSION, ARCH, BAZAAR, SURROUND_SCM, MAC,
256                         SERENA_DIMENSIONS_10, MERCURIAL, GIT, BITKEEPER, DARCS));
257                 break;
258             case STANDARD_SCMS:
259                 result.addAll(Arrays.asList(SUBVERSION, GIT, BAZAAR, MERCURIAL, CVS));
260                 break;
261 
262             default:
263                 result.add(this);
264         }
265         return result;
266     }
267 
268     /**
269      * Returns combined and deduped collection of patterns.
270      * @return the combined and deduped collection of patterns in the given collection.
271      */
272     public Set<String> patterns() {
273         Set<String> result = new HashSet<>();
274         getCollections().forEach(sc -> result.addAll(sc.patterns));
275         return result;
276     }
277 
278     /**
279      * Returns the fileProcessor if it exists.
280      *
281      * @return the fileProcessor if it exists, {@code null} otherwise.
282      */
283     public ExtendedIterator<AbstractFileProcessorBuilder> fileProcessorBuilder() {
284         List<AbstractFileProcessorBuilder> lst = new ArrayList<>();
285         for (StandardCollection sc : getCollections()) {
286             if (sc.fileProcessorBuilder != null) {
287                 lst.add(sc.fileProcessorBuilder);
288             }
289         }
290         return ExtendedIterator.create(lst.iterator());
291     }
292 
293     /**
294      * Returns the documentNameMatchSupplier if it exists.
295      *
296      * @return the documentNameMatchSupplier if it exists, {@code null} otherwise.
297      */
298     public DocumentNameMatcher staticDocumentNameMatcher() {
299         // account for cases where this has more than one supplier.
300         List<DocumentNameMatcher> lst = new ArrayList<>();
301         for (StandardCollection sc : getCollections()) {
302             if (sc.staticDocumentNameMatcher != null) {
303                 lst.add(sc.staticDocumentNameMatcher);
304             }
305         }
306         if (lst.isEmpty()) {
307             return null;
308         }
309         if (lst.size() == 1) {
310             return lst.get(0);
311         }
312 
313         return new DocumentNameMatcher(name() + " static DocumentNameMatchers",  DocumentNameMatcher.or(lst));
314     }
315 
316     /**
317      * Returns {@code true} if the collections has a document name match supplier.
318      *
319      * @return {@code true} if the collections has a document name match supplier.
320      */
321     public boolean hasStaticDocumentNameMatcher() {
322         // account for cases where this has more than one supplier.
323         for (StandardCollection sc : getCollections()) {
324             if (sc.staticDocumentNameMatcher != null) {
325                 return true;
326             }
327         }
328         return false;
329     }
330 }