You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ad...@apache.org on 2016/10/01 09:29:53 UTC

svn commit: r1762989 - in /maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd: CpdReport.java CpdViolationCheckMojo.java ExcludeDuplicationsFromFile.java ExcludeViolationsFromFile.java PmdReport.java PmdViolationCheckMojo.java

Author: adangel
Date: Sat Oct  1 09:29:53 2016
New Revision: 1762989

URL: http://svn.apache.org/viewvc?rev=1762989&view=rev
Log:
[MPMD-162] PMD/CPD report does not take into account pmd.excludeFromFailureFile
Refactoring - move the code into Exclude{Violations,Duplications}FromFile
helper classes

Added:
    maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeDuplicationsFromFile.java
      - copied, changed from r1762988, maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java
    maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeViolationsFromFile.java
Modified:
    maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java
    maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java
    maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java
    maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdViolationCheckMojo.java

Modified: maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java?rev=1762989&r1=1762988&r2=1762989&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java (original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java Sat Oct  1 09:29:53 2016
@@ -22,20 +22,16 @@ package org.apache.maven.plugin.pmd;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.FileReader;
 import java.io.IOException;
-import java.io.LineNumberReader;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Properties;
 import java.util.ResourceBundle;
-import java.util.Set;
 
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugins.annotations.Mojo;
@@ -54,7 +50,6 @@ import net.sourceforge.pmd.cpd.JavaLangu
 import net.sourceforge.pmd.cpd.JavaTokenizer;
 import net.sourceforge.pmd.cpd.Language;
 import net.sourceforge.pmd.cpd.LanguageFactory;
-import net.sourceforge.pmd.cpd.Mark;
 import net.sourceforge.pmd.cpd.Match;
 import net.sourceforge.pmd.cpd.Renderer;
 import net.sourceforge.pmd.cpd.XMLRenderer;
@@ -434,78 +429,15 @@ public class CpdReport
 
 
 
-
-    private final List<Set<String>> exclusionList = new ArrayList<>();
+    private final ExcludeDuplicationsFromFile excludeDuplicationsFromFile = new ExcludeDuplicationsFromFile();
     protected boolean isExcludedFromFailure( final Match errorDetail )
     {
-        final Set<String> uniquePaths = new HashSet<>();
-        for ( Mark mark : errorDetail.getMarkSet() )
-        {
-            uniquePaths.add( mark.getFilename() );
-        }
-        for ( final Set<String> singleExclusionGroup : exclusionList )
-        {
-            if ( uniquePaths.size() == singleExclusionGroup.size()
-                && duplicationExcludedByGroup( uniquePaths, singleExclusionGroup ) )
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean duplicationExcludedByGroup( final Set<String> uniquePaths, final Set<String> singleExclusionGroup )
-    {
-        for ( final String path : uniquePaths )
-        {
-            if ( !fileExcludedByGroup( path, singleExclusionGroup ) )
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean fileExcludedByGroup( final String path, final Set<String> singleExclusionGroup )
-    {
-        final String formattedPath = path.replace( '\\', '.' ).replace( '/', '.' );
-        for ( final String className : singleExclusionGroup )
-        {
-            if ( formattedPath.contains( className ) )
-            {
-                return true;
-            }
-        }
-        return false;
+        return excludeDuplicationsFromFile.isExcludedFromFailure( errorDetail );
     }
 
     protected void loadExcludeFromFailuresData( final String excludeFromFailureFile )
         throws MojoExecutionException
     {
-        try ( LineNumberReader reader = new LineNumberReader( new FileReader( excludeFromFailureFile ) ) )
-        {
-            String line;
-            while ( ( line = reader.readLine() ) != null )
-            {
-                if ( !line.startsWith( "#" ) )
-                {
-                    exclusionList.add( createSetFromExclusionLine( line ) );
-                }
-            }
-        }
-        catch ( final IOException e )
-        {
-            throw new MojoExecutionException( "Cannot load file " + excludeFromFailureFile, e );
-        }
-    }
-
-    private Set<String> createSetFromExclusionLine( final String line )
-    {
-        final Set<String> result = new HashSet<>();
-        for ( final String className : line.split( "," ) )
-        {
-            result.add( className.trim() );
-        }
-        return result;
+        excludeDuplicationsFromFile.loadExcludeFromFailuresData( excludeFromFailureFile );
     }
 }

Modified: maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java?rev=1762989&r1=1762988&r2=1762989&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java (original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java Sat Oct  1 09:29:53 2016
@@ -22,11 +22,7 @@ package org.apache.maven.plugin.pmd;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
-import java.io.LineNumberReader;
-import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
@@ -58,8 +54,6 @@ public class CpdViolationCheckMojo
     @Parameter( property = "cpd.skip", defaultValue = "false" )
     private boolean skip;
 
-    private final List<Set<String>> exclusionList = new ArrayList<>();
-
     /**
      * Whether to fail the build if the validation check fails.
      *
@@ -118,76 +112,18 @@ public class CpdViolationCheckMojo
         return details.getDuplications();
     }
 
+    private final ExcludeDuplicationsFromFile excludeDuplicationsFromFile = new ExcludeDuplicationsFromFile();
     @Override
     protected boolean isExcludedFromFailure( final Duplication errorDetail )
     {
-        final Set<String> uniquePaths = new HashSet<>();
-        for ( final CpdFile cpdFile : errorDetail.getFiles() )
-        {
-            uniquePaths.add( cpdFile.getPath() );
-        }
-        for ( final Set<String> singleExclusionGroup : exclusionList )
-        {
-            if ( uniquePaths.size() == singleExclusionGroup.size()
-                && duplicationExcludedByGroup( uniquePaths, singleExclusionGroup ) )
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean duplicationExcludedByGroup( final Set<String> uniquePaths, final Set<String> singleExclusionGroup )
-    {
-        for ( final String path : uniquePaths )
-        {
-            if ( !fileExcludedByGroup( path, singleExclusionGroup ) )
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean fileExcludedByGroup( final String path, final Set<String> singleExclusionGroup )
-    {
-        final String formattedPath = path.replace( '\\', '.' ).replace( '/', '.' );
-        for ( final String className : singleExclusionGroup )
-        {
-            if ( formattedPath.contains( className ) )
-            {
-                return true;
-            }
-        }
-        return false;
+        return excludeDuplicationsFromFile.isExcludedFromFailure( errorDetail );
     }
 
     @Override
     protected void loadExcludeFromFailuresData( final String excludeFromFailureFile )
         throws MojoExecutionException
     {
-        try ( LineNumberReader reader = new LineNumberReader( new FileReader( excludeFromFailureFile ) ) )
-        {
-            String line;
-            while ( ( line = reader.readLine() ) != null )
-            {
-                exclusionList.add( createSetFromExclusionLine( line ) );
-            }
-        }
-        catch ( final IOException e )
-        {
-            throw new MojoExecutionException( "Cannot load file " + excludeFromFailureFile, e );
-        }
-    }
-
-    private Set<String> createSetFromExclusionLine( final String line )
-    {
-        final Set<String> result = new HashSet<>();
-        for ( final String className : line.split( "," ) )
-        {
-            result.add( className.trim() );
-        }
-        return result;
+        excludeDuplicationsFromFile.loadExcludeFromFailuresData( excludeFromFailureFile );
     }
 
     @Override

Copied: maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeDuplicationsFromFile.java (from r1762988, maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java)
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeDuplicationsFromFile.java?p2=maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeDuplicationsFromFile.java&p1=maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java&r1=1762988&r2=1762989&rev=1762989&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdViolationCheckMojo.java (original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeDuplicationsFromFile.java Sat Oct  1 09:29:53 2016
@@ -9,7 +9,7 @@ package org.apache.maven.plugin.pmd;
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *  http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -19,7 +19,6 @@ package org.apache.maven.plugin.pmd;
  * under the License.
  */
 
-import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.LineNumberReader;
@@ -29,103 +28,60 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugin.pmd.model.CpdErrorDetail;
 import org.apache.maven.plugin.pmd.model.CpdFile;
 import org.apache.maven.plugin.pmd.model.Duplication;
-import org.apache.maven.plugin.pmd.model.io.xpp3.CpdXpp3Reader;
-import org.apache.maven.plugins.annotations.Execute;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import net.sourceforge.pmd.cpd.Mark;
+import net.sourceforge.pmd.cpd.Match;
 
 /**
- * Fail the build if there were any CPD violations in the source code.
+ * This class contains utility methods to load property files which define which files
+ * should be excluded from the CPD duplication results.
+ * See property <code>pmd.excludeFromFailureFile</code>.
  *
- * @version $Id$
- * @since 2.0
+ * @author Andreas Dangel
  */
-@Mojo( name = "cpd-check", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true )
-@Execute( goal = "cpd" )
-public class CpdViolationCheckMojo
-    extends AbstractPmdViolationCheckMojo<Duplication>
+public class ExcludeDuplicationsFromFile
 {
 
-    /**
-     * Skip the CPD violation checks. Most useful on the command line via "-Dcpd.skip=true".
-     */
-    @Parameter( property = "cpd.skip", defaultValue = "false" )
-    private boolean skip;
-
     private final List<Set<String>> exclusionList = new ArrayList<>();
 
     /**
-     * Whether to fail the build if the validation check fails.
-     *
-     * @since 3.0
-     */
-    @Parameter( property = "cpd.failOnViolation", defaultValue = "true", required = true )
-    protected boolean failOnViolation;
-
-    /**
-     * {@inheritDoc}
+     * Checks whether the given {@link Duplication} is excluded.
+     * Note: The exclusion must have been loaded before via {@link #loadExcludeFromFailuresData(String)}.
+     * 
+     * @param errorDetail the duplication to check
+     * @return <code>true</code> if the given duplication should be excluded, <code>false</code> otherwise.
      */
-    public void execute()
-        throws MojoExecutionException, MojoFailureException
+    public boolean isExcludedFromFailure( final Duplication errorDetail )
     {
-        if ( !skip )
+        final Set<String> uniquePaths = new HashSet<>();
+        for ( final CpdFile cpdFile : errorDetail.getFiles() )
         {
-            executeCheck( "cpd.xml", "duplication", "CPD duplication", 10 );
+            uniquePaths.add( cpdFile.getPath() );
         }
+        return isExcludedFromFailure( uniquePaths );
     }
 
     /**
-     * {@inheritDoc}
+     * Checks whether the given {@link Match} is excluded.
+     * Note: The exclusion must have been loaded before via {@link #loadExcludeFromFailuresData(String)}.
+     * 
+     * @param errorDetail the duplication to check
+     * @return <code>true</code> if the given duplication should be excluded, <code>false</code> otherwise.
      */
-    @Override
-    protected void printError( Duplication item, String severity )
+    public boolean isExcludedFromFailure( final Match errorDetail )
     {
-        int lines = item.getLines();
-
-        StringBuilder buff = new StringBuilder( 100 );
-        buff.append( "CPD " ).append( severity ).append( ": Found " );
-        buff.append( lines ).append( " lines of duplicated code at locations:" );
-        this.getLog().info( buff.toString() );
-
-        for ( CpdFile file : item.getFiles() )
+        final Set<String> uniquePaths = new HashSet<>();
+        for ( Mark mark : errorDetail.getMarkSet() )
         {
-            buff.setLength( 0 );
-            buff.append( "    " );
-            buff.append( file.getPath() );
-            buff.append( " line " ).append( file.getLine() );
-            this.getLog().info( buff.toString() );
+            uniquePaths.add( mark.getFilename() );
         }
-
-        this.getLog().debug( "CPD " + severity + ": Code Fragment " );
-        this.getLog().debug( item.getCodefragment() );
+        return isExcludedFromFailure( uniquePaths );
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected List<Duplication> getErrorDetails( File cpdFile )
-        throws XmlPullParserException, IOException
+    private boolean isExcludedFromFailure( Set<String> uniquePaths )
     {
-        CpdXpp3Reader reader = new CpdXpp3Reader();
-        CpdErrorDetail details = reader.read( new FileReader( cpdFile ), false );
-        return details.getDuplications();
-    }
-
-    @Override
-    protected boolean isExcludedFromFailure( final Duplication errorDetail )
-    {
-        final Set<String> uniquePaths = new HashSet<>();
-        for ( final CpdFile cpdFile : errorDetail.getFiles() )
-        {
-            uniquePaths.add( cpdFile.getPath() );
-        }
         for ( final Set<String> singleExclusionGroup : exclusionList )
         {
             if ( uniquePaths.size() == singleExclusionGroup.size()
@@ -162,16 +118,24 @@ public class CpdViolationCheckMojo
         return false;
     }
 
-    @Override
-    protected void loadExcludeFromFailuresData( final String excludeFromFailureFile )
-        throws MojoExecutionException
+    /**
+     * Loads the CPD exclusions from the given file.
+     *
+     * @param excludeFromFailureFile the file to load the exclusions from
+     * @throws MojoExecutionException if the file couldn't be loaded
+     */
+    public void loadExcludeFromFailuresData( final String excludeFromFailureFile )
+            throws MojoExecutionException
     {
         try ( LineNumberReader reader = new LineNumberReader( new FileReader( excludeFromFailureFile ) ) )
         {
             String line;
             while ( ( line = reader.readLine() ) != null )
             {
-                exclusionList.add( createSetFromExclusionLine( line ) );
+                if ( !line.startsWith( "#" ) )
+                {
+                    exclusionList.add( createSetFromExclusionLine( line ) );
+                }
             }
         }
         catch ( final IOException e )
@@ -189,22 +153,4 @@ public class CpdViolationCheckMojo
         }
         return result;
     }
-
-    @Override
-    protected int getPriority( Duplication errorDetail )
-    {
-        return 0;
-    }
-
-    @Override
-    protected ViolationDetails<Duplication> newViolationDetailsInstance()
-    {
-        return new ViolationDetails<>();
-    }
-
-    @Override
-    public boolean isFailOnViolation()
-    {
-        return failOnViolation;
-    }
-}
\ No newline at end of file
+}

Added: maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeViolationsFromFile.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeViolationsFromFile.java?rev=1762989&view=auto
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeViolationsFromFile.java (added)
+++ maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/ExcludeViolationsFromFile.java Sat Oct  1 09:29:53 2016
@@ -0,0 +1,151 @@
+package org.apache.maven.plugin.pmd;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.pmd.model.Violation;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+
+import net.sourceforge.pmd.RuleViolation;
+
+/**
+ * This class contains utility for loading property files, which define which PMD violations
+ * from which classes should be ignored and not cause a failure.
+ * See property <code>pmd.excludeFromFailureFile</code>.
+ *
+ * @author Andreas Dangel
+ */
+public class ExcludeViolationsFromFile
+{
+    private Map<String, Set<String>> excludeFromFailureClasses = new HashMap<>();
+    
+    /**
+     * Loads the exclude definitions from the given file.
+     *
+     * @param excludeFromFailureFile the path to the properties file
+     * @throws MojoExecutionException if the properties file couldn't be loaded
+     */
+    public void loadExcludeFromFailuresData( final String excludeFromFailureFile )
+        throws MojoExecutionException
+    {
+        File file = new File( excludeFromFailureFile );
+        if ( !file.exists() )
+        {
+            return;
+        }
+        final Properties props = new Properties();
+        FileInputStream fileInputStream = null;
+        try
+        {
+            fileInputStream = new FileInputStream( new File( excludeFromFailureFile ) );
+            props.load( fileInputStream );
+            fileInputStream.close();
+            fileInputStream = null;
+        }
+        catch ( final IOException e )
+        {
+            throw new MojoExecutionException( "Cannot load properties file " + excludeFromFailureFile, e );
+        }
+        finally
+        {
+            IOUtil.close( fileInputStream );
+        }
+        for ( final Entry<Object, Object> propEntry : props.entrySet() )
+        {
+            final Set<String> excludedRuleSet = new HashSet<>();
+            final String className = propEntry.getKey().toString();
+            final String[] excludedRules = propEntry.getValue().toString().split( "," );
+            for ( final String excludedRule : excludedRules )
+            {
+                excludedRuleSet.add( excludedRule.trim() );
+            }
+            excludeFromFailureClasses.put( className, excludedRuleSet );
+        }
+    }
+
+    /**
+     * Checks whether the given {@link Violation} is excluded. Note: the exclusions must have been
+     * loaded before via {@link #loadExcludeFromFailuresData(String)}.
+     *
+     * @param errorDetail the violation to check
+     * @return <code>true</code> if the violation should be excluded, <code>false</code> otherwise.
+     */
+    public boolean isExcludedFromFailure( final Violation errorDetail )
+    {
+        final String className = extractClassName( errorDetail.getViolationPackage(), errorDetail.getViolationClass(),
+                errorDetail.getFileName() );
+        return isExcludedFromFailure( className, errorDetail.getRule() );
+    }
+
+    /**
+     * Checks whether the given {@link RuleViolation} is excluded. Note: the exclusions must have been
+     * loaded before via {@link #loadExcludeFromFailuresData(String)}.
+     *
+     * @param errorDetail the violation to check
+     * @return <code>true</code> if the violation should be excluded, <code>false</code> otherwise.
+     */
+    public boolean isExcludedFromFailure( final RuleViolation errorDetail )
+    {
+        final String className = extractClassName( errorDetail.getPackageName(), errorDetail.getClassName(),
+                errorDetail.getFilename() );
+        return isExcludedFromFailure( className, errorDetail.getRule().getName() );
+    }
+
+    private boolean isExcludedFromFailure( String className, String ruleName )
+    {
+        final Set<String> excludedRuleSet = excludeFromFailureClasses.get( className );
+        return excludedRuleSet != null && excludedRuleSet.contains( ruleName );
+    }
+
+    private String extractClassName( String packageName, String className, String fullPath )
+    {
+        // for some reason, some violations don't contain the package name, so we have to guess the full class name
+        // this looks like a bug in PMD - at least for UnusedImport rule.
+        if ( StringUtils.isNotEmpty( packageName ) && StringUtils.isNotEmpty( className ) )
+        {
+            return packageName + "." + className;
+        }
+        else if ( StringUtils.isNotEmpty( packageName ) )
+        {
+            String fileName = fullPath;
+            fileName = fileName.substring( fileName.lastIndexOf( File.separatorChar ) + 1 );
+            fileName = fileName.substring( 0, fileName.length() - 5 );
+            return packageName + "." + fileName;
+        }
+        else
+        {
+            final String fileName = fullPath;
+            final int javaIdx = fileName.indexOf( File.separator + "java" + File.separator );
+            return fileName.substring( javaIdx >= 0 ? javaIdx + 6 : 0, fileName.length() - 5 ).replace(
+                File.separatorChar, '.' );
+        }
+    }
+}

Modified: maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java?rev=1762989&r1=1762988&r2=1762989&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java (original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java Sat Oct  1 09:29:53 2016
@@ -20,7 +20,6 @@ package org.apache.maven.plugin.pmd;
  */
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -29,16 +28,26 @@ import java.io.PrintStream;
 import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Properties;
 import java.util.ResourceBundle;
-import java.util.Set;
-import java.util.Map.Entry;
+
+import org.apache.maven.doxia.sink.Sink;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.reporting.MavenReportException;
+import org.codehaus.plexus.resource.ResourceManager;
+import org.codehaus.plexus.resource.loader.FileResourceCreationException;
+import org.codehaus.plexus.resource.loader.FileResourceLoader;
+import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.StringUtils;
 
 import net.sourceforge.pmd.PMD;
 import net.sourceforge.pmd.PMDConfiguration;
@@ -60,22 +69,6 @@ import net.sourceforge.pmd.renderers.XML
 import net.sourceforge.pmd.util.datasource.DataSource;
 import net.sourceforge.pmd.util.datasource.FileDataSource;
 
-import org.apache.maven.doxia.sink.Sink;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.annotations.Component;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.reporting.MavenReportException;
-import org.codehaus.plexus.resource.ResourceManager;
-import org.codehaus.plexus.resource.loader.FileResourceCreationException;
-import org.codehaus.plexus.resource.loader.FileResourceLoader;
-import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
-import org.codehaus.plexus.util.FileUtils;
-import org.codehaus.plexus.util.IOUtil;
-import org.codehaus.plexus.util.ReaderFactory;
-import org.codehaus.plexus.util.StringUtils;
-
 /**
  * Creates a PMD report.
  *
@@ -677,76 +670,16 @@ public class PmdReport
         return renderer;
     }
 
-    private final Map<String, Set<String>> excludeFromFailureClasses = new HashMap<>();
+    private final ExcludeViolationsFromFile excludeFromFile = new ExcludeViolationsFromFile();
 
     protected void loadExcludeFromFailuresData( final String excludeFromFailureFile )
         throws MojoExecutionException
     {
-        File file = new File( excludeFromFailureFile );
-        if ( !file.exists() )
-        {
-            return;
-        }
-        final Properties props = new Properties();
-        FileInputStream fileInputStream = null;
-        try
-        {
-            fileInputStream = new FileInputStream( new File( excludeFromFailureFile ) );
-            props.load( fileInputStream );
-            fileInputStream.close();
-            fileInputStream = null;
-        }
-        catch ( final IOException e )
-        {
-            throw new MojoExecutionException( "Cannot load properties file " + excludeFromFailureFile, e );
-        }
-        finally
-        {
-            IOUtil.close( fileInputStream );
-        }
-        for ( final Entry<Object, Object> propEntry : props.entrySet() )
-        {
-            final Set<String> excludedRuleSet = new HashSet<>();
-            final String className = propEntry.getKey().toString();
-            final String[] excludedRules = propEntry.getValue().toString().split( "," );
-            for ( final String excludedRule : excludedRules )
-            {
-                excludedRuleSet.add( excludedRule.trim() );
-            }
-            excludeFromFailureClasses.put( className, excludedRuleSet );
-        }
+        excludeFromFile.loadExcludeFromFailuresData( excludeFromFailureFile );
     }
 
     protected boolean isExcludedFromFailure( final RuleViolation errorDetail )
     {
-        final String className = extractClassName( errorDetail );
-        final Set<String> excludedRuleSet = excludeFromFailureClasses.get( className );
-        return excludedRuleSet != null && excludedRuleSet.contains( errorDetail.getRule().getName() );
-    }
-
-    private String extractClassName( final RuleViolation errorDetail )
-    {
-        // for some reason, some violations don't contain the package name, so we have to guess the full class name
-        // this looks like a bug in PMD - at least for UnusedImport rule.
-        if ( StringUtils.isNotEmpty( errorDetail.getPackageName() )
-                && StringUtils.isNotEmpty( errorDetail.getClassName() ) )
-        {
-            return errorDetail.getPackageName() + "." + errorDetail.getClassName();
-        }
-        else if ( StringUtils.isNotEmpty( errorDetail.getPackageName() ) )
-        {
-            String fileName = errorDetail.getFilename();
-            fileName = fileName.substring( fileName.lastIndexOf( File.separatorChar ) + 1 );
-            fileName = fileName.substring( 0, fileName.length() - 5 );
-            return errorDetail.getPackageName() + "." + fileName;
-        }
-        else
-        {
-            final String fileName = errorDetail.getFilename();
-            final int javaIdx = fileName.indexOf( File.separator + "java" + File.separator );
-            return fileName.substring( javaIdx >= 0 ? javaIdx + 6 : 0, fileName.length() - 5 ).replace(
-                File.separatorChar, '.' );
-        }
+        return excludeFromFile.isExcludedFromFailure( errorDetail );
     }
-
 }

Modified: maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdViolationCheckMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdViolationCheckMojo.java?rev=1762989&r1=1762988&r2=1762989&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdViolationCheckMojo.java (original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdViolationCheckMojo.java Sat Oct  1 09:29:53 2016
@@ -19,6 +19,12 @@ package org.apache.maven.plugin.pmd;
  * under the License.
  */
 
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.pmd.model.PmdErrorDetail;
@@ -29,23 +35,9 @@ import org.apache.maven.plugins.annotati
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
-import org.codehaus.plexus.util.IOUtil;
 import org.codehaus.plexus.util.StringUtils;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.Set;
-
 /**
  * Fail the build if there were any PMD violations in the source code.
  *
@@ -71,7 +63,7 @@ public class PmdViolationCheckMojo
     @Parameter( property = "pmd.skip", defaultValue = "false" )
     private boolean skip;
 
-    private final Map<String, Set<String>> excludeFromFailureClasses = new HashMap<>();
+    private final ExcludeViolationsFromFile excludeFromFile = new ExcludeViolationsFromFile();
 
     /**
      * {@inheritDoc}
@@ -89,63 +81,13 @@ public class PmdViolationCheckMojo
     protected void loadExcludeFromFailuresData( final String excludeFromFailureFile )
         throws MojoExecutionException
     {
-        File file = new File( excludeFromFailureFile );
-        if ( !file.exists() )
-        {
-            return;
-        }
-        final Properties props = new Properties();
-        FileInputStream fileInputStream = null;
-        try
-        {
-            fileInputStream = new FileInputStream( new File( excludeFromFailureFile ) );
-            props.load( fileInputStream );
-            fileInputStream.close();
-            fileInputStream = null;
-        }
-        catch ( final IOException e )
-        {
-            throw new MojoExecutionException( "Cannot load properties file " + excludeFromFailureFile, e );
-        }
-        finally
-        {
-            IOUtil.close( fileInputStream );
-        }
-        for ( final Entry<Object, Object> propEntry : props.entrySet() )
-        {
-            final Set<String> excludedRuleSet = new HashSet<>();
-            final String className = propEntry.getKey().toString();
-            final String[] excludedRules = propEntry.getValue().toString().split( "," );
-            for ( final String excludedRule : excludedRules )
-            {
-                excludedRuleSet.add( excludedRule.trim() );
-            }
-            excludeFromFailureClasses.put( className, excludedRuleSet );
-        }
+        excludeFromFile.loadExcludeFromFailuresData( excludeFromFailureFile );
     }
 
     @Override
     protected boolean isExcludedFromFailure( final Violation errorDetail )
     {
-        final String className = extractClassName( errorDetail );
-        final Set<String> excludedRuleSet = excludeFromFailureClasses.get( className );
-        return excludedRuleSet != null && excludedRuleSet.contains( errorDetail.getRule() );
-    }
-
-    private String extractClassName( final Violation errorDetail )
-    {
-        // for some reason, some violations don't contain the package name, so we have to guess the full class name
-        if ( errorDetail.getViolationPackage() != null && errorDetail.getViolationClass() != null )
-        {
-            return errorDetail.getViolationPackage() + "." + errorDetail.getViolationClass();
-        }
-        else
-        {
-            final String fileName = errorDetail.getFileName();
-            final int javaIdx = fileName.indexOf( File.separator + "java" + File.separator );
-            return fileName.substring( javaIdx >= 0 ? javaIdx + 6 : 0, fileName.length() - 5 ).replace(
-                File.separatorChar, '.' );
-        }
+        return excludeFromFile.isExcludedFromFailure( errorDetail );
     }
 
     /**