View Javadoc
1   package org.apache.maven.plugin.pmd;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.FileReader;
24  import java.io.IOException;
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import org.apache.maven.plugin.MojoExecutionException;
29  import org.apache.maven.plugin.MojoFailureException;
30  import org.apache.maven.plugin.pmd.model.PmdErrorDetail;
31  import org.apache.maven.plugin.pmd.model.PmdFile;
32  import org.apache.maven.plugin.pmd.model.Violation;
33  import org.apache.maven.plugin.pmd.model.io.xpp3.PmdXpp3Reader;
34  import org.apache.maven.plugins.annotations.Execute;
35  import org.apache.maven.plugins.annotations.LifecyclePhase;
36  import org.apache.maven.plugins.annotations.Mojo;
37  import org.apache.maven.plugins.annotations.Parameter;
38  import org.codehaus.plexus.util.StringUtils;
39  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
40  
41  /**
42   * Fail the build if there were any PMD violations in the source code.
43   *
44   * @version $Id: PmdViolationCheckMojo.html 999063 2016-10-08 16:53:12Z adangel $
45   * @since 2.0
46   */
47  @Mojo( name = "check", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true )
48  @Execute( goal = "pmd" )
49  public class PmdViolationCheckMojo
50      extends AbstractPmdViolationCheckMojo<Violation>
51  {
52      /**
53       * Default constructor. Initializes with the correct {@link ExcludeViolationsFromFile}.
54       */
55      public PmdViolationCheckMojo()
56      {
57          super( new ExcludeViolationsFromFile() );
58      }
59  
60      /**
61       * What priority level to fail the build on. Failures at or above this level will stop the build. Anything below
62       * will be warnings and will be displayed in the build output if verbose=true. Note: Minimum Priority = 5 Maximum
63       * Priority = 0
64       */
65      @Parameter( property = "pmd.failurePriority", defaultValue = "5", required = true )
66      private int failurePriority;
67  
68      /**
69       * Skip the PMD checks. Most useful on the command line via "-Dpmd.skip=true".
70       */
71      @Parameter( property = "pmd.skip", defaultValue = "false" )
72      private boolean skip;
73  
74      /**
75       * {@inheritDoc}
76       */
77      public void execute()
78          throws MojoExecutionException, MojoFailureException
79      {
80          if ( !skip )
81          {
82              executeCheck( "pmd.xml", "violation", "PMD violation", failurePriority );
83          }
84      }
85  
86      /**
87       * {@inheritDoc}
88       */
89      protected void printError( Violation item, String severity )
90      {
91  
92          StringBuilder buff = new StringBuilder( 100 );
93          buff.append( "PMD " ).append( severity ).append( ": " );
94          if ( item.getViolationClass() != null )
95          {
96              if ( item.getViolationPackage() != null )
97              {
98                  buff.append( item.getViolationPackage() );
99                  buff.append( "." );
100             }
101             buff.append( item.getViolationClass() );
102         }
103         else
104         {
105             buff.append( item.getFileName() );
106         }
107         buff.append( ":" );
108         buff.append( item.getBeginline() );
109         buff.append( " Rule:" ).append( item.getRule() );
110         buff.append( " Priority:" ).append( item.getPriority() );
111         buff.append( " " ).append( item.getText() ).append( "." );
112 
113         this.getLog().info( buff.toString() );
114     }
115 
116     @Override
117     protected List<Violation> getErrorDetails( File pmdFile )
118         throws XmlPullParserException, IOException
119     {
120         try ( FileReader reader1 = new FileReader( pmdFile ) )
121         {
122             PmdXpp3Reader reader = new PmdXpp3Reader();
123             PmdErrorDetail details = reader.read( reader1, false );
124 
125             List<Violation> violations = new ArrayList<>();
126             for ( PmdFile file : details.getFiles() )
127             {
128                 String fullPath = file.getName();
129 
130                 for ( Violation violation : file.getViolations() )
131                 {
132                     violation.setFileName( getFilename( fullPath, violation.getViolationPackage() ) );
133                     violations.add( violation );
134                 }
135             }
136             return violations;
137         }
138     }
139 
140     @Override
141     protected int getPriority( Violation errorDetail )
142     {
143         return errorDetail.getPriority();
144     }
145 
146     @Override
147     protected ViolationDetails<Violation> newViolationDetailsInstance()
148     {
149         return new ViolationDetails<>();
150     }
151 
152     private String getFilename( String fullpath, String pkg )
153     {
154         int index = fullpath.lastIndexOf( File.separatorChar );
155 
156         while ( StringUtils.isNotEmpty( pkg ) )
157         {
158             index = fullpath.substring( 0, index ).lastIndexOf( File.separatorChar );
159 
160             int dot = pkg.indexOf( '.' );
161 
162             if ( dot < 0 )
163             {
164                 break;
165             }
166             pkg = pkg.substring( dot + 1 );
167         }
168 
169         return fullpath.substring( index + 1 );
170     }
171 }