1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.pmd;
20
21 import java.io.IOException;
22 import java.nio.file.Files;
23 import java.nio.file.Paths;
24 import java.util.ArrayList;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.stream.Collectors;
29 import java.util.stream.Stream;
30
31 import net.sourceforge.pmd.cpd.Mark;
32 import net.sourceforge.pmd.cpd.Match;
33 import org.apache.maven.plugin.MojoExecutionException;
34 import org.apache.maven.plugins.pmd.model.CpdFile;
35 import org.apache.maven.plugins.pmd.model.Duplication;
36
37
38
39
40
41
42
43
44 public class ExcludeDuplicationsFromFile implements ExcludeFromFile<Duplication> {
45
46 private final List<Set<String>> exclusionList = new ArrayList<>();
47
48 @Override
49 public boolean isExcludedFromFailure(final Duplication errorDetail) {
50 final Set<String> uniquePaths = new HashSet<>();
51 for (final CpdFile cpdFile : errorDetail.getFiles()) {
52 uniquePaths.add(cpdFile.getPath());
53 }
54 return isExcludedFromFailure(uniquePaths);
55 }
56
57
58
59
60
61
62
63
64 public boolean isExcludedFromFailure(final Match errorDetail) {
65 final Set<String> uniquePaths = new HashSet<>();
66 for (Mark mark : errorDetail.getMarkSet()) {
67 uniquePaths.add(mark.getLocation().getFileId().getAbsolutePath());
68 }
69 return isExcludedFromFailure(uniquePaths);
70 }
71
72 private boolean isExcludedFromFailure(Set<String> uniquePaths) {
73 for (final Set<String> singleExclusionGroup : exclusionList) {
74 if (uniquePaths.size() == singleExclusionGroup.size()
75 && duplicationExcludedByGroup(uniquePaths, singleExclusionGroup)) {
76 return true;
77 }
78 }
79 return false;
80 }
81
82 private boolean duplicationExcludedByGroup(final Set<String> uniquePaths, final Set<String> singleExclusionGroup) {
83 for (final String path : uniquePaths) {
84 if (!fileExcludedByGroup(path, singleExclusionGroup)) {
85 return false;
86 }
87 }
88 return true;
89 }
90
91 private boolean fileExcludedByGroup(final String path, final Set<String> singleExclusionGroup) {
92 final String formattedPath = path.replace('\\', '.').replace('/', '.');
93 for (final String className : singleExclusionGroup) {
94 if (formattedPath.contains(className)) {
95 return true;
96 }
97 }
98 return false;
99 }
100
101 @Override
102 public void loadExcludeFromFailuresData(final String excludeFromFailureFile) throws MojoExecutionException {
103 if (excludeFromFailureFile == null || excludeFromFailureFile.isEmpty()) {
104 return;
105 }
106
107 try (Stream<String> lines = Files.lines(Paths.get(excludeFromFailureFile))) {
108 exclusionList.addAll(lines.filter(line -> !line.startsWith("#"))
109 .map(line -> createSetFromExclusionLine(line))
110 .collect(Collectors.toList()));
111 } catch (final IOException e) {
112 throw new MojoExecutionException("Cannot load file " + excludeFromFailureFile, e);
113 }
114 }
115
116 private Set<String> createSetFromExclusionLine(final String line) {
117 final Set<String> result = new HashSet<>();
118 for (final String className : line.split(",")) {
119 result.add(className.trim());
120 }
121 return result;
122 }
123
124 @Override
125 public int countExclusions() {
126 return exclusionList.size();
127 }
128 }