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.File;
23  import java.io.FileInputStream;
24  import java.io.IOException;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.Map;
28  import java.util.Map.Entry;
29  import java.util.Properties;
30  import java.util.Set;
31  
32  import org.apache.commons.lang3.StringUtils;
33  import org.apache.maven.plugin.MojoExecutionException;
34  import org.apache.maven.plugins.pmd.model.Violation;
35  
36  import net.sourceforge.pmd.RuleViolation;
37  
38  
39  
40  
41  
42  
43  
44  
45  public class ExcludeViolationsFromFile implements ExcludeFromFile<Violation>
46  {
47      private Map<String, Set<String>> excludeFromFailureClasses = new HashMap<>();
48  
49      @Override
50      public void loadExcludeFromFailuresData( final String excludeFromFailureFile )
51          throws MojoExecutionException
52      {
53          if ( StringUtils.isEmpty( excludeFromFailureFile ) )
54          {
55              return;
56          }
57  
58          File file = new File( excludeFromFailureFile );
59          if ( !file.exists() )
60          {
61              return;
62          }
63          final Properties props = new Properties();
64          try ( FileInputStream fileInputStream = new FileInputStream( new File( excludeFromFailureFile ) ) )
65          {
66              props.load( fileInputStream );
67          }
68          catch ( final IOException e )
69          {
70              throw new MojoExecutionException( "Cannot load properties file " + excludeFromFailureFile, e );
71          }
72          for ( final Entry<Object, Object> propEntry : props.entrySet() )
73          {
74              final Set<String> excludedRuleSet = new HashSet<>();
75              final String className = propEntry.getKey().toString();
76              final String[] excludedRules = propEntry.getValue().toString().split( "," );
77              for ( final String excludedRule : excludedRules )
78              {
79                  excludedRuleSet.add( excludedRule.trim() );
80              }
81              excludeFromFailureClasses.put( className, excludedRuleSet );
82          }
83      }
84  
85      @Override
86      public boolean isExcludedFromFailure( final Violation errorDetail )
87      {
88          final String className = extractClassName( errorDetail.getViolationPackage(), errorDetail.getViolationClass(),
89                  errorDetail.getFileName() );
90          return isExcludedFromFailure( className, errorDetail.getRule() );
91      }
92  
93      
94  
95  
96  
97  
98  
99  
100     public boolean isExcludedFromFailure( final RuleViolation errorDetail )
101     {
102         final String className = extractClassName( errorDetail.getPackageName(), errorDetail.getClassName(),
103                 errorDetail.getFilename() );
104         return isExcludedFromFailure( className, errorDetail.getRule().getName() );
105     }
106 
107     @Override
108     public int countExclusions()
109     {
110         int result = 0;
111         for ( Set<String> rules : excludeFromFailureClasses.values() )
112         {
113             result += rules.size();
114         }
115         return result;
116     }
117 
118     private boolean isExcludedFromFailure( String className, String ruleName )
119     {
120         final Set<String> excludedRuleSet = excludeFromFailureClasses.get( className );
121         return excludedRuleSet != null && excludedRuleSet.contains( ruleName );
122     }
123 
124     private String extractClassName( String packageName, String className, String fullPath )
125     {
126         
127         
128         if ( StringUtils.isNotEmpty( packageName ) && StringUtils.isNotEmpty( className ) )
129         {
130             return packageName + "." + className;
131         }
132         else if ( StringUtils.isNotEmpty( packageName ) )
133         {
134             String fileName = fullPath;
135             fileName = fileName.substring( fileName.lastIndexOf( File.separatorChar ) + 1 );
136             fileName = fileName.substring( 0, fileName.length() - 5 );
137             return packageName + "." + fileName;
138         }
139         else
140         {
141             final String fileName = fullPath;
142             final int javaIdx = fileName.indexOf( File.separator + "java" + File.separator );
143             return fileName.substring( javaIdx >= 0 ? javaIdx + 6 : 0, fileName.length() - 5 ).replace(
144                 File.separatorChar, '.' );
145         }
146     }
147 }