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